further work on FELIX-1355 - now able to browse repositories defined by projects
involved refactoring of IRepositoryModel and associated classes


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@991568 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/SigilCore.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/SigilCore.java
index 4cfbbc6..69cb7a1 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/SigilCore.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/SigilCore.java
@@ -34,7 +34,6 @@
 import org.apache.felix.sigil.common.config.IBldProject;
 import org.apache.felix.sigil.common.core.BldCore;
 import org.apache.felix.sigil.common.model.ICapabilityModelElement;
-import org.apache.felix.sigil.common.model.ModelElementFactory;
 import org.apache.felix.sigil.common.model.eclipse.ISigilBundle;
 import org.apache.felix.sigil.common.repository.IBundleRepository;
 import org.apache.felix.sigil.common.repository.IRepositoryManager;
@@ -43,14 +42,15 @@
 import org.apache.felix.sigil.eclipse.install.IOSGiInstallManager;
 import org.apache.felix.sigil.eclipse.internal.install.OSGiInstallManager;
 import org.apache.felix.sigil.eclipse.internal.model.project.SigilModelRoot;
-import org.apache.felix.sigil.eclipse.internal.model.project.SigilProject;
 import org.apache.felix.sigil.eclipse.internal.model.repository.RepositoryPreferences;
-import org.apache.felix.sigil.eclipse.internal.repository.eclipse.GlobalRepositoryManager;
-import org.apache.felix.sigil.eclipse.internal.repository.manager.RepositoryMap;
+import org.apache.felix.sigil.eclipse.internal.repository.manager.GlobalRepositoryManager;
+import org.apache.felix.sigil.eclipse.internal.repository.manager.IEclipseBundleRepository;
+import org.apache.felix.sigil.eclipse.internal.repository.manager.RepositoryCache;
 import org.apache.felix.sigil.eclipse.internal.resources.ProjectResourceListener;
 import org.apache.felix.sigil.eclipse.internal.resources.SigilProjectManager;
 import org.apache.felix.sigil.eclipse.model.project.ISigilModelRoot;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
+import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryPreferences;
 import org.apache.felix.sigil.eclipse.model.util.JavaHelper;
 import org.eclipse.core.resources.ICommand;
@@ -76,7 +76,6 @@
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.osgi.framework.BundleContext;
-import org.osgi.util.tracker.ServiceTracker;
 
 /**
  * The activator class controls the plug-in life cycle
@@ -142,15 +141,11 @@
     // The shared instance
     private static SigilCore plugin;
 
-    private ServiceTracker descriptorTracker;
-    private ServiceTracker registryTracker;
-    private ServiceTracker serializerTracker;
-    private static IRepositoryPreferences repositoryPrefs;
+    private static RepositoryPreferences repositoryPrefs;
     private static SigilProjectManager projectManager;
     private static OSGiInstallManager installs;
     private static ISigilModelRoot modelRoot;
     private static GlobalRepositoryManager globalRepositoryManager;
-    private static RepositoryMap repositoryMap;
 
     /**
      * Returns the shared instance
@@ -268,18 +263,17 @@
     {
         super.start(context);
 
-        modelRoot = new SigilModelRoot();
+        RepositoryCache repositoryCache = new RepositoryCache();
+        projectManager = new SigilProjectManager(repositoryCache);
 
-        repositoryPrefs = new RepositoryPreferences();
+        modelRoot = new SigilModelRoot();
 
         installs = new OSGiInstallManager();
 
-        repositoryMap = new RepositoryMap();
-        globalRepositoryManager = new GlobalRepositoryManager(repositoryMap);
+        repositoryPrefs = new RepositoryPreferences();
+        globalRepositoryManager = new GlobalRepositoryManager(repositoryCache);
         globalRepositoryManager.initialise();
 
-        projectManager = new SigilProjectManager();
-
         registerModelElements(context);
         registerResourceListeners();
     }
@@ -293,26 +287,11 @@
      */
     public void stop(BundleContext context) throws Exception
     {
-        if (descriptorTracker != null)
-        {
-            descriptorTracker.close();
-            descriptorTracker = null;
-        }
-
-        if (registryTracker != null)
-        {
-            registryTracker.close();
-            registryTracker = null;
-        }
-
-        if (serializerTracker != null)
-        {
-            serializerTracker.close();
-            serializerTracker = null;
-        }
-
         globalRepositoryManager.destroy();
         globalRepositoryManager = null;
+        
+        projectManager.destroy();
+        projectManager = null;
 
         plugin = null;
 
@@ -404,8 +383,6 @@
     {
         // trick to get eclipse to lazy load BldCore for model elements
         BldCore.getLicenseManager();
-        ModelElementFactory.getInstance().register(ISigilProjectModel.class,
-            SigilProject.class, "project", "sigil", null);
     }
 
     public static IOSGiInstallManager getInstallManager()
@@ -428,7 +405,7 @@
         if ( model == null ) return globalRepositoryManager;
         try
         {
-            return projectManager.getRepositoryManager(model, repositoryMap);
+            return projectManager.getRepositoryManager(model);
         }
         catch (CoreException e)
         {
@@ -436,6 +413,16 @@
             return globalRepositoryManager;
         }        
     }
+    
+    /**
+     * @param rep
+     * @return
+     */
+    public static IRepositoryModel getRepositoryModel(IBundleRepository rep)
+    {
+        IEclipseBundleRepository cast = (IEclipseBundleRepository) rep;
+        return cast.getModel();
+    }    
 
     public static IRepositoryPreferences getRepositoryPreferences()
     {
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/ExtensionUtils.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/ExtensionUtils.java
new file mode 100644
index 0000000..5d1cd0b
--- /dev/null
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/ExtensionUtils.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.sigil.eclipse.internal.model.repository;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.apache.felix.sigil.eclipse.SigilCore;
+import org.apache.felix.sigil.eclipse.model.repository.IRepositoryType;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.swt.graphics.Image;
+import org.osgi.framework.Bundle;
+
+/**
+ * @author dave
+ *
+ */
+public class ExtensionUtils
+{
+    public static List<IRepositoryType> loadRepositoryTypes()
+    {
+        List<IRepositoryType> repositories = new ArrayList<IRepositoryType>();
+
+        IExtensionRegistry registry = Platform.getExtensionRegistry();
+
+        IExtensionPoint p = registry.getExtensionPoint(SigilCore.REPOSITORY_PROVIDER_EXTENSION_POINT_ID);
+
+        for (IExtension e : p.getExtensions())
+        {
+            for (IConfigurationElement c : e.getConfigurationElements())
+            {
+                repositories.add(toRepositoryType(e, c));
+            }
+        }
+
+        return repositories;
+    }
+    
+    /**
+     * @param ext 
+     * @param conf
+     * @return
+     */
+    public static IRepositoryType toRepositoryType(IExtension ext, IConfigurationElement conf)
+    {
+        String id = conf.getAttribute("id");
+        String type = conf.getAttribute("type");
+        boolean dynamic = Boolean.valueOf(conf.getAttribute("dynamic"));
+        String icon = conf.getAttribute("icon");
+        String provider = conf.getAttribute("alias");                
+        Image image = (icon == null || icon.trim().length() == 0) ? null
+            : loadImage(ext, icon);
+        return new RepositoryType(id, provider, type, dynamic, image);
+    }
+    
+    @SuppressWarnings("unchecked")
+    private static Image loadImage(IExtension ext, String icon)
+    {
+        int i = icon.lastIndexOf("/");
+        String path = i == -1 ? "/" : icon.substring(0, i);
+        String name = i == -1 ? icon : icon.substring(i + 1);
+
+        Bundle b = Platform.getBundle(ext.getContributor().getName());
+
+        Enumeration<URL> en = b.findEntries(path, name, false);
+        Image image = null;
+
+        if (en.hasMoreElements())
+        {
+            try
+            {
+                image = SigilCore.loadImage(en.nextElement());
+            }
+            catch (IOException e)
+            {
+                SigilCore.error("Failed to load image", e);
+            }
+        }
+        else
+        {
+            SigilCore.error("No such image " + icon + " in bundle " + b.getSymbolicName());
+        }
+
+        return image;
+    }
+    
+}
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryModel.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryModel.java
index 2b52c45..45888c1 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryModel.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryModel.java
@@ -19,31 +19,46 @@
 
 package org.apache.felix.sigil.eclipse.internal.model.repository;
 
+import java.util.Properties;
+
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryType;
-import org.eclipse.jface.preference.PreferenceStore;
 
 public class RepositoryModel implements IRepositoryModel
 {
-    private String id;
+    public static final String NAME = "name";
 
-    private String name;
+    private String id;
 
     private IRepositoryType type;
 
-    private PreferenceStore preferences;
+    private Properties properties = new Properties();
+    
+    private Throwable throwable;
 
-    public RepositoryModel(String id, String name, IRepositoryType type, PreferenceStore preferences)
+    public RepositoryModel(String id, IRepositoryType type)
     {
         this.id = id;
-        this.name = name;
         this.type = type;
-        this.preferences = preferences;
     }
 
-    public PreferenceStore getPreferences()
+    /**
+     * @param exception 
+     * @param id2
+     * @param type2
+     * @param properties2
+     */
+    public RepositoryModel(String id, IRepositoryType type, Properties properties, Exception exception)
     {
-        return preferences;
+        this.id = id;
+        this.type = type;
+        this.properties = properties;
+        this.throwable = exception;
+    }
+
+    public Properties getProperties()
+    {
+        return properties;
     }
 
     public IRepositoryType getType()
@@ -58,12 +73,16 @@
 
     public String getName()
     {
-        return name;
-    }
-
-    public void setName(String name)
-    {
-        this.name = name;
+        if ( getType().isDynamic() ) {
+            String name = properties.getProperty(NAME);
+            if ( name == null ) {
+                name = id;
+            }
+            return name;
+        }
+        else {
+            return getType().getName();
+        }
     }
 
     @Override
@@ -88,6 +107,15 @@
 
     public String toString()
     {
-        return type.getId() + ":" + id + ":" + name;
+        return type.getId() + ":" + id + ":" + getName();
     }
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel#getProblem()
+     */
+    public Throwable getProblem()
+    {
+        return throwable;
+    }
+
 }
\ No newline at end of file
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryPreferences.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryPreferences.java
index 7eb22f3..44d7c80 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryPreferences.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryPreferences.java
@@ -20,33 +20,29 @@
 package org.apache.felix.sigil.eclipse.internal.model.repository;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
-import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 import java.util.UUID;
 
+import org.apache.felix.sigil.common.config.IRepositoryConfig;
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryPreferences;
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryType;
 import org.apache.felix.sigil.eclipse.preferences.PrefsUtils;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IExtension;
-import org.eclipse.core.runtime.IExtensionPoint;
-import org.eclipse.core.runtime.IExtensionRegistry;
 import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Platform;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.preference.PreferenceStore;
-import org.eclipse.swt.graphics.Image;
-import org.osgi.framework.Bundle;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
 
 public class RepositoryPreferences implements IRepositoryPreferences
 {
@@ -58,19 +54,13 @@
     private static final String LOC = ".loc";
     private static final String TIMESTAMP = ".timestamp";
 
-    private static final HashMap<String, String> migrationTable = new HashMap<String, String>();
-    
-    static {
-        migrationTable.put("org.apache.felix.sigil.core.file", "filesystem");
-    }
-
     public List<IRepositoryModel> loadRepositories()
     {
         IPreferenceStore prefs = SigilCore.getDefault().getPreferenceStore();
 
         ArrayList<IRepositoryModel> repositories = new ArrayList<IRepositoryModel>();
 
-        for (RepositoryType type : loadRepositoryTypes())
+        for (IRepositoryType type : loadRepositoryTypes())
         {
             String typeID = type.getId();
 
@@ -159,40 +149,13 @@
         }
         prefs.setValue(REPOSITORY_ORDER, PrefsUtils.listToString(ids));
     }
-
-    public List<RepositoryType> loadRepositoryTypes()
-    {
-        List<RepositoryType> repositories = new ArrayList<RepositoryType>();
-
-        IExtensionRegistry registry = Platform.getExtensionRegistry();
-
-        IExtensionPoint p = registry.getExtensionPoint(SigilCore.REPOSITORY_PROVIDER_EXTENSION_POINT_ID);
-
-        for (IExtension e : p.getExtensions())
-        {
-            for (IConfigurationElement c : e.getConfigurationElements())
-            {
-                String id = c.getAttribute("id");
-                String type = c.getAttribute("type");
-                boolean dynamic = Boolean.valueOf(c.getAttribute("dynamic"));
-                String icon = c.getAttribute("icon");
-                String provider = c.getAttribute("alias");                
-                Image image = (icon == null || icon.trim().length() == 0) ? null
-                    : loadImage(e, icon);
-                repositories.add(new RepositoryType(id, provider, type, dynamic, image));
-            }
-        }
-
-        return repositories;
-    }
+    
 
     public IRepositoryModel newRepositoryElement(IRepositoryType type)
     {
         String id = UUID.randomUUID().toString();
-        PreferenceStore prefs = new PreferenceStore();
-        RepositoryModel element = new RepositoryModel(id, "", type, prefs);
-        prefs.setFilename(makeFileName(element));
-        prefs.setValue("id", id);
+        RepositoryModel element = new RepositoryModel(id, type);
+        element.getProperties().setProperty("id", id);
         return element;
     }
 
@@ -264,7 +227,7 @@
         }
     }
 
-    private static void saveRepositoryPreferences(List<IRepositoryModel> repositories,
+    private void saveRepositoryPreferences(List<IRepositoryModel> repositories,
         HashMap<IRepositoryType, List<IRepositoryModel>> mapped) throws CoreException
     {
         for (IRepositoryModel rep : repositories)
@@ -272,7 +235,7 @@
             try
             {
                 createDir(makeFileName(rep));
-                rep.getPreferences().save();
+                toPreferenceStore(rep).save();
                 List<IRepositoryModel> list = mapped.get(rep.getType());
                 if (list == null)
                 {
@@ -299,10 +262,6 @@
     {
         String key = makeKey(element);
         prefs.setValue(key + LOC, makeFileName(element));
-        if (element.getType().isDynamic())
-        {
-            prefs.setValue(key + NAME, element.getName());
-        }
         prefs.setValue(key + TIMESTAMP, now());
     }
 
@@ -331,13 +290,10 @@
         return path.toOSString();
     }
 
-    private static RepositoryModel loadRepository(String id, String key,
-        RepositoryType type, IPreferenceStore prefs)
+    private RepositoryModel loadRepository(String id, String key,
+        IRepositoryType type, IPreferenceStore prefs)
     {
-        String name = type.isDynamic() ? prefs.getString(key + NAME) : type.getType();
-
-        PreferenceStore repPrefs = new PreferenceStore();
-        RepositoryModel element = new RepositoryModel(id, name, type, repPrefs);
+        RepositoryModel element = new RepositoryModel(id, type);
 
         String loc = prefs.getString(key + LOC);
 
@@ -346,54 +302,78 @@
             loc = makeFileName(element);
         }
 
-        repPrefs.setFilename(loc);
-
         if (new File(loc).exists())
         {
+            FileInputStream in = null; 
             try
             {
-                repPrefs.load();
+                in = new FileInputStream(loc);
+                Properties props = element.getProperties();
+                props.load(in);
+                
+                if (type.isDynamic() && !props.containsKey(RepositoryModel.NAME)) {
+                    String name = prefs.getString(key + NAME);
+                    props.setProperty(RepositoryModel.NAME, name);
+                }
+                
+                if (!props.containsKey(IRepositoryConfig.REPOSITORY_PROVIDER)) {
+                    props.put(IRepositoryConfig.REPOSITORY_PROVIDER, type.getProvider());
+                }
+
             }
             catch (IOException e)
             {
                 SigilCore.error("Failed to load properties for repository " + key, e);
             }
+            finally {
+                if ( in != null ) {
+                    try
+                    {
+                        in.close();
+                    }
+                    catch (IOException e)
+                    {
+                        SigilCore.error("Failed to close properties file " + loc, e);
+                    }
+                }
+            }
         }
 
-        repPrefs.setValue("id", id);
+        element.getProperties().setProperty("id", id);
 
         return element;
     }
 
-    @SuppressWarnings("unchecked")
-    private static Image loadImage(IExtension ext, String icon)
+    /* (non-Javadoc)
+     * @see org.apache.felix.sigil.eclipse.model.repository.IRepositoryPreferences#loadRepositoryTypes()
+     */
+    public List<IRepositoryType> loadRepositoryTypes()
     {
-        int i = icon.lastIndexOf("/");
-        String path = i == -1 ? "/" : icon.substring(0, i);
-        String name = i == -1 ? icon : icon.substring(i + 1);
-
-        Bundle b = Platform.getBundle(ext.getContributor().getName());
-
-        Enumeration<URL> en = b.findEntries(path, name, false);
-        Image image = null;
-
-        if (en.hasMoreElements())
-        {
-            try
-            {
-                image = SigilCore.loadImage(en.nextElement());
-            }
-            catch (IOException e)
-            {
-                SigilCore.error("Failed to load image", e);
-            }
-        }
-        else
-        {
-            SigilCore.error("No such image " + icon + " in bundle " + b.getSymbolicName());
-        }
-
-        return image;
+        return ExtensionUtils.loadRepositoryTypes();
     }
 
+    /* (non-Javadoc)
+     * @see org.apache.felix.sigil.eclipse.model.repository.IRepositoryPreferences#getPreferenceStore(org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel)
+     */
+    public PreferenceStore toPreferenceStore(final IRepositoryModel model)
+    {
+        PreferenceStore store = new PreferenceStore();
+        store.setFilename(makeFileName(model));
+        
+        for (Map.Entry<Object, Object> e : model.getProperties().entrySet()) {
+            store.setValue((String) e.getKey(), (String) e.getValue());
+        }
+        
+        store.setValue("provider", model.getType().getProvider());
+
+        store.addPropertyChangeListener(new IPropertyChangeListener()
+        {            
+            public void propertyChange(PropertyChangeEvent event)
+            {
+                model.getProperties().setProperty(event.getProperty(), (String) event.getNewValue());
+            }
+        });
+        
+        return store;
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryType.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryType.java
index 53889b7..1630699 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryType.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryType.java
@@ -39,7 +39,7 @@
         this.icon = icon;
     }
 
-    public String getType()
+    public String getName()
     {
         return type;
     }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/SigilRepositoryManager.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/SigilRepositoryManager.java
deleted file mode 100644
index d6fb658..0000000
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/SigilRepositoryManager.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.felix.sigil.eclipse.internal.repository.eclipse;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.sigil.common.repository.AbstractRepositoryManager;
-import org.apache.felix.sigil.common.repository.IBundleRepository;
-import org.apache.felix.sigil.common.repository.IRepositoryManager;
-import org.apache.felix.sigil.common.repository.IRepositoryProvider;
-import org.apache.felix.sigil.common.repository.RepositoryException;
-import org.apache.felix.sigil.eclipse.SigilCore;
-import org.apache.felix.sigil.eclipse.internal.repository.manager.RepositoryMap;
-import org.apache.felix.sigil.eclipse.internal.repository.manager.IRepositoryMap.RepositoryCache;
-import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
-import org.apache.felix.sigil.eclipse.model.repository.IRepositoryType;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IExtension;
-import org.eclipse.core.runtime.IExtensionPoint;
-import org.eclipse.core.runtime.IExtensionRegistry;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.util.IPropertyChangeListener;
-import org.eclipse.jface.util.PropertyChangeEvent;
-
-public class SigilRepositoryManager extends AbstractRepositoryManager implements IRepositoryManager, IPropertyChangeListener
-{
-
-    private RepositoryMap cachedRepositories;
-
-    public SigilRepositoryManager(RepositoryMap cachedRepositories)
-    {
-        this.cachedRepositories = cachedRepositories;
-    }
-
-    @Override
-    public void initialise()
-    {
-        super.initialise();
-        SigilCore.getDefault().getPreferenceStore().addPropertyChangeListener(this);
-    }
-
-    public void destroy()
-    {
-        IPreferenceStore prefs = SigilCore.getDefault().getPreferenceStore();
-        if (prefs != null)
-        {
-            prefs.removePropertyChangeListener(this);
-        }
-    }
-
-    @Override
-    protected void loadRepositories()
-    {
-        IPreferenceStore prefs = SigilCore.getDefault().getPreferenceStore();
-
-        ArrayList<IBundleRepository> repos = new ArrayList<IBundleRepository>();
-        HashSet<String> ids = new HashSet<String>();
-
-        List<IRepositoryModel> models = findRepositories();
-        for (IRepositoryModel repo : models)
-        {
-            try
-            {
-                IRepositoryProvider provider = findProvider(repo.getType());
-                String id = repo.getId();
-                IBundleRepository repoImpl = null;
-                if (repo.getType().isDynamic())
-                {
-                    String instance = "repository." + repo.getType().getId() + "." + id;
-                    String loc = prefs.getString(instance + ".loc");
-                    Properties pref = loadPreferences(loc);
-                    repoImpl = loadRepository(id, pref, provider);
-                }
-                else
-                {
-                    repoImpl = loadRepository(id, null, provider);
-                }
-
-                repos.add(repoImpl);
-                ids.add(id);
-            }
-            catch (Exception e)
-            {
-                SigilCore.error("Failed to load repository for " + repo, e);
-            }
-        }
-
-        setRepositories(repos.toArray(new IBundleRepository[repos.size()]));
-
-        cachedRepositories.retainAll(ids);
-    }
-
-    private IRepositoryProvider findProvider(IRepositoryType repositoryType)
-        throws CoreException
-    {
-        String id = repositoryType.getId();
-
-        IExtensionRegistry registry = Platform.getExtensionRegistry();
-        IExtensionPoint p = registry.getExtensionPoint(SigilCore.REPOSITORY_PROVIDER_EXTENSION_POINT_ID);
-
-        for (IExtension e : p.getExtensions())
-        {
-            for (IConfigurationElement c : e.getConfigurationElements())
-            {
-                if (id.equals(c.getAttribute("id")))
-                {
-                    IRepositoryProvider provider = (IRepositoryProvider) c.createExecutableExtension("class");
-                    return provider;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    protected List<IRepositoryModel> findRepositories()
-    {
-        return SigilCore.getRepositoryPreferences().loadRepositories();
-    }
-
-    private IBundleRepository loadRepository(String id, Properties pref,
-        IRepositoryProvider provider) throws RepositoryException
-    {
-        try
-        {
-            if (pref == null)
-            {
-                pref = new Properties();
-            }
-
-            RepositoryCache cache = cachedRepositories.get(id);
-
-            if (cache == null || !cache.pref.equals(pref))
-            {
-                IBundleRepository repo = provider.createRepository(id, pref);
-                cache = new RepositoryCache(pref, repo);
-                cachedRepositories.put(id, cache);
-            }
-
-            return cache.repo;
-        }
-        catch (RuntimeException e)
-        {
-            throw new RepositoryException("Failed to build repositories", e);
-        }
-    }
-
-    private Properties loadPreferences(String loc) throws FileNotFoundException,
-        IOException
-    {
-        FileInputStream in = null;
-        try
-        {
-            Properties pref = new Properties();
-            pref.load(new FileInputStream(loc));
-            return pref;
-        }
-        finally
-        {
-            if (in != null)
-            {
-                try
-                {
-                    in.close();
-                }
-                catch (IOException e)
-                {
-                    SigilCore.error("Failed to close file", e);
-                }
-            }
-        }
-    }
-
-    public void propertyChange(PropertyChangeEvent event)
-    {
-        if (event.getProperty().equals("repository.timestamp"))
-        {
-            loadRepositories();
-        }
-    }
-}
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/AbstractEclipseRepositoryConfig.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/AbstractEclipseRepositoryConfig.java
new file mode 100644
index 0000000..b3dda25
--- /dev/null
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/AbstractEclipseRepositoryConfig.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.sigil.eclipse.internal.repository.manager;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.sigil.common.config.IRepositoryConfig;
+import org.apache.felix.sigil.eclipse.SigilCore;
+import org.apache.felix.sigil.eclipse.internal.model.repository.RepositoryModel;
+import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * @author dave
+ *
+ */
+public abstract class AbstractEclipseRepositoryConfig implements IRepositoryConfig
+{
+
+    protected abstract IRepositoryConfig[] getConfigs();
+    
+    /* (non-Javadoc)
+     * @see org.apache.felix.sigil.common.config.IRepositoryConfig#getAllRepositories()
+     */
+    public List<String> getAllRepositories()
+    {
+        ArrayList<String> list = new ArrayList<String>();
+        for (IRepositoryConfig c : getConfigs()) {
+            list.addAll(c.getAllRepositories());
+        }
+        list.addAll(readRepositoryNames());
+        return list;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.sigil.common.config.IRepositoryConfig#getRepositoryConfig(java.lang.String)
+     */
+    public Properties getRepositoryConfig(String name)
+    {
+        Properties props = null;
+        for(IRepositoryConfig c : getConfigs()) {
+            props = c.getRepositoryConfig(name);
+            if ( props != null ) {
+                if ( !props.containsKey(RepositoryModel.NAME)) {
+                    props.setProperty(RepositoryModel.NAME, name);
+                }
+                break;
+            }
+        }
+        if ( props == null ) {
+            props = readRepositoryConfig(name);
+        }
+        return props;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.sigil.common.config.IRepositoryConfig#getRepositoryDefinition(java.lang.String)
+     */
+    public URI getRepositoryDefinition(String name)
+    {
+        URI def = null;
+        for(IRepositoryConfig c : getConfigs()) {
+            def = c.getRepositoryDefinition(name);
+            if ( def != null ) {
+                break;
+            }
+        }
+        if ( def == null ) {
+            if ( readRepositoryNames().contains(name) ) {
+                def = URI.create("sigil:eclipse:preferences");
+            }
+        }
+        return def;
+    }
+
+    /**
+     * @return
+     */
+    static List<String> readRepositoryNames()
+    {
+        List<IRepositoryModel> models = findRepositories();
+        ArrayList<String> repos = new ArrayList<String>(models.size());
+        for (IRepositoryModel repo : models)
+        {
+            String id = repo.getId();
+            repos.add(id);
+        }
+        
+        return repos;
+    }
+
+    static Properties readRepositoryConfig(String name) {
+        for (IRepositoryModel repo : findRepositories())
+        {
+            String id = repo.getId();
+            if ( name.equals(id) ) {
+                return repo.getProperties();
+            }
+        }
+        
+        // ok not found
+        return null;
+    }
+    
+    private static final List<IRepositoryModel> findRepositories()
+    {
+        return SigilCore.getRepositoryPreferences().loadRepositories();
+    }    
+}
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/EclipseRepositoryManager.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/AbstractEclipseRepositoryManager.java
similarity index 74%
rename from sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/EclipseRepositoryManager.java
rename to sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/AbstractEclipseRepositoryManager.java
index fb9b46c..6e105b6 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/EclipseRepositoryManager.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/AbstractEclipseRepositoryManager.java
@@ -29,9 +29,7 @@
 import org.apache.felix.sigil.common.repository.AbstractRepositoryManager;
 import org.apache.felix.sigil.common.repository.IBundleRepository;
 import org.apache.felix.sigil.common.repository.IRepositoryProvider;
-import org.apache.felix.sigil.common.repository.RepositoryException;
 import org.apache.felix.sigil.eclipse.SigilCore;
-import org.apache.felix.sigil.eclipse.internal.repository.manager.IRepositoryMap.RepositoryCache;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.util.IPropertyChangeListener;
 import org.eclipse.jface.util.PropertyChangeEvent;
@@ -40,19 +38,19 @@
  * @author dave
  *
  */
-public class EclipseRepositoryManager extends AbstractRepositoryManager implements IPropertyChangeListener
+public abstract class AbstractEclipseRepositoryManager extends AbstractRepositoryManager implements IPropertyChangeListener
 {
     private final IRepositoryConfig config;
-    private final IRepositoryMap repositoryMap;
+    private final IRepositoryCache repositoryCache;
     
-    /**
-     * @param config
-     * @param repositoryMap2 
-     */
-    public EclipseRepositoryManager(IRepositoryConfig config, IRepositoryMap repositoryMap)
+    public AbstractEclipseRepositoryManager(IRepositoryConfig config, IRepositoryCache repositoryMap)
     {
-        this.config = new EclipseRepositoryConfig(config);
-        this.repositoryMap = repositoryMap;
+        this.config = config;
+        this.repositoryCache = repositoryMap;
+    }
+    
+    public IRepositoryConfig getConfig() {
+        return config;
     }
     
     @Override
@@ -111,7 +109,7 @@
                 Properties props = config.getRepositoryConfig(name);
                 if (props != null) {
                     String uid = config.getRepositoryDefinition(name).toString() + '#' + name;
-                    IBundleRepository repo = buildRepository(uid, name, props);
+                    IBundleRepository repo = buildRepository(uid, props);
                     
                     if ( repo != null ) {
                         list.add(repo);
@@ -125,10 +123,10 @@
      * @param repo
      * @return 
      */
-    private IBundleRepository buildRepository(String uid, String name, Properties repo)
+    private IBundleRepository buildRepository(String uid, Properties repo)
     {
-        String disabled = repo.getProperty("disabled");
-        if ("true".equalsIgnoreCase(disabled == null ? null : disabled.trim())) return null;
+        String disabled = repo.getProperty("disabled", "false");
+        if (Boolean.parseBoolean(disabled.trim())) return null;
         
         String optStr = repo.getProperty("optional", "false");
         boolean optional = Boolean.parseBoolean(optStr.trim());
@@ -136,7 +134,7 @@
         String alias = repo.getProperty(IRepositoryConfig.REPOSITORY_PROVIDER);
         if (alias == null)
         {
-            String msg = "provider not specified for repository: " + name;
+            String msg = "provider not specified for repository: " + uid;
             
             if (optional)            
                 SigilCore.log(msg);
@@ -149,7 +147,7 @@
         try
         {
             IRepositoryProvider instance = EclipseRepositoryFactory.getProvider(alias);
-            IBundleRepository repository = loadRepository(uid, name, repo, instance);
+            IBundleRepository repository = repositoryCache.getRepository(uid, repo, instance);
             return repository;
         }
         catch (Exception e)
@@ -165,33 +163,6 @@
         return null;
     }
     
-    private IBundleRepository loadRepository(String uid, String id, Properties pref,
-        IRepositoryProvider provider) throws RepositoryException
-    {
-        try
-        {
-            if (pref == null)
-            {
-                pref = new Properties();
-            }
-
-            RepositoryCache cache = repositoryMap.get(uid);
-
-            if (cache == null || !cache.pref.equals(pref))
-            {
-                IBundleRepository repo = provider.createRepository(id, pref);
-                cache = new RepositoryCache(pref, repo);
-                repositoryMap.put(uid, cache);
-            }
-
-            return cache.repo;
-        }
-        catch (RuntimeException e)
-        {
-            throw new RepositoryException("Failed to build repositories", e);
-        }
-    }
-
     /* (non-Javadoc)
      * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
      */
@@ -202,5 +173,5 @@
             loadRepositories();
         }
     }
-    
+
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/EclipseBundleRepository.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/EclipseBundleRepository.java
new file mode 100644
index 0000000..68f9263
--- /dev/null
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/EclipseBundleRepository.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.sigil.eclipse.internal.repository.manager;
+
+import java.util.HashSet;
+import java.util.Properties;
+
+import org.apache.felix.sigil.common.repository.AbstractBundleRepository;
+import org.apache.felix.sigil.common.repository.IBundleRepository;
+import org.apache.felix.sigil.common.repository.IBundleRepositoryListener;
+import org.apache.felix.sigil.common.repository.IRepositoryProvider;
+import org.apache.felix.sigil.common.repository.IRepositoryVisitor;
+import org.apache.felix.sigil.eclipse.internal.model.repository.RepositoryModel;
+import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
+import org.apache.felix.sigil.eclipse.model.repository.IRepositoryType;
+
+/**
+ * @author dave
+ *
+ */
+public class EclipseBundleRepository extends AbstractBundleRepository implements IEclipseBundleRepository
+{
+    
+    private final IRepositoryProvider provider;
+    private final Properties properties;
+    private final IRepositoryType type;
+    
+    private final HashSet<IBundleRepositoryListener> listeners = new HashSet<IBundleRepositoryListener>();
+    
+    private Exception exception;
+    private IBundleRepository delegate;
+
+    /**
+     * @param provider
+     * @param type 
+     * @param id
+     * @param properties
+     */
+    public EclipseBundleRepository(IRepositoryProvider provider, IRepositoryType type, String id, Properties properties)
+    {
+        super(id);
+        this.provider = provider;
+        this.type = type;
+        this.properties = properties;
+    }
+    
+    private synchronized IBundleRepository getDelegate() {
+        if (delegate == null && exception == null) {
+            try
+            {
+                delegate = provider.createRepository(getId(), properties);
+                for (IBundleRepositoryListener listener : listeners) {
+                    delegate.addBundleRepositoryListener(listener);
+                }
+                exception = null;
+            }
+            catch (Exception e)
+            {
+                delegate = null;
+                exception = e;
+            }
+        }
+        
+        return delegate;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.sigil.common.repository.IBundleRepository#accept(org.apache.felix.sigil.common.repository.IRepositoryVisitor, int)
+     */
+    public void accept(IRepositoryVisitor visitor, int options)
+    {
+        IBundleRepository delegate = getDelegate();
+        if ( delegate != null ) {
+            delegate.accept(visitor, options);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.sigil.common.repository.IBundleRepository#addBundleRepositoryListener(org.apache.felix.sigil.common.repository.IBundleRepositoryListener)
+     */
+    public synchronized void addBundleRepositoryListener(IBundleRepositoryListener listener)
+    {
+        IBundleRepository delegate = getDelegate();
+        if ( delegate != null ) {
+            delegate.addBundleRepositoryListener(listener);
+        }
+        else {
+            listeners.add(listener);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.felix.sigil.common.repository.IBundleRepository#removeBundleRepositoryListener(org.apache.felix.sigil.common.repository.IBundleRepositoryListener)
+     */
+    public synchronized void removeBundleRepositoryListener(IBundleRepositoryListener listener)
+    {
+        IBundleRepository delegate = getDelegate();
+        if ( delegate != null ) {
+            delegate.removeBundleRepositoryListener(listener);
+        }
+        else {
+            listeners.remove(listener);
+        }
+    }    
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.sigil.common.repository.IBundleRepository#refresh()
+     */
+    public void refresh()
+    {
+        IBundleRepository delegate = getDelegate();
+        if ( delegate == null ) {
+            exception = null;
+            getDelegate();
+        }
+        else {
+            delegate.refresh();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.sigil.eclipse.internal.repository.manager.IEclipseBundleRepository#getModel()
+     */
+    public IRepositoryModel getModel()
+    {
+        return new RepositoryModel(getId(), type, properties, exception);
+    }
+
+}
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/EclipseRepositoryConfig.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/EclipseRepositoryConfig.java
deleted file mode 100644
index 1846846..0000000
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/EclipseRepositoryConfig.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.felix.sigil.eclipse.internal.repository.manager;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.sigil.common.config.IRepositoryConfig;
-import org.apache.felix.sigil.eclipse.SigilCore;
-import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
-import org.eclipse.jface.preference.IPreferenceStore;
-
-/**
- * @author dave
- *
- */
-public class EclipseRepositoryConfig implements IRepositoryConfig
-{
-
-    private final IRepositoryConfig projectConfig;
-    
-    public EclipseRepositoryConfig(IRepositoryConfig projectConfig) {
-        this.projectConfig = projectConfig;
-    }
-    
-    /* (non-Javadoc)
-     * @see org.apache.felix.sigil.common.config.IRepositoryConfig#getAllRepositories()
-     */
-    public List<String> getAllRepositories()
-    {
-        ArrayList<String> list = new ArrayList<String>(projectConfig.getAllRepositories());
-        list.addAll(readRepositoryNames());
-        return list;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.felix.sigil.common.config.IRepositoryConfig#getRepositoryConfig(java.lang.String)
-     */
-    public Properties getRepositoryConfig(String name)
-    {
-        Properties props = projectConfig.getRepositoryConfig(name);
-        if ( props == null ) {
-            props = readRepositoryConfig(name);
-        }
-        return props;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.felix.sigil.common.config.IRepositoryConfig#getRepositoryDefinition(java.lang.String)
-     */
-    public URI getRepositoryDefinition(String name)
-    {
-        URI def = projectConfig.getRepositoryDefinition(name);
-        if ( def == null ) {
-            if ( readRepositoryNames().contains(name) ) {
-                def = URI.create("sigil:eclipse:preferences");
-            }
-        }
-        return def;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.felix.sigil.common.config.IRepositoryConfig#getRepositoryPath()
-     */
-    public List<String> getRepositoryPath()
-    {
-        return projectConfig.getRepositoryPath();
-    }
-
-    /**
-     * @return
-     */
-    private static List<String> readRepositoryNames()
-    {
-        List<IRepositoryModel> models = findRepositories();
-        ArrayList<String> repos = new ArrayList<String>(models.size());
-        for (IRepositoryModel repo : models)
-        {
-            String id = repo.getId();
-            repos.add(id);
-        }
-        
-        return repos;
-    }
-
-    private static Properties readRepositoryConfig(String name) {
-        IPreferenceStore prefs = SigilCore.getDefault().getPreferenceStore();
-
-        for (IRepositoryModel repo : findRepositories())
-        {
-            try
-            {
-                String id = repo.getId();
-                if ( name.equals(id) ) {
-                    Properties pref = null;
-                    if (repo.getType().isDynamic())
-                    {
-                        String instance = "repository." + repo.getType().getId() + "." + id;
-                        String loc = prefs.getString(instance + ".loc");
-                        pref = loadPreferences(loc);                     
-                    }
-                    else
-                    {
-                        pref = new Properties();
-                    }
-                    
-                    if (!pref.containsKey(IRepositoryConfig.REPOSITORY_PROVIDER)) {
-                        pref.put(IRepositoryConfig.REPOSITORY_PROVIDER, repo.getType().getProvider());
-                    }
-                    return pref;
-                }
-            }
-            catch (IOException e)
-            {
-                SigilCore.error("Failed to load repository for " + repo, e);
-            }
-        }
-        
-        // ok not found
-        return null;
-    }
-    
-    private static final List<IRepositoryModel> findRepositories()
-    {
-        return SigilCore.getRepositoryPreferences().loadRepositories();
-    }
-    
-    private static final Properties loadPreferences(String loc) throws FileNotFoundException,
-    IOException
-    {
-        FileInputStream in = null;
-        try
-        {
-            Properties pref = new Properties();
-            pref.load(new FileInputStream(loc));
-            return pref;
-        }
-        finally
-        {
-            if (in != null)
-            {
-                try
-                {
-                    in.close();
-                }
-                catch (IOException e)
-                {
-                    SigilCore.error("Failed to close file", e);
-                }
-            }
-        }
-    }    
-}
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/EclipseRepositoryFactory.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/EclipseRepositoryFactory.java
index 24f6c2b..c87af41 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/EclipseRepositoryFactory.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/EclipseRepositoryFactory.java
@@ -19,8 +19,13 @@
 
 package org.apache.felix.sigil.eclipse.internal.repository.manager;
 
+import java.util.Properties;
+
+import org.apache.felix.sigil.common.repository.IBundleRepository;
 import org.apache.felix.sigil.common.repository.IRepositoryProvider;
 import org.apache.felix.sigil.eclipse.SigilCore;
+import org.apache.felix.sigil.eclipse.internal.model.repository.ExtensionUtils;
+import org.apache.felix.sigil.eclipse.model.repository.IRepositoryType;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExtension;
@@ -35,6 +40,28 @@
 public class EclipseRepositoryFactory
 {
 
+    static class EclipseRepositoryProviderWrapper implements IRepositoryProvider {
+        private final IRepositoryProvider delegate;
+        private final IRepositoryType type;
+
+        /**
+         * @param provider
+         * @param type 
+         */
+        public EclipseRepositoryProviderWrapper(IRepositoryProvider provider, IRepositoryType type)
+        {
+            this.delegate = provider;
+            this.type = type;
+        }
+
+        /* (non-Javadoc)
+         * @see org.apache.felix.sigil.common.repository.IRepositoryProvider#createRepository(java.lang.String, java.util.Properties)
+         */
+        public IBundleRepository createRepository(String id, Properties properties)
+        {
+            return new EclipseBundleRepository(delegate, type, id, properties);
+        }
+    }
     /**
      * @param alias
      * @return
@@ -52,11 +79,14 @@
                 if (alias.equals(c.getAttribute("alias")))
                 {
                     IRepositoryProvider provider = (IRepositoryProvider) c.createExecutableExtension("class");
-                    return provider;
+                    IRepositoryType type = ExtensionUtils.toRepositoryType(e, c);
+                    return new EclipseRepositoryProviderWrapper(provider, type);
                 }
             }
         }
 
         return null;
     }
+    
+    
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/GlobalRepositoryConfig.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/GlobalRepositoryConfig.java
new file mode 100644
index 0000000..b5ed778
--- /dev/null
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/GlobalRepositoryConfig.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.sigil.eclipse.internal.repository.manager;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.felix.sigil.common.config.IRepositoryConfig;
+import org.apache.felix.sigil.eclipse.SigilCore;
+import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * @author dave
+ *
+ */
+public class GlobalRepositoryConfig extends AbstractEclipseRepositoryConfig
+{
+    /* (non-Javadoc)
+     * @see org.apache.felix.sigil.common.config.IRepositoryConfig#getRepositoryPath()
+     */
+    public List<String> getRepositoryPath()
+    {
+        return Collections.singletonList(IRepositoryConfig.WILD_CARD);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.felix.sigil.eclipse.internal.repository.manager.AbstractEclipseRepositoryConfig#getConfigs()
+     */
+    @Override
+    protected IRepositoryConfig[] getConfigs()
+    {
+        ArrayList<IRepositoryConfig> list = new ArrayList<IRepositoryConfig>(); 
+        for (ISigilProjectModel p : SigilCore.getRoot().getProjects() ) {
+            try
+            {
+                IRepositoryConfig c = p.getRepositoryConfig();
+                list.add( c );
+            }
+            catch (CoreException e)
+            {
+                SigilCore.error("Failed to read repository config", e);
+            }            
+        }
+        return list.toArray( new IRepositoryConfig[list.size()] );
+    }
+}
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/GlobalRepositoryManager.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/GlobalRepositoryManager.java
similarity index 63%
rename from sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/GlobalRepositoryManager.java
rename to sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/GlobalRepositoryManager.java
index 7e4c21c..1aa8110 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/GlobalRepositoryManager.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/GlobalRepositoryManager.java
@@ -17,19 +17,21 @@
  * under the License.
  */
 
-package org.apache.felix.sigil.eclipse.internal.repository.eclipse;
+package org.apache.felix.sigil.eclipse.internal.repository.manager;
 
-import org.apache.felix.sigil.common.repository.IRepositoryManager;
-import org.apache.felix.sigil.eclipse.internal.repository.eclipse.SigilRepositoryManager;
-import org.apache.felix.sigil.eclipse.internal.repository.manager.RepositoryMap;
-
-public class GlobalRepositoryManager extends SigilRepositoryManager implements IRepositoryManager
+/**
+ * @author dave
+ *
+ */
+public class GlobalRepositoryManager extends AbstractEclipseRepositoryManager
 {
 
-    public GlobalRepositoryManager(RepositoryMap map)
+    /**
+     * @param repositoryMap
+     */
+    public GlobalRepositoryManager(IRepositoryCache repositoryMap)
     {
-        super(map);
+        super(new GlobalRepositoryConfig(), repositoryMap);
     }
 
-
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/IRepositoryMap.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/IEclipseBundleRepository.java
similarity index 64%
copy from sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/IRepositoryMap.java
copy to sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/IEclipseBundleRepository.java
index c2dc1fa..e33dc9e 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/IRepositoryMap.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/IEclipseBundleRepository.java
@@ -19,39 +19,14 @@
 
 package org.apache.felix.sigil.eclipse.internal.repository.manager;
 
-import java.util.Properties;
-
 import org.apache.felix.sigil.common.repository.IBundleRepository;
+import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
 
 /**
  * @author dave
  *
  */
-public interface IRepositoryMap
+public interface IEclipseBundleRepository extends IBundleRepository
 {
-
-    public static class RepositoryCache
-    {
-        public final Properties pref;
-        public final IBundleRepository repo;
-
-        public RepositoryCache(Properties pref, IBundleRepository repo)
-        {
-            this.pref = pref;
-            this.repo = repo;
-        }
-    }
-
-    /**
-     * @param uid
-     * @return
-     */
-    RepositoryCache get(String uid);
-
-    /**
-     * @param uid
-     * @param cache
-     */
-    void put(String uid, RepositoryCache cache);
-
+    IRepositoryModel getModel();
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/IRepositoryMap.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/IRepositoryCache.java
similarity index 68%
rename from sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/IRepositoryMap.java
rename to sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/IRepositoryCache.java
index c2dc1fa..dadf8d1 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/IRepositoryMap.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/IRepositoryCache.java
@@ -19,39 +19,32 @@
 
 package org.apache.felix.sigil.eclipse.internal.repository.manager;
 
+import java.util.Collection;
 import java.util.Properties;
 
 import org.apache.felix.sigil.common.repository.IBundleRepository;
+import org.apache.felix.sigil.common.repository.IRepositoryProvider;
+import org.apache.felix.sigil.common.repository.RepositoryException;
 
 /**
  * @author dave
  *
  */
-public interface IRepositoryMap
+public interface IRepositoryCache
 {
-
-    public static class RepositoryCache
-    {
-        public final Properties pref;
-        public final IBundleRepository repo;
-
-        public RepositoryCache(Properties pref, IBundleRepository repo)
-        {
-            this.pref = pref;
-            this.repo = repo;
-        }
-    }
-
     /**
+     * @param sponsor
      * @param uid
+     * @param props
+     * @param instance
      * @return
+     * @throws RepositoryException
      */
-    RepositoryCache get(String uid);
+    IBundleRepository getRepository(String uid, Properties props,
+        IRepositoryProvider instance) throws RepositoryException;
 
     /**
-     * @param uid
-     * @param cache
+     * @param flush
      */
-    void put(String uid, RepositoryCache cache);
-
+    void discard(Collection<String> ids);
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/ProjectRepositoryConfig.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/ProjectRepositoryConfig.java
new file mode 100644
index 0000000..3cdfc8e
--- /dev/null
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/ProjectRepositoryConfig.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.sigil.eclipse.internal.repository.manager;
+
+import java.util.List;
+import org.apache.felix.sigil.common.config.IRepositoryConfig;
+
+/**
+ * @author dave
+ *
+ */
+public class ProjectRepositoryConfig extends AbstractEclipseRepositoryConfig
+{
+
+    private final IRepositoryConfig projectConfig;
+    
+    public ProjectRepositoryConfig(IRepositoryConfig projectConfig) {
+        this.projectConfig = projectConfig;
+    }
+    
+    protected IRepositoryConfig[] getConfigs() {
+        return new IRepositoryConfig[] { projectConfig };
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.felix.sigil.common.config.IRepositoryConfig#getRepositoryPath()
+     */
+    public List<String> getRepositoryPath()
+    {
+        return projectConfig.getRepositoryPath();
+    }
+
+}
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/IRepositoryMap.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/ProjectRepositoryManager.java
similarity index 61%
copy from sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/IRepositoryMap.java
copy to sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/ProjectRepositoryManager.java
index c2dc1fa..895617b 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/IRepositoryMap.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/ProjectRepositoryManager.java
@@ -19,39 +19,23 @@
 
 package org.apache.felix.sigil.eclipse.internal.repository.manager;
 
-import java.util.Properties;
 
-import org.apache.felix.sigil.common.repository.IBundleRepository;
+import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
+import org.eclipse.core.runtime.CoreException;
 
 /**
  * @author dave
  *
  */
-public interface IRepositoryMap
+public class ProjectRepositoryManager extends AbstractEclipseRepositoryManager
 {
-
-    public static class RepositoryCache
+    /**
+     * @param model
+     * @param repositoryMap2 
+     * @throws CoreException 
+     */
+    public ProjectRepositoryManager(ISigilProjectModel model, IRepositoryCache repositoryMap) throws CoreException
     {
-        public final Properties pref;
-        public final IBundleRepository repo;
-
-        public RepositoryCache(Properties pref, IBundleRepository repo)
-        {
-            this.pref = pref;
-            this.repo = repo;
-        }
+        super(new ProjectRepositoryConfig(model.getRepositoryConfig()), repositoryMap);
     }
-
-    /**
-     * @param uid
-     * @return
-     */
-    RepositoryCache get(String uid);
-
-    /**
-     * @param uid
-     * @param cache
-     */
-    void put(String uid, RepositoryCache cache);
-
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/RepositoryCache.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/RepositoryCache.java
new file mode 100644
index 0000000..895eaba
--- /dev/null
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/RepositoryCache.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.sigil.eclipse.internal.repository.manager;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Properties;
+
+import org.apache.felix.sigil.common.repository.IBundleRepository;
+import org.apache.felix.sigil.common.repository.IRepositoryProvider;
+import org.apache.felix.sigil.common.repository.RepositoryException;
+
+public class RepositoryCache implements IRepositoryCache
+{
+    public static class RepositoryStore
+    {
+        public final Properties pref;
+        public final IBundleRepository repo;
+
+        public RepositoryStore(Properties pref, IBundleRepository repo)
+        {
+            this.pref = pref;
+            this.repo = repo;
+        }
+    }
+
+    private HashMap<String, RepositoryStore> cachedRepositories = new HashMap<String, RepositoryStore>();
+
+    public synchronized void retainAll(Collection<String> ids)
+    {
+        for (Iterator<String> i = cachedRepositories.keySet().iterator(); i.hasNext();)
+        {
+            if (!ids.contains(i.next()))
+            {
+                i.remove();
+            }
+        }
+    }
+
+    public IBundleRepository getRepository(String uid, Properties pref,
+        IRepositoryProvider provider) throws RepositoryException
+    {
+        try
+        {
+            if (pref == null)
+            {
+                pref = new Properties();
+            }
+
+            RepositoryStore cache = get(uid);
+
+            if (cache == null || !cache.pref.equals(pref))
+            {
+                IBundleRepository repo = provider.createRepository(uid, pref);
+                cache = new RepositoryStore(pref, repo);
+                put(uid, cache);
+            }
+
+            return cache.repo;
+        }
+        catch (RuntimeException e)
+        {
+            throw new RepositoryException("Failed to build repositories", e);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.felix.sigil.eclipse.internal.repository.manager.IRepositoryCache#discard(java.util.Collection)
+     */
+    public void discard(Collection<String> ids)
+    {
+        cachedRepositories.keySet().removeAll(ids);
+    }
+    
+
+    private RepositoryStore get(String id)
+    {
+        return cachedRepositories.get(id);
+    }
+
+    private void put(String id, RepositoryStore cache)
+    {
+        cachedRepositories.put(id, cache);
+    }
+}
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/RepositoryMap.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/RepositoryMap.java
deleted file mode 100644
index f103964..0000000
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/manager/RepositoryMap.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.felix.sigil.eclipse.internal.repository.manager;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-
-
-public class RepositoryMap implements IRepositoryMap
-{
-    private HashMap<String, RepositoryCache> cachedRepositories = new HashMap<String, RepositoryCache>();
-
-    public synchronized void retainAll(Collection<String> ids)
-    {
-        for (Iterator<String> i = cachedRepositories.keySet().iterator(); i.hasNext();)
-        {
-            if (!ids.contains(i.next()))
-            {
-                i.remove();
-            }
-        }
-    }
-
-    public synchronized RepositoryCache get(String id)
-    {
-        return cachedRepositories.get(id);
-    }
-
-    public synchronized void put(String id, RepositoryCache cache)
-    {
-        cachedRepositories.put(id, cache);
-    }
-
-}
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/resources/SigilProjectManager.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/resources/SigilProjectManager.java
index ad9e348..9af30af 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/resources/SigilProjectManager.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/resources/SigilProjectManager.java
@@ -18,22 +18,28 @@
  */
 package org.apache.felix.sigil.eclipse.internal.resources;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 
-import org.apache.felix.sigil.common.config.IRepositoryConfig;
+import org.apache.felix.sigil.common.repository.IBundleRepository;
 import org.apache.felix.sigil.common.repository.IRepositoryManager;
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.internal.model.project.SigilProject;
-import org.apache.felix.sigil.eclipse.internal.repository.manager.EclipseRepositoryManager;
-import org.apache.felix.sigil.eclipse.internal.repository.manager.IRepositoryMap;
+import org.apache.felix.sigil.eclipse.internal.repository.manager.ProjectRepositoryManager;
+import org.apache.felix.sigil.eclipse.internal.repository.manager.IRepositoryCache;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.CoreException;
 
 public class SigilProjectManager
 {
-    private static HashMap<IProject, ISigilProjectModel> projects = new HashMap<IProject, ISigilProjectModel>();
-    private static HashMap<ISigilProjectModel, EclipseRepositoryManager> repositoryManagers = new HashMap<ISigilProjectModel, EclipseRepositoryManager>();
+    private final HashMap<IProject, ISigilProjectModel> projects = new HashMap<IProject, ISigilProjectModel>();
+    private final HashMap<ISigilProjectModel, ProjectRepositoryManager> repositoryManagers = new HashMap<ISigilProjectModel, ProjectRepositoryManager>();    
+    private final IRepositoryCache repositoryCache;
+    
+    public SigilProjectManager(IRepositoryCache repositoryCache) {
+        this.repositoryCache = repositoryCache;
+    }
 
     public ISigilProjectModel getSigilProject(IProject project) throws CoreException
     {
@@ -63,32 +69,51 @@
         synchronized (projects)
         {
             ISigilProjectModel model = projects.remove(project);
+            ArrayList<String> flush = new ArrayList<String>();
             if ( model != null ) {
-                EclipseRepositoryManager manager = repositoryManagers.remove(model);
-                manager.destroy();           
-            }            
+                ProjectRepositoryManager manager = repositoryManagers.remove(model);
+                manager.destroy();
+                for(IBundleRepository rep : manager.getRepositories()) {
+                    flush.add(rep.getId());
+                }
+            }
+            
+            for (ProjectRepositoryManager manager : repositoryManagers.values()) {
+                for(IBundleRepository rep : manager.getRepositories()) {
+                    flush.remove(rep.getId());
+                }
+            }
+            
+            repositoryCache.discard(flush);
         }
     }
 
     /**
      * @param model
-     * @param repositoryMap 
+     * @param repositoryCache 
      * @throws CoreException 
      */
-    public IRepositoryManager getRepositoryManager(ISigilProjectModel model, IRepositoryMap repositoryMap) throws CoreException
+    public IRepositoryManager getRepositoryManager(ISigilProjectModel model) throws CoreException
     {
         synchronized( projects ) {
-            EclipseRepositoryManager manager = repositoryManagers.get(model);
+            ProjectRepositoryManager manager = repositoryManagers.get(model);
             
             if ( manager == null ) {
-                IRepositoryConfig config = model.getRepositoryConfig();
-                
-                manager = new EclipseRepositoryManager(config, repositoryMap);
-                
+                manager = new ProjectRepositoryManager(model, repositoryCache);                
                 repositoryManagers.put(model, manager);
             }
             
             return manager;
         }
     }
+
+    /**
+     * 
+     */
+    public synchronized void destroy()
+    {
+        for(ProjectRepositoryManager man : repositoryManagers.values()) {
+            man.destroy();
+        }
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryModel.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryModel.java
index 89c8671..27d9723 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryModel.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryModel.java
@@ -19,18 +19,17 @@
 
 package org.apache.felix.sigil.eclipse.model.repository;
 
-import org.eclipse.jface.preference.PreferenceStore;
+import java.util.Properties;
 
 public interface IRepositoryModel
 {
-
     String getId();
 
-    void setName(String stringValue);
-
     String getName();
 
-    PreferenceStore getPreferences();
+    Properties getProperties();
 
     IRepositoryType getType();
+    
+    Throwable getProblem();
 }
\ No newline at end of file
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryPreferences.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryPreferences.java
index 708b74e..de40e56 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryPreferences.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryPreferences.java
@@ -21,18 +21,18 @@
 
 import java.util.List;
 
-import org.apache.felix.sigil.eclipse.internal.model.repository.RepositoryType;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.preference.IPreferenceStore;
 
 public interface IRepositoryPreferences
 {
     List<IRepositoryModel> loadRepositories();
 
-    IRepositoryModel findRepository(String id);
-
     void saveRepositories(List<IRepositoryModel> repositories) throws CoreException;
 
-    List<RepositoryType> loadRepositoryTypes();
+    List<IRepositoryType> loadRepositoryTypes();
+    
+    IPreferenceStore toPreferenceStore(IRepositoryModel model);
 
     IRepositoryModel newRepositoryElement(IRepositoryType type);
 }
\ No newline at end of file
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryType.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryType.java
index 7c706d1..e1e4987 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryType.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryType.java
@@ -24,7 +24,7 @@
 public interface IRepositoryType
 {
 
-    String getType();
+    String getName();
 
     String getId();
 
diff --git a/sigil/eclipse/obr/src/org/apache/felix/sigil/obr/eclipse/OBRRepositoryWizardPage.java b/sigil/eclipse/obr/src/org/apache/felix/sigil/obr/eclipse/OBRRepositoryWizardPage.java
index c9a949f..cd1856a 100644
--- a/sigil/eclipse/obr/src/org/apache/felix/sigil/obr/eclipse/OBRRepositoryWizardPage.java
+++ b/sigil/eclipse/obr/src/org/apache/felix/sigil/obr/eclipse/OBRRepositoryWizardPage.java
@@ -132,7 +132,7 @@
     {
         super.storeFields();
         IPath dir = Activator.getDefault().getStateLocation();
-        getModel().getPreferences().setValue( "index", dir.append( getModel().getId() + ".obr" ).toOSString() );
+        getModel().getProperties().setProperty( "index", dir.append( getModel().getId() + ".obr" ).toOSString() );
     }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/preferences/repository/RepositoriesView.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/preferences/repository/RepositoriesView.java
index 19d6783..a2db4df 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/preferences/repository/RepositoriesView.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/preferences/repository/RepositoriesView.java
@@ -285,7 +285,7 @@
     }
 
     @SuppressWarnings("unchecked")
-    protected void refresh(Control parent, IStructuredSelection sel)
+    private void refresh(Control parent, IStructuredSelection sel)
     {
         ArrayList<IRepositoryModel> models = new ArrayList<IRepositoryModel>(sel.size());
 
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/preferences/repository/RepositoryTypeSelectionPage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/preferences/repository/RepositoryTypeSelectionPage.java
index f36a85e..74e856a 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/preferences/repository/RepositoryTypeSelectionPage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/preferences/repository/RepositoryTypeSelectionPage.java
@@ -75,7 +75,7 @@
             public String getText(Object element)
             {
                 IRepositoryType rep = (IRepositoryType) element;
-                return rep.getType();
+                return rep.getName();
             }
 
             @Override
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/repository/FileSystemRepositoryWizardPage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/repository/FileSystemRepositoryWizardPage.java
index 5e5b935..96a5374 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/repository/FileSystemRepositoryWizardPage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/repository/FileSystemRepositoryWizardPage.java
@@ -26,8 +26,6 @@
 import org.eclipse.jface.preference.BooleanFieldEditor;
 import org.eclipse.jface.preference.DirectoryFieldEditor;
 import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
 
 public class FileSystemRepositoryWizardPage extends RepositoryWizardPage implements IWizardPage
 {
@@ -43,15 +41,6 @@
     public void createFieldEditors()
     {
         dirEditor = new DirectoryFieldEditor("dir", "Directory:", getFieldEditorParent());
-        dirEditor.getTextControl(getFieldEditorParent()).addModifyListener(
-            new ModifyListener()
-            {
-                public void modifyText(ModifyEvent e)
-                {
-                    checkPageComplete();
-                }
-            });
-
         addField(dirEditor);
         addField(new BooleanFieldEditor("recurse", "Recurse:", getFieldEditorParent()));
     }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/views/RepositoryViewPart.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/views/RepositoryViewPart.java
index 1a85949..d2f60ea 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/views/RepositoryViewPart.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/internal/views/RepositoryViewPart.java
@@ -113,8 +113,7 @@
         public RepositoryAction(IBundleRepository rep)
         {
             this.rep = rep;
-            this.model = SigilCore.getRepositoryPreferences().findRepository(
-                rep.getId());
+            this.model = SigilCore.getRepositoryModel(rep);
         }
 
         @Override
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/util/ModelLabelProvider.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/util/ModelLabelProvider.java
index 71d32cb..7103095 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/util/ModelLabelProvider.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/util/ModelLabelProvider.java
@@ -93,8 +93,7 @@
         if (element instanceof IBundleRepository)
         {
             IBundleRepository rep = (IBundleRepository) element;
-            IRepositoryModel config = SigilCore.getRepositoryPreferences().findRepository(
-                rep.getId());
+            IRepositoryModel config = SigilCore.getRepositoryModel(rep);
             return config.getType().getIcon();
         }
 
@@ -168,8 +167,7 @@
         if (element instanceof IBundleRepository)
         {
             IBundleRepository rep = (IBundleRepository) element;
-            IRepositoryModel config = SigilCore.getRepositoryPreferences().findRepository(
-                rep.getId());
+            IRepositoryModel config = SigilCore.getRepositoryModel(rep);
             return config.getName();
         }
 
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/wizard/repository/RepositoryWizardPage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/wizard/repository/RepositoryWizardPage.java
index ca922d2..bf94a38 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/wizard/repository/RepositoryWizardPage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/eclipse/ui/wizard/repository/RepositoryWizardPage.java
@@ -21,8 +21,10 @@
 
 import java.util.ArrayList;
 
+import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
 import org.eclipse.jface.preference.FieldEditor;
+import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.preference.StringFieldEditor;
 import org.eclipse.jface.wizard.WizardPage;
 import org.eclipse.swt.SWT;
@@ -34,9 +36,10 @@
 public abstract class RepositoryWizardPage extends WizardPage
 {
 
-    private StringFieldEditor nameEditor;
     private ArrayList<FieldEditor> editors = new ArrayList<FieldEditor>();
     private RepositoryWizard wizard;
+    private IPreferenceStore prefs;
+    private StringFieldEditor nameEditor;
 
     protected RepositoryWizardPage(String pageName, RepositoryWizard parent)
     {
@@ -60,20 +63,13 @@
         if (getModel().getType().isDynamic())
         {
             nameEditor = new StringFieldEditor("name", "Name:", control);
-            nameEditor.setStringValue(getModel().getName());
-            nameEditor.getTextControl(getFieldEditorParent()).addModifyListener(
-                new ModifyListener()
-                {
-                    public void modifyText(ModifyEvent e)
-                    {
-                        checkPageComplete();
-                    }
-                });
+            nameEditor.setEmptyStringAllowed(false);
+            addField(nameEditor);
         }
 
         createFieldEditors();
 
-        int cols = nameEditor == null ? 0 : nameEditor.getNumberOfControls();
+        int cols = 0;
         for (FieldEditor e : editors)
         {
             cols = Math.max(cols, e.getNumberOfControls());
@@ -81,15 +77,21 @@
 
         control.setLayout(new GridLayout(cols, false));
 
-        if (nameEditor != null)
-        {
-            nameEditor.fillIntoGrid(getFieldEditorParent(), cols);
-        }
-
         for (FieldEditor e : editors)
         {
+            if (e instanceof StringFieldEditor) {
+                StringFieldEditor sfe = (StringFieldEditor) e;
+                sfe.getTextControl(getFieldEditorParent()).addModifyListener(
+                    new ModifyListener()
+                    {
+                        public void modifyText(ModifyEvent e)
+                        {
+                            checkPageComplete();
+                        }
+                    });
+            }
             e.fillIntoGrid(getFieldEditorParent(), cols);
-            e.setPreferenceStore(getModel().getPreferences());
+            e.setPreferenceStore(getStore());
             e.load();
         }
 
@@ -100,7 +102,19 @@
     {
         if (nameEditor != null)
         {
-            setPageComplete(nameEditor.getStringValue().length() > 0);
+            int len = nameEditor.getStringValue().length();
+            boolean ok = len > 0;
+            setPageComplete(ok);
+            if ( !ok ) {
+                setErrorMessage("Name should not be empty");
+            }
+            else {
+                ok = nameEditor.getStringValue().trim().length() == len;
+                setPageComplete(ok);
+                if ( !ok ) {
+                    setErrorMessage("Name cannot start or end with whitespace");
+                }
+            }
         }
     }
 
@@ -108,6 +122,14 @@
     {
         return wizard.getModel();
     }
+    
+    protected IPreferenceStore getStore() {
+        if ( prefs == null ) {
+            prefs = SigilCore.getRepositoryPreferences().toPreferenceStore(getModel());
+        }
+        
+        return prefs;
+    }
 
     protected Composite getFieldEditorParent()
     {
@@ -116,13 +138,10 @@
 
     public void storeFields()
     {
-        getModel().setName(nameEditor.getStringValue());
         for (FieldEditor e : editors)
         {
             e.store();
         }
-        getModel().getPreferences().setValue("provider", getModel().getType().getProvider());
-
     }
 
 }