FELIX-1322 bulk update of formatting based on eclipse style referenced in http://felix.apache.org/site/coding-standards.html


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@796467 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/sigil/common/core.tests/src/org/apache/felix/sigil/core/BundleModelElementTest.java b/sigil/common/core.tests/src/org/apache/felix/sigil/core/BundleModelElementTest.java
index 4a97475..430d14e 100644
--- a/sigil/common/core.tests/src/org/apache/felix/sigil/core/BundleModelElementTest.java
+++ b/sigil/common/core.tests/src/org/apache/felix/sigil/core/BundleModelElementTest.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core;
 
+
 import java.util.Arrays;
 
 import org.apache.felix.sigil.core.internal.model.osgi.BundleModelElement;
@@ -28,69 +29,82 @@
 
 import junit.framework.TestCase;
 
-public class BundleModelElementTest extends TestCase {
 
-	public BundleModelElementTest(String name) {
-		super(name);
-	}
-	
-	public void testAddRequires() {
-		BundleModelElement element = new BundleModelElement();
-		checkRequires(element);
-	}
-	
-	public void testAddImports() {
-		BundleModelElement element = new BundleModelElement();
-		checkImports(element);
-	}
-	
-	public void testAddImportsAndRequires() {
-		BundleModelElement element = new BundleModelElement();
-		checkImports(element);
-		checkRequires(element);
-		
-		element = new BundleModelElement();
-		checkRequires(element);
-		checkImports(element);
-	}
-	
-	private void checkImports(BundleModelElement element) {
-		PackageImport foo = new PackageImport();
-		foo.setPackageName("foo");
-		foo.setVersions( VersionRange.parseVersionRange("1.0.0") );
-		PackageImport bar = new PackageImport();
-		bar.setPackageName( "bar" );
-		bar.setVersions( VersionRange.parseVersionRange("[2.2.2, 3.3.3]") );
-		PackageImport baz = new PackageImport();
-		baz.setPackageName( "baz" );
-		baz.setVersions( VersionRange.parseVersionRange("[3.0.0, 4.0.0)") );
-		
-		element.addChild(foo.clone());
-		element.addChild(bar.clone());
-		element.addChild(baz.clone());
-		
-		assertTrue( Arrays.asList(element.children()).contains(foo) );
-		assertTrue( Arrays.asList(element.children()).contains(bar) );
-		assertTrue( Arrays.asList(element.children()).contains(baz) );
-	}
+public class BundleModelElementTest extends TestCase
+{
 
-	private void checkRequires(BundleModelElement element) {
-		RequiredBundle foo = new RequiredBundle();
-		foo.setSymbolicName( "foo" );
-		foo.setVersions( VersionRange.parseVersionRange("1.0.0") );
-		RequiredBundle bar = new RequiredBundle();
-		bar.setSymbolicName( "bar" );
-		bar.setVersions( VersionRange.parseVersionRange("[2.2.2, 3.3.3]") );
-		RequiredBundle baz = new RequiredBundle();
-		baz.setSymbolicName( "baz" );
-		baz.setVersions( VersionRange.parseVersionRange("[3.0.0, 4.0.0)") );
-		
-		element.addChild(foo.clone());
-		element.addChild(bar.clone());
-		element.addChild(baz.clone());
-		
-		assertTrue( Arrays.asList(element.children()).contains(foo) );
-		assertTrue( Arrays.asList(element.children()).contains(bar) );
-		assertTrue( Arrays.asList(element.children()).contains(baz) );
-	}
+    public BundleModelElementTest( String name )
+    {
+        super( name );
+    }
+
+
+    public void testAddRequires()
+    {
+        BundleModelElement element = new BundleModelElement();
+        checkRequires( element );
+    }
+
+
+    public void testAddImports()
+    {
+        BundleModelElement element = new BundleModelElement();
+        checkImports( element );
+    }
+
+
+    public void testAddImportsAndRequires()
+    {
+        BundleModelElement element = new BundleModelElement();
+        checkImports( element );
+        checkRequires( element );
+
+        element = new BundleModelElement();
+        checkRequires( element );
+        checkImports( element );
+    }
+
+
+    private void checkImports( BundleModelElement element )
+    {
+        PackageImport foo = new PackageImport();
+        foo.setPackageName( "foo" );
+        foo.setVersions( VersionRange.parseVersionRange( "1.0.0" ) );
+        PackageImport bar = new PackageImport();
+        bar.setPackageName( "bar" );
+        bar.setVersions( VersionRange.parseVersionRange( "[2.2.2, 3.3.3]" ) );
+        PackageImport baz = new PackageImport();
+        baz.setPackageName( "baz" );
+        baz.setVersions( VersionRange.parseVersionRange( "[3.0.0, 4.0.0)" ) );
+
+        element.addChild( foo.clone() );
+        element.addChild( bar.clone() );
+        element.addChild( baz.clone() );
+
+        assertTrue( Arrays.asList( element.children() ).contains( foo ) );
+        assertTrue( Arrays.asList( element.children() ).contains( bar ) );
+        assertTrue( Arrays.asList( element.children() ).contains( baz ) );
+    }
+
+
+    private void checkRequires( BundleModelElement element )
+    {
+        RequiredBundle foo = new RequiredBundle();
+        foo.setSymbolicName( "foo" );
+        foo.setVersions( VersionRange.parseVersionRange( "1.0.0" ) );
+        RequiredBundle bar = new RequiredBundle();
+        bar.setSymbolicName( "bar" );
+        bar.setVersions( VersionRange.parseVersionRange( "[2.2.2, 3.3.3]" ) );
+        RequiredBundle baz = new RequiredBundle();
+        baz.setSymbolicName( "baz" );
+        baz.setVersions( VersionRange.parseVersionRange( "[3.0.0, 4.0.0)" ) );
+
+        element.addChild( foo.clone() );
+        element.addChild( bar.clone() );
+        element.addChild( baz.clone() );
+
+        assertTrue( Arrays.asList( element.children() ).contains( foo ) );
+        assertTrue( Arrays.asList( element.children() ).contains( bar ) );
+        assertTrue( Arrays.asList( element.children() ).contains( baz ) );
+    }
 }
diff --git a/sigil/common/core.tests/src/org/apache/felix/sigil/core/ConfigTest.java b/sigil/common/core.tests/src/org/apache/felix/sigil/core/ConfigTest.java
index cf4bd39..9a5596a 100644
--- a/sigil/common/core.tests/src/org/apache/felix/sigil/core/ConfigTest.java
+++ b/sigil/common/core.tests/src/org/apache/felix/sigil/core/ConfigTest.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core;
 
+
 import java.io.IOException;
 import java.net.URI;
 import java.util.Set;
@@ -33,39 +34,47 @@
 import org.apache.felix.sigil.model.osgi.IBundleModelElement;
 import org.apache.felix.sigil.model.osgi.IPackageImport;
 
-public class ConfigTest extends TestCase {
-	
-	static final URI base = URI.create("test/ConfigTest/sigil.properties");
 
-	public ConfigTest(String name) {
-		super(name);
-	}
-	
-	public void testSimple() throws IOException {
-		IBldProject project = BldFactory.getProject(base.resolve("test1.properties"));
-		
-		ISigilBundle bundle = project.getDefaultBundle();
-		IBundleModelElement info = bundle.getBundleInfo();
-		
-		checkImports(info.getImports());
-		
-		//IBundleModelElement requirements = project.getRequirements();
-	}
-	
-	private void checkImports(Set<IPackageImport> imports) {
-		PackageImport foo = new PackageImport();
-		foo.setPackageName("foo");
-		foo.setVersions(VersionRange.parseVersionRange("1.0.0"));
-		PackageImport bar = new PackageImport();
-		bar.setPackageName( "bar" );
-		bar.setVersions(VersionRange.parseVersionRange("[2.2.2, 3.3.3]"));
-		PackageImport baz = new PackageImport();
-		baz.setPackageName( "baz" );
-		baz.setVersions(VersionRange.parseVersionRange("[3.0.0, 4.0.0)"));
-		
-		assertTrue(foo.toString(), imports.contains(foo));
-		assertTrue(bar.toString(), imports.contains(bar));
-		assertTrue(baz.toString(), imports.contains(baz));
-	}
+public class ConfigTest extends TestCase
+{
+
+    static final URI base = URI.create( "test/ConfigTest/sigil.properties" );
+
+
+    public ConfigTest( String name )
+    {
+        super( name );
+    }
+
+
+    public void testSimple() throws IOException
+    {
+        IBldProject project = BldFactory.getProject( base.resolve( "test1.properties" ) );
+
+        ISigilBundle bundle = project.getDefaultBundle();
+        IBundleModelElement info = bundle.getBundleInfo();
+
+        checkImports( info.getImports() );
+
+        //IBundleModelElement requirements = project.getRequirements();
+    }
+
+
+    private void checkImports( Set<IPackageImport> imports )
+    {
+        PackageImport foo = new PackageImport();
+        foo.setPackageName( "foo" );
+        foo.setVersions( VersionRange.parseVersionRange( "1.0.0" ) );
+        PackageImport bar = new PackageImport();
+        bar.setPackageName( "bar" );
+        bar.setVersions( VersionRange.parseVersionRange( "[2.2.2, 3.3.3]" ) );
+        PackageImport baz = new PackageImport();
+        baz.setPackageName( "baz" );
+        baz.setVersions( VersionRange.parseVersionRange( "[3.0.0, 4.0.0)" ) );
+
+        assertTrue( foo.toString(), imports.contains( foo ) );
+        assertTrue( bar.toString(), imports.contains( bar ) );
+        assertTrue( baz.toString(), imports.contains( baz ) );
+    }
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/bnd/BundleBuilder.java b/sigil/common/core/src/org/apache/felix/sigil/bnd/BundleBuilder.java
index 8886ffa..f76e9bd 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/bnd/BundleBuilder.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/bnd/BundleBuilder.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.bnd;
 
+
 import static java.lang.String.format;
 
 import java.io.File;
@@ -52,11 +53,13 @@
 import aQute.lib.osgi.Jar;
 import aQute.lib.osgi.Processor;
 
-public class BundleBuilder {
+
+public class BundleBuilder
+{
     public static final String COMPONENT_ACTIVATOR_PKG = "XXX-FIXME-XXX";
     public static final String COMPONENT_ACTIVATOR = COMPONENT_ACTIVATOR_PKG + ".Activator";
-    public static final String[] COMPONENT_ACTIVATOR_DEPS = { "XXX-FIXME-XXX",
-            "org.osgi.framework", "org.osgi.util.tracker" };
+    public static final String[] COMPONENT_ACTIVATOR_DEPS =
+        { "XXX-FIXME-XXX", "org.osgi.framework", "org.osgi.util.tracker" };
     public static final String COMPONENT_DIR = "META-INF/XXX-FIXME-XXX";
     public static final String COMPONENT_FLAG = "Installable-Component";
     public static final String COMPONENT_LIST = "Installable-Component-Templates";
@@ -77,12 +80,15 @@
     private String codebaseFormat;
     private Set<String> systemPkgs;
 
-    public interface Log {
-        void warn(String msg);
+    public interface Log
+    {
+        void warn( String msg );
 
-        void verbose(String msg);
+
+        void verbose( String msg );
     }
 
+
     /**
      * creates a BundleBuilder.
      * 
@@ -93,7 +99,8 @@
      *            [ext] is replaced with "jar".
      * @param hashtable
      */
-    public BundleBuilder(IBldProject project, File[] classpath, String destPattern, Properties env) {
+    public BundleBuilder( IBldProject project, File[] classpath, String destPattern, Properties env )
+    {
         this.project = project;
         this.classpath = classpath;
         this.destPattern = destPattern;
@@ -101,116 +108,139 @@
 
         Properties options = project.getOptions();
 
-        addMissingImports = options.containsKey(BldAttr.OPTION_ADD_IMPORTS)
-                && Boolean.parseBoolean(options.getProperty(BldAttr.OPTION_ADD_IMPORTS));
-        omitUnusedImports = options.containsKey(BldAttr.OPTION_OMIT_IMPORTS)
-                && Boolean.parseBoolean(options.getProperty(BldAttr.OPTION_OMIT_IMPORTS));
+        addMissingImports = options.containsKey( BldAttr.OPTION_ADD_IMPORTS )
+            && Boolean.parseBoolean( options.getProperty( BldAttr.OPTION_ADD_IMPORTS ) );
+        omitUnusedImports = options.containsKey( BldAttr.OPTION_OMIT_IMPORTS )
+            && Boolean.parseBoolean( options.getProperty( BldAttr.OPTION_OMIT_IMPORTS ) );
 
-        defaultPubtype = options.getProperty(BldAttr.PUBTYPE_ATTRIBUTE, "rmi.codebase");
+        defaultPubtype = options.getProperty( BldAttr.PUBTYPE_ATTRIBUTE, "rmi.codebase" );
 
-        codebaseFormat = options.getProperty("codebaseFormat",
-                "cds://%1$s?bundle.symbolic.name=%2$s&type=%3$s");
+        codebaseFormat = options.getProperty( "codebaseFormat", "cds://%1$s?bundle.symbolic.name=%2$s&type=%3$s" );
 
-        for (IBldBundle b : project.getBundles()) {
+        for ( IBldBundle b : project.getBundles() )
+        {
             lastBundle = b.getId();
-            for (IPackageImport import1 : b.getImports()) {
-                if (import1.getOSGiImport().equals(IPackageImport.OSGiImport.AUTO)) {
-                    unused.add(import1.getPackageName());
+            for ( IPackageImport import1 : b.getImports() )
+            {
+                if ( import1.getOSGiImport().equals( IPackageImport.OSGiImport.AUTO ) )
+                {
+                    unused.add( import1.getPackageName() );
                 }
             }
         }
 
-        try {
+        try
+        {
             systemPkgs = new HashSet<String>();
-            Properties profile = SystemRepositoryProvider.readProfile(null);
-            String pkgs = profile.getProperty("org.osgi.framework.system.packages");
-            for (String pkg : pkgs.split(",\\s*")) {
-                systemPkgs.add(pkg);
+            Properties profile = SystemRepositoryProvider.readProfile( null );
+            String pkgs = profile.getProperty( "org.osgi.framework.system.packages" );
+            for ( String pkg : pkgs.split( ",\\s*" ) )
+            {
+                systemPkgs.add( pkg );
             }
-        } catch (IOException e) {
+        }
+        catch ( IOException e )
+        {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
     }
 
-    public List<String> errors() {
+
+    public List<String> errors()
+    {
         return errors;
     }
 
-    public List<String> warnings() {
+
+    public List<String> warnings()
+    {
         return warnings;
     }
 
+
     @SuppressWarnings("unchecked")
-    private void convertErrors(String prefix, List messages) {
+    private void convertErrors( String prefix, List messages )
+    {
         // TODO: make error mapping more generic
         final String jarEmpty = "The JAR is empty";
 
-        for (Object omsg : messages) {
-            if (jarEmpty.equals(omsg))
-                warnings.add(prefix + omsg);
+        for ( Object omsg : messages )
+        {
+            if ( jarEmpty.equals( omsg ) )
+                warnings.add( prefix + omsg );
             else
-                errors.add(prefix + omsg);
+                errors.add( prefix + omsg );
         }
     }
 
+
     @SuppressWarnings("unchecked")
-    private void convertWarnings(String prefix, List messages) {
-        for (Object omsg : messages) {
-            warnings.add(prefix + omsg);
+    private void convertWarnings( String prefix, List messages )
+    {
+        for ( Object omsg : messages )
+        {
+            warnings.add( prefix + omsg );
         }
     }
 
-    public boolean createBundle(IBldBundle bundle, boolean force, Log log) throws Exception {
-        int bracket = destPattern.indexOf('[');
-        if (bracket < 0) {
-            throw new Exception("destPattern MUST contain [id] or [name].");
+
+    public boolean createBundle( IBldBundle bundle, boolean force, Log log ) throws Exception
+    {
+        int bracket = destPattern.indexOf( '[' );
+        if ( bracket < 0 )
+        {
+            throw new Exception( "destPattern MUST contain [id] or [name]." );
         }
 
-        String dest = destPattern.replaceFirst("\\[id\\]", bundle.getId());
-        dest = dest.replaceFirst("\\[name\\]", bundle.getSymbolicName());
-        dest = dest.replaceFirst("\\[ext\\]", "jar");
+        String dest = destPattern.replaceFirst( "\\[id\\]", bundle.getId() );
+        dest = dest.replaceFirst( "\\[name\\]", bundle.getSymbolicName() );
+        dest = dest.replaceFirst( "\\[ext\\]", "jar" );
 
-        bracket = dest.indexOf('[');
-        if (bracket >= 0) {
-            String token = dest.substring(bracket);
-            throw new Exception("destPattern: expected [id] or [name]: " + token);
+        bracket = dest.indexOf( '[' );
+        if ( bracket >= 0 )
+        {
+            String token = dest.substring( bracket );
+            throw new Exception( "destPattern: expected [id] or [name]: " + token );
         }
 
         errors.clear();
         warnings.clear();
 
-        if (!bundle.getDownloadContents().isEmpty()) {
+        if ( !bundle.getDownloadContents().isEmpty() )
+        {
             // create dljar
             Properties dlspec = new Properties();
             StringBuilder sb = new StringBuilder();
 
-            for (String pkg : bundle.getDownloadContents()) {
-                if (sb.length() > 0)
-                    sb.append(",");
-                sb.append(pkg);
+            for ( String pkg : bundle.getDownloadContents() )
+            {
+                if ( sb.length() > 0 )
+                    sb.append( "," );
+                sb.append( pkg );
             }
 
-            dlspec.setProperty(Constants.PRIVATE_PACKAGE, sb.toString());
-            dlspec.setProperty(Constants.BUNDLE_NAME, "Newton download jar");
-            dlspec.setProperty(Constants.NOEXTRAHEADERS, "true");
+            dlspec.setProperty( Constants.PRIVATE_PACKAGE, sb.toString() );
+            dlspec.setProperty( Constants.BUNDLE_NAME, "Newton download jar" );
+            dlspec.setProperty( Constants.NOEXTRAHEADERS, "true" );
             // stop it being a bundle, so cds doesn't scan it
-            dlspec.setProperty(Constants.REMOVE_HEADERS, Constants.BUNDLE_SYMBOLICNAME);
+            dlspec.setProperty( Constants.REMOVE_HEADERS, Constants.BUNDLE_SYMBOLICNAME );
 
             Builder builder = new Builder();
-            builder.setProperties(dlspec);
-            builder.setClasspath(classpath);
+            builder.setProperties( dlspec );
+            builder.setClasspath( classpath );
 
             Jar dljar = builder.build();
-            convertErrors("BND (dljar): ", builder.getErrors());
-            convertWarnings("BND (dljar): ", builder.getWarnings());
+            convertErrors( "BND (dljar): ", builder.getErrors() );
+            convertWarnings( "BND (dljar): ", builder.getWarnings() );
 
-            String dldest = dest.replaceFirst("\\.jar$", "-dl.jar");
-            File dloutput = new File(dldest);
-            if (!dloutput.exists() || dloutput.lastModified() <= dljar.lastModified() || force) {
+            String dldest = dest.replaceFirst( "\\.jar$", "-dl.jar" );
+            File dloutput = new File( dldest );
+            if ( !dloutput.exists() || dloutput.lastModified() <= dljar.lastModified() || force )
+            {
                 // jar.write(dldest) catches and ignores IOException
-                OutputStream out = new FileOutputStream(dldest);
-                dljar.write(out);
+                OutputStream out = new FileOutputStream( dldest );
+                dljar.write( out );
                 out.close();
                 dljar.close();
                 // XXX deleting dljar causes it to be rebuilt each time
@@ -221,46 +251,51 @@
             builder.close();
         }
 
-        Properties spec = getBndSpec(bundle, dest);
+        Properties spec = getBndSpec( bundle, dest );
 
-        if (log != null) {
-            log.verbose("BND instructions: " + spec.toString());
+        if ( log != null )
+        {
+            log.verbose( "BND instructions: " + spec.toString() );
         }
 
         Builder builder = new Builder();
-        builder.setPedantic(true);
-        builder.setProperties(spec);
-        builder.mergeProperties(env, false);
+        builder.setPedantic( true );
+        builder.setProperties( spec );
+        builder.mergeProperties( env, false );
 
-        builder.setClasspath(classpath);
+        builder.setClasspath( classpath );
         // builder.setSourcepath(sourcepath);
 
         Jar jar = builder.build();
 
-        convertErrors("BND: ", builder.getErrors());
-        convertWarnings("BND: ", builder.getWarnings());
+        convertErrors( "BND: ", builder.getErrors() );
+        convertWarnings( "BND: ", builder.getWarnings() );
 
-        augmentImports(builder, jar, bundle);
+        augmentImports( builder, jar, bundle );
 
-        if (log != null) {
-            for (String warn : warnings) {
-                log.warn(warn);
+        if ( log != null )
+        {
+            for ( String warn : warnings )
+            {
+                log.warn( warn );
             }
         }
 
-        if (!errors.isEmpty()) {
-            throw new Exception(errors.toString());
+        if ( !errors.isEmpty() )
+        {
+            throw new Exception( errors.toString() );
         }
 
         boolean modified = false;
-        File output = new File(dest);
+        File output = new File( dest );
 
-        if (!output.exists() || force || (output.lastModified() <= jar.lastModified())
-                || (output.lastModified() <= project.getLastModified())) {
+        if ( !output.exists() || force || ( output.lastModified() <= jar.lastModified() )
+            || ( output.lastModified() <= project.getLastModified() ) )
+        {
             modified = true;
             // jar.write(dest) catches and ignores IOException
-            OutputStream out = new FileOutputStream(dest);
-            jar.write(out);
+            OutputStream out = new FileOutputStream( dest );
+            jar.write( out );
             out.close();
             jar.close();
         }
@@ -270,12 +305,14 @@
         return modified;
     }
 
-    private void augmentImports(Builder builder, Jar jar, IBldBundle bundle) throws IOException {
-        Attributes main = jar.getManifest().getMainAttributes();
-        String impHeader = main.getValue(Constants.IMPORT_PACKAGE);
-        Map<String, Map<String, String>> bndImports = Processor.parseHeader(impHeader, builder);
 
-        if (bndImports.isEmpty())
+    private void augmentImports( Builder builder, Jar jar, IBldBundle bundle ) throws IOException
+    {
+        Attributes main = jar.getManifest().getMainAttributes();
+        String impHeader = main.getValue( Constants.IMPORT_PACKAGE );
+        Map<String, Map<String, String>> bndImports = Processor.parseHeader( impHeader, builder );
+
+        if ( bndImports.isEmpty() )
             return;
 
         ArrayList<String> self = new ArrayList<String>();
@@ -283,204 +320,243 @@
         ArrayList<String> modified = new ArrayList<String>();
         ArrayList<String> unversioned = new ArrayList<String>();
 
-        String expHeader = main.getValue(Constants.EXPORT_PACKAGE);
-        Set<String> bndExports = Processor.parseHeader(expHeader, builder).keySet();
+        String expHeader = main.getValue( Constants.EXPORT_PACKAGE );
+        Set<String> bndExports = Processor.parseHeader( expHeader, builder ).keySet();
 
         HashMap<String, IPackageImport> imports = new HashMap<String, IPackageImport>();
-        for (IPackageImport pi : getImports(bundle)) {
-            switch (pi.getOSGiImport()) {
-            case NEVER:
-                break;
-            case ALWAYS:
-                String pkg = pi.getPackageName();
-                if (!bndImports.containsKey(pkg)) {
-                    // Bnd doesn't think this import is needed - but we know
-                    // better
-                    HashMap<String, String> attrs = new HashMap<String, String>();
-                    attrs.put(BldAttr.VERSION_ATTRIBUTE, pi.getVersions().toString());
-                    bndImports.put(pkg, attrs);
-                    modified.add(pkg + ";resolve=runtime");
-                }
-                // fall thru */
-            case AUTO:
-                imports.put(pi.getPackageName(), pi);
-                break;
+        for ( IPackageImport pi : getImports( bundle ) )
+        {
+            switch ( pi.getOSGiImport() )
+            {
+                case NEVER:
+                    break;
+                case ALWAYS:
+                    String pkg = pi.getPackageName();
+                    if ( !bndImports.containsKey( pkg ) )
+                    {
+                        // Bnd doesn't think this import is needed - but we know
+                        // better
+                        HashMap<String, String> attrs = new HashMap<String, String>();
+                        attrs.put( BldAttr.VERSION_ATTRIBUTE, pi.getVersions().toString() );
+                        bndImports.put( pkg, attrs );
+                        modified.add( pkg + ";resolve=runtime" );
+                    }
+                    // fall thru */
+                case AUTO:
+                    imports.put( pi.getPackageName(), pi );
+                    break;
             }
         }
 
         boolean importDot = false;
 
-        for (String pkg : bndImports.keySet()) {
-            unused.remove(pkg);
-            Map<String, String> attrs = bndImports.get(pkg);
-            String currentVersion = (String) attrs.get(BldAttr.VERSION_ATTRIBUTE);
-            IPackageImport pi = imports.get(pkg);
+        for ( String pkg : bndImports.keySet() )
+        {
+            unused.remove( pkg );
+            Map<String, String> attrs = bndImports.get( pkg );
+            String currentVersion = ( String ) attrs.get( BldAttr.VERSION_ATTRIBUTE );
+            IPackageImport pi = imports.get( pkg );
 
-            if (pi != null) {
+            if ( pi != null )
+            {
                 VersionRange range = pi.getVersions();
                 String version = range.toString();
 
-                if (!version.equals(currentVersion) && !range.equals(VersionRange.ANY_VERSION)) {
-                    attrs.put(BldAttr.VERSION_ATTRIBUTE, version);
-                    if (pi.isOptional())
-                        attrs.put(BldAttr.RESOLUTION_ATTRIBUTE, BldAttr.RESOLUTION_OPTIONAL);
-                    modified
-                            .add(pkg + ";version=" + version + (pi.isOptional() ? ";optional" : ""));
-                } else if ((currentVersion == null) && !systemPkgs.contains(pkg)) {
-                    unversioned.add(pkg);
+                if ( !version.equals( currentVersion ) && !range.equals( VersionRange.ANY_VERSION ) )
+                {
+                    attrs.put( BldAttr.VERSION_ATTRIBUTE, version );
+                    if ( pi.isOptional() )
+                        attrs.put( BldAttr.RESOLUTION_ATTRIBUTE, BldAttr.RESOLUTION_OPTIONAL );
+                    modified.add( pkg + ";version=" + version + ( pi.isOptional() ? ";optional" : "" ) );
                 }
-            } else {
+                else if ( ( currentVersion == null ) && !systemPkgs.contains( pkg ) )
+                {
+                    unversioned.add( pkg );
+                }
+            }
+            else
+            {
                 // bnd added the import ...
-                if (currentVersion == null) {
-                    String defaultVersion = project.getDefaultPackageVersion(pkg);
-                    if (defaultVersion != null) {
-                        attrs.put(BldAttr.VERSION_ATTRIBUTE, defaultVersion);
+                if ( currentVersion == null )
+                {
+                    String defaultVersion = project.getDefaultPackageVersion( pkg );
+                    if ( defaultVersion != null )
+                    {
+                        attrs.put( BldAttr.VERSION_ATTRIBUTE, defaultVersion );
                         currentVersion = defaultVersion;
                     }
                 }
 
-                String imp = pkg + (currentVersion == null ? "" : ";version=" + currentVersion);
-                if (bndExports.contains(pkg)) {
-                    self.add(imp);
-                } else {
-                    if (pkg.equals(".")) {
-                        warnings.add("Bnd wants to import '.' (ignored)");
+                String imp = pkg + ( currentVersion == null ? "" : ";version=" + currentVersion );
+                if ( bndExports.contains( pkg ) )
+                {
+                    self.add( imp );
+                }
+                else
+                {
+                    if ( pkg.equals( "." ) )
+                    {
+                        warnings.add( "Bnd wants to import '.' (ignored)" );
                         importDot = true;
-                    } else {
-                        missing.add(imp);
+                    }
+                    else
+                    {
+                        missing.add( imp );
                     }
                 }
             }
         }
 
-        if (!modified.isEmpty() || importDot) {
-            if (importDot)
-                bndImports.remove(".");
+        if ( !modified.isEmpty() || importDot )
+        {
+            if ( importDot )
+                bndImports.remove( "." );
             // warnings.add("INFO: sigil modified imports: " + modified);
-            main.putValue(Constants.IMPORT_PACKAGE, Processor.printClauses(bndImports,
-                    "resolution:"));
+            main.putValue( Constants.IMPORT_PACKAGE, Processor.printClauses( bndImports, "resolution:" ) );
         }
 
-        if (!self.isEmpty()) {
+        if ( !self.isEmpty() )
+        {
             // warnings.add("INFO: added self imports: " + self);
         }
 
-        if (!missing.isEmpty()) {
-            warnings.add("missing imports (added): " + missing);
+        if ( !missing.isEmpty() )
+        {
+            warnings.add( "missing imports (added): " + missing );
         }
 
-        if (!unversioned.isEmpty()) {
-            warnings.add("unversioned imports: " + unversioned);
+        if ( !unversioned.isEmpty() )
+        {
+            warnings.add( "unversioned imports: " + unversioned );
         }
 
-        if (bundle.getId().equals(lastBundle)) {
-            if (!unused.isEmpty()) {
-                warnings.add("unused imports (omitted): " + unused);
+        if ( bundle.getId().equals( lastBundle ) )
+        {
+            if ( !unused.isEmpty() )
+            {
+                warnings.add( "unused imports (omitted): " + unused );
             }
         }
     }
 
-    public Properties getBndSpec(IBldBundle bundle, String dest) throws IOException {
+
+    public Properties getBndSpec( IBldBundle bundle, String dest ) throws IOException
+    {
         Properties spec = new Properties();
 
         String junkHeaders = Constants.INCLUDE_RESOURCE; // shows local build
-                                                         // paths; can be
-                                                         // verbose
+        // paths; can be
+        // verbose
         junkHeaders += "," + Constants.PRIVATE_PACKAGE; // less useful, as we
-                                                        // use it for exported
-                                                        // content too.
+        // use it for exported
+        // content too.
 
-        spec.setProperty(Constants.REMOVE_HEADERS, junkHeaders);
-        spec.setProperty(Constants.NOEXTRAHEADERS, "true"); // Created-By,
-                                                            // Bnd-LastModified
-                                                            // and Tool
-        spec.setProperty(Constants.CREATED_BY, "sigil.codecauldron.org");
+        spec.setProperty( Constants.REMOVE_HEADERS, junkHeaders );
+        spec.setProperty( Constants.NOEXTRAHEADERS, "true" ); // Created-By,
+        // Bnd-LastModified
+        // and Tool
+        spec.setProperty( Constants.CREATED_BY, "sigil.codecauldron.org" );
 
         Properties headers = bundle.getHeaders();
         // XXX: catch attempts to set headers that conflict with Bnd
         // instructions we generate?
-        spec.putAll(headers);
+        spec.putAll( headers );
 
-        spec.setProperty(Constants.BUNDLE_SYMBOLICNAME, bundle.getSymbolicName());
-        spec.setProperty(Constants.BUNDLE_VERSION, bundle.getVersion());
+        spec.setProperty( Constants.BUNDLE_SYMBOLICNAME, bundle.getSymbolicName() );
+        spec.setProperty( Constants.BUNDLE_VERSION, bundle.getVersion() );
 
         String activator = bundle.getActivator();
-        if (activator != null)
-            spec.setProperty(Constants.BUNDLE_ACTIVATOR, activator);
+        if ( activator != null )
+            spec.setProperty( Constants.BUNDLE_ACTIVATOR, activator );
 
-        addRequirements(bundle, spec);
+        addRequirements( bundle, spec );
 
-        List<String> exports = addExports(bundle, spec);
+        List<String> exports = addExports( bundle, spec );
 
-        String composites = addResources(bundle, spec);
+        String composites = addResources( bundle, spec );
 
         ArrayList<String> contents = new ArrayList<String>();
-        contents.addAll(bundle.getContents());
+        contents.addAll( bundle.getContents() );
 
-        if (contents.isEmpty()) {
-            if (!project.getSourcePkgs().isEmpty()) {
-                contents.addAll(project.getSourcePkgs());
-            } else {
-                contents.addAll(exports);
+        if ( contents.isEmpty() )
+        {
+            if ( !project.getSourcePkgs().isEmpty() )
+            {
+                contents.addAll( project.getSourcePkgs() );
+            }
+            else
+            {
+                contents.addAll( exports );
             }
         }
 
-        if (composites.length() > 0) {
-            if (spec.containsKey(Constants.BUNDLE_ACTIVATOR))
-                warnings.add("-activator ignored when -composites specified.");
-            spec.setProperty(Constants.BUNDLE_ACTIVATOR, COMPONENT_ACTIVATOR);
-            spec.setProperty(COMPONENT_FLAG, "true");
-            spec.setProperty(COMPONENT_LIST, composites);
+        if ( composites.length() > 0 )
+        {
+            if ( spec.containsKey( Constants.BUNDLE_ACTIVATOR ) )
+                warnings.add( "-activator ignored when -composites specified." );
+            spec.setProperty( Constants.BUNDLE_ACTIVATOR, COMPONENT_ACTIVATOR );
+            spec.setProperty( COMPONENT_FLAG, "true" );
+            spec.setProperty( COMPONENT_LIST, composites );
             // add activator pkg directly, to avoid needing to add jar to
             // Bundle-ClassPath.
             // split-package directive needed to stop Bnd whinging when using
             // other bundles containing the component-activator.
-            contents.add(COMPONENT_ACTIVATOR_PKG + ";-split-package:=merge-first");
+            contents.add( COMPONENT_ACTIVATOR_PKG + ";-split-package:=merge-first" );
         }
 
-        List<String> srcPkgs = addLibs(bundle, dest, spec);
+        List<String> srcPkgs = addLibs( bundle, dest, spec );
 
-        contents.addAll(srcPkgs);
-        addContents(contents, spec);
+        contents.addAll( srcPkgs );
+        addContents( contents, spec );
 
         IRequiredBundle fh = bundle.getFragmentHost();
-        if (fh != null) {
+        if ( fh != null )
+        {
             StringBuilder sb = new StringBuilder();
-            sb.append(fh.getSymbolicName());
-            addVersions(fh.getVersions(), sb);
-            spec.setProperty(Constants.FRAGMENT_HOST, sb.toString());
+            sb.append( fh.getSymbolicName() );
+            addVersions( fh.getVersions(), sb );
+            spec.setProperty( Constants.FRAGMENT_HOST, sb.toString() );
         }
 
         return spec;
     }
 
-    private void addContents(List<String> contents, Properties spec) {
+
+    private void addContents( List<String> contents, Properties spec )
+    {
         // add contents
         StringBuilder sb = new StringBuilder();
-        for (String pkg : contents) {
-            if (sb.length() > 0)
-                sb.append(",");
-            sb.append(pkg);
+        for ( String pkg : contents )
+        {
+            if ( sb.length() > 0 )
+                sb.append( "," );
+            sb.append( pkg );
         }
 
-        if (sb.length() > 0)
-            spec.setProperty(Constants.PRIVATE_PACKAGE, sb.toString());
+        if ( sb.length() > 0 )
+            spec.setProperty( Constants.PRIVATE_PACKAGE, sb.toString() );
     }
 
-    private void appendProperty(String key, String value, Properties p) {
-        String list = p.getProperty(key);
 
-        if (list == null) {
+    private void appendProperty( String key, String value, Properties p )
+    {
+        String list = p.getProperty( key );
+
+        if ( list == null )
+        {
             list = value;
-        } else {
+        }
+        else
+        {
             list = list + "," + value;
         }
 
-        p.setProperty(key, list);
+        p.setProperty( key, list );
     }
 
-    private List<String> addLibs(IBldBundle bundle, String dest, Properties spec)
-            throws IOException {
+
+    private List<String> addLibs( IBldBundle bundle, String dest, Properties spec ) throws IOException
+    {
         // final String cleanVersion =
         // Builder.cleanupVersion(bundle.getVersion());
         final String name = bundle.getSymbolicName();
@@ -488,186 +564,213 @@
         ArrayList<String> srcPkgs = new ArrayList<String>();
         Map<String, Map<String, String>> libs = bundle.getLibs();
 
-        if (!bundle.getDownloadContents().isEmpty()) {
+        if ( !bundle.getDownloadContents().isEmpty() )
+        {
             // implicitly add dljar
-            File fdest = new File(dest);
-            String dlname = fdest.getName().replaceFirst("\\.jar$", "-dl.jar");
+            File fdest = new File( dest );
+            String dlname = fdest.getName().replaceFirst( "\\.jar$", "-dl.jar" );
 
             HashMap<String, String> attr = new HashMap<String, String>();
-            attr.put(BldAttr.KIND_ATTRIBUTE, "codebase");
-            attr.put(BldAttr.PUBLISH_ATTRIBUTE, dlname);
+            attr.put( BldAttr.KIND_ATTRIBUTE, "codebase" );
+            attr.put( BldAttr.PUBLISH_ATTRIBUTE, dlname );
 
             HashMap<String, Map<String, String>> lib2 = new HashMap<String, Map<String, String>>();
-            lib2.putAll(libs);
-            lib2.put(dlname, attr);
+            lib2.putAll( libs );
+            lib2.put( dlname, attr );
             libs = lib2;
         }
 
         StringBuilder items = new StringBuilder();
 
-        for (String jarpath : libs.keySet()) {
-            Map<String, String> attr = libs.get(jarpath);
-            String kind = attr.get(BldAttr.KIND_ATTRIBUTE);
-            String publish = attr.get(BldAttr.PUBLISH_ATTRIBUTE);
+        for ( String jarpath : libs.keySet() )
+        {
+            Map<String, String> attr = libs.get( jarpath );
+            String kind = attr.get( BldAttr.KIND_ATTRIBUTE );
+            String publish = attr.get( BldAttr.PUBLISH_ATTRIBUTE );
 
             // first find the lib ..
-            String path = attr.get(BldAttr.PATH_ATTRIBUTE);
-            if (path == null)
+            String path = attr.get( BldAttr.PATH_ATTRIBUTE );
+            if ( path == null )
                 path = jarpath;
 
-            File fsPath = bundle.resolve(path);
+            File fsPath = bundle.resolve( path );
 
-            if (!fsPath.exists()) {
+            if ( !fsPath.exists() )
+            {
                 // try destDir
-                File destDir = new File(dest).getParentFile();
-                File file = new File(destDir, fsPath.getName());
+                File destDir = new File( dest ).getParentFile();
+                File file = new File( destDir, fsPath.getName() );
 
-                if (!file.exists()) {
+                if ( !file.exists() )
+                {
                     // try searching classpath
-                    file = findInClasspathDir(fsPath.getName());
+                    file = findInClasspathDir( fsPath.getName() );
                 }
 
-                if (file != null && file.exists())
+                if ( file != null && file.exists() )
                     fsPath = file;
             }
 
-            if (!fsPath.exists()) {
+            if ( !fsPath.exists() )
+            {
                 // XXX: find external bundle using name and version range?
                 // For now just let BND fail when it can't find resource.
             }
 
-            appendProperty(Constants.INCLUDE_RESOURCE, jarpath + "=" + fsPath, spec);
+            appendProperty( Constants.INCLUDE_RESOURCE, jarpath + "=" + fsPath, spec );
 
-            if ("classpath".equals(kind)) {
-                String bcp = spec.getProperty(Constants.BUNDLE_CLASSPATH);
-                if (bcp == null || bcp.length() == 0)
-                    spec.setProperty(Constants.BUNDLE_CLASSPATH, ".");
-                appendProperty(Constants.BUNDLE_CLASSPATH, jarpath, spec);
+            if ( "classpath".equals( kind ) )
+            {
+                String bcp = spec.getProperty( Constants.BUNDLE_CLASSPATH );
+                if ( bcp == null || bcp.length() == 0 )
+                    spec.setProperty( Constants.BUNDLE_CLASSPATH, "." );
+                appendProperty( Constants.BUNDLE_CLASSPATH, jarpath, spec );
             }
 
-            if (publish != null) {
-                String pubtype = attr.get(BldAttr.PUBTYPE_ATTRIBUTE);
-                if (pubtype == null)
+            if ( publish != null )
+            {
+                String pubtype = attr.get( BldAttr.PUBTYPE_ATTRIBUTE );
+                if ( pubtype == null )
                     pubtype = defaultPubtype;
 
-                if ("codebase".equals(kind)) {
-                    String codebase = format(codebaseFormat, publish, name, pubtype);
-                    String zone = attr.get(BldAttr.ZONE_ATTRIBUTE);
-                    if (zone != null)
+                if ( "codebase".equals( kind ) )
+                {
+                    String codebase = format( codebaseFormat, publish, name, pubtype );
+                    String zone = attr.get( BldAttr.ZONE_ATTRIBUTE );
+                    if ( zone != null )
                         codebase += "&zone=" + zone;
-                    appendProperty("RMI-Codebase", codebase, spec);
+                    appendProperty( "RMI-Codebase", codebase, spec );
                 }
 
                 // add item to publish xml
-                items.append(format("<item name=\"%s\" path=\"%s\">\n", publish, jarpath));
-                items.append(format("<attribute name=\"type\" value=\"%s\"/>\n", pubtype));
-                items.append("</item>\n");
+                items.append( format( "<item name=\"%s\" path=\"%s\">\n", publish, jarpath ) );
+                items.append( format( "<attribute name=\"type\" value=\"%s\"/>\n", pubtype ) );
+                items.append( "</item>\n" );
             }
         }
 
-        if (items.length() > 0) {
-            File publishFile = new File(dest.replaceFirst("\\.jar$", "-publish.xml"));
+        if ( items.length() > 0 )
+        {
+            File publishFile = new File( dest.replaceFirst( "\\.jar$", "-publish.xml" ) );
             publishFile.deleteOnExit();
-            PrintWriter writer = new PrintWriter(new FileWriter(publishFile));
+            PrintWriter writer = new PrintWriter( new FileWriter( publishFile ) );
 
-            writer.println("<publish>");
-            writer.println(format("<attribute name=\"bundle.symbolic.name\" value=\"%s\"/>", name));
-            writer.print(items.toString());
-            writer.println("</publish>");
+            writer.println( "<publish>" );
+            writer.println( format( "<attribute name=\"bundle.symbolic.name\" value=\"%s\"/>", name ) );
+            writer.print( items.toString() );
+            writer.println( "</publish>" );
             writer.close();
 
-            appendProperty(Constants.INCLUDE_RESOURCE, "publish.xml=" + publishFile, spec);
+            appendProperty( Constants.INCLUDE_RESOURCE, "publish.xml=" + publishFile, spec );
         }
 
         return srcPkgs;
     }
 
-    private String addResources(IBldBundle bundle, Properties spec) {
+
+    private String addResources( IBldBundle bundle, Properties spec )
+    {
         Map<String, String> resources = bundle.getResources();
         StringBuilder composites = new StringBuilder();
 
-        for (String composite : bundle.getComposites()) {
-            File path = bundle.resolve(composite);
+        for ( String composite : bundle.getComposites() )
+        {
+            File path = bundle.resolve( composite );
             String name = path.getName();
 
             String bPath = COMPONENT_DIR + "/" + name;
-            resources.put(bPath, path.getPath());
+            resources.put( bPath, path.getPath() );
 
-            if (composites.length() > 0)
-                composites.append(",");
-            composites.append(bPath);
+            if ( composites.length() > 0 )
+                composites.append( "," );
+            composites.append( bPath );
         }
 
         StringBuilder sb = new StringBuilder();
 
-        for (String bPath : resources.keySet()) {
-            if (bPath.startsWith("@")) { // Bnd in-line jar
-                if (sb.length() > 0)
-                    sb.append(",");
-                sb.append('@');
-                sb.append(bundle.resolve(bPath.substring(1)));
+        for ( String bPath : resources.keySet() )
+        {
+            if ( bPath.startsWith( "@" ) )
+            { // Bnd in-line jar
+                if ( sb.length() > 0 )
+                    sb.append( "," );
+                sb.append( '@' );
+                sb.append( bundle.resolve( bPath.substring( 1 ) ) );
                 continue;
             }
 
-            String fsPath = resources.get(bPath);
-            if ("".equals(fsPath))
+            String fsPath = resources.get( bPath );
+            if ( "".equals( fsPath ) )
                 fsPath = bPath;
 
-            File resolved = bundle.resolve(fsPath);
+            File resolved = bundle.resolve( fsPath );
 
             // fsPath may contain Bnd variable, making path appear to not exist
 
-            if (!resolved.exists()) {
+            if ( !resolved.exists() )
+            {
                 // Bnd already looks for classpath jars
-                File found = findInClasspathDir(fsPath);
-                if (found != null) {
+                File found = findInClasspathDir( fsPath );
+                if ( found != null )
+                {
                     fsPath = found.getPath();
-                } else {
+                }
+                else
+                {
                     fsPath = resolved.getAbsolutePath();
                 }
-            } else {
+            }
+            else
+            {
                 fsPath = resolved.getAbsolutePath();
             }
 
-            if (sb.length() > 0)
-                sb.append(",");
-            sb.append(bPath);
-            sb.append('=');
-            sb.append(fsPath);
+            if ( sb.length() > 0 )
+                sb.append( "," );
+            sb.append( bPath );
+            sb.append( '=' );
+            sb.append( fsPath );
         }
 
-        if (sb.length() > 0)
-            spec.setProperty(Constants.INCLUDE_RESOURCE, sb.toString());
+        if ( sb.length() > 0 )
+            spec.setProperty( Constants.INCLUDE_RESOURCE, sb.toString() );
 
         return composites.toString();
     }
 
-    private List<IPackageImport> getImports(IBldBundle bundle) {
+
+    private List<IPackageImport> getImports( IBldBundle bundle )
+    {
         List<IPackageImport> imports = bundle.getImports();
         Set<String> pkgs = new HashSet<String>();
 
-        for (IPackageImport pi : imports) {
-            pkgs.add(pi.getPackageName());
+        for ( IPackageImport pi : imports )
+        {
+            pkgs.add( pi.getPackageName() );
         }
 
         // add component activator imports
-        if (!bundle.getComposites().isEmpty()) {
-            for (String pkg : BundleBuilder.COMPONENT_ACTIVATOR_DEPS) {
-                if (pkgs.contains(pkg))
+        if ( !bundle.getComposites().isEmpty() )
+        {
+            for ( String pkg : BundleBuilder.COMPONENT_ACTIVATOR_DEPS )
+            {
+                if ( pkgs.contains( pkg ) )
                     continue;
                 PackageImport pi = new PackageImport();
-                pi.setPackageName(pkg);
-                String versions = project.getDefaultPackageVersion(pkg);
-                if (versions != null)
-                    pi.setVersions(VersionRange.parseVersionRange(versions));
-                imports.add(pi);
+                pi.setPackageName( pkg );
+                String versions = project.getDefaultPackageVersion( pkg );
+                if ( versions != null )
+                    pi.setVersions( VersionRange.parseVersionRange( versions ) );
+                imports.add( pi );
             }
         }
 
         return imports;
     }
 
-    private void addRequirements(IBldBundle bundle, Properties spec) {
+
+    private void addRequirements( IBldBundle bundle, Properties spec )
+    {
         StringBuilder sb = new StringBuilder();
 
         // option;addMissingImports=true
@@ -680,115 +783,138 @@
         // avoids warnings like:
         // "Importing packages that are never referred to by any class on the Bundle-ClassPath"
 
-        if (omitUnusedImports && !addMissingImports) {
-            warnings.add("omitUnusedImports ignored as addMissingImports=false.");
+        if ( omitUnusedImports && !addMissingImports )
+        {
+            warnings.add( "omitUnusedImports ignored as addMissingImports=false." );
             omitUnusedImports = false;
         }
 
-        List<IPackageImport> imports = getImports(bundle);
+        List<IPackageImport> imports = getImports( bundle );
 
-        sb.setLength(0);
+        sb.setLength( 0 );
 
         // allow existing header;Package-Import to specify ignored packages
-        sb.append(spec.getProperty(Constants.IMPORT_PACKAGE, ""));
+        sb.append( spec.getProperty( Constants.IMPORT_PACKAGE, "" ) );
 
-        for (IPackageImport pi : imports) {
-            switch (pi.getOSGiImport()) {
-            case AUTO:
-                if (omitUnusedImports)
-                    continue; // added by Import-Package: * and fixed by
-                              // augmentImports()
-                break;
-            case NEVER:
-                if (pi.isDependency())
-                    continue; // resolve=compile
-                break;
-            case ALWAYS:
-                // Bnd will probably whinge that this import is not used.
-                // we omit it here and replace it in augmentImports,
-                // but only if addMissingImports is true;
-                // otherwise, if the import is used, Bnd will fail.
-                if (addMissingImports)
-                    continue;
-                break;
+        for ( IPackageImport pi : imports )
+        {
+            switch ( pi.getOSGiImport() )
+            {
+                case AUTO:
+                    if ( omitUnusedImports )
+                        continue; // added by Import-Package: * and fixed by
+                    // augmentImports()
+                    break;
+                case NEVER:
+                    if ( pi.isDependency() )
+                        continue; // resolve=compile
+                    break;
+                case ALWAYS:
+                    // Bnd will probably whinge that this import is not used.
+                    // we omit it here and replace it in augmentImports,
+                    // but only if addMissingImports is true;
+                    // otherwise, if the import is used, Bnd will fail.
+                    if ( addMissingImports )
+                        continue;
+                    break;
             }
 
-            if (sb.length() > 0)
-                sb.append(",");
+            if ( sb.length() > 0 )
+                sb.append( "," );
 
-            if (pi.getOSGiImport().equals(IPackageImport.OSGiImport.NEVER)) {
-                sb.append("!");
-                sb.append(pi.getPackageName());
-            } else {
-                sb.append(pi.getPackageName());
-                addVersions(pi.getVersions(), sb);
+            if ( pi.getOSGiImport().equals( IPackageImport.OSGiImport.NEVER ) )
+            {
+                sb.append( "!" );
+                sb.append( pi.getPackageName() );
+            }
+            else
+            {
+                sb.append( pi.getPackageName() );
+                addVersions( pi.getVersions(), sb );
 
-                if (pi.isOptional()) {
-                    sb.append(";resolution:=optional");
+                if ( pi.isOptional() )
+                {
+                    sb.append( ";resolution:=optional" );
                 }
             }
         }
 
-        if (addMissingImports) {
-            if (sb.length() > 0)
-                sb.append(",");
-            sb.append("*");
+        if ( addMissingImports )
+        {
+            if ( sb.length() > 0 )
+                sb.append( "," );
+            sb.append( "*" );
         }
 
-        spec.setProperty(Constants.IMPORT_PACKAGE, sb.toString());
+        spec.setProperty( Constants.IMPORT_PACKAGE, sb.toString() );
 
-        sb.setLength(0);
-        for (IRequiredBundle rb : bundle.getRequires()) {
-            if (sb.length() > 0)
-                sb.append(",");
-            sb.append(rb.getSymbolicName());
-            addVersions(rb.getVersions(), sb);
+        sb.setLength( 0 );
+        for ( IRequiredBundle rb : bundle.getRequires() )
+        {
+            if ( sb.length() > 0 )
+                sb.append( "," );
+            sb.append( rb.getSymbolicName() );
+            addVersions( rb.getVersions(), sb );
         }
 
-        if (sb.length() > 0) {
-            spec.setProperty(Constants.REQUIRE_BUNDLE, sb.toString());
+        if ( sb.length() > 0 )
+        {
+            spec.setProperty( Constants.REQUIRE_BUNDLE, sb.toString() );
         }
     }
 
-    private List<String> addExports(IBldBundle bundle, Properties spec) {
+
+    private List<String> addExports( IBldBundle bundle, Properties spec )
+    {
         List<IPackageExport> exports = bundle.getExports();
         ArrayList<String> list = new ArrayList<String>();
         StringBuilder sb = new StringBuilder();
 
-        for (IPackageExport export : exports) {
-            if (sb.length() > 0)
-                sb.append(",");
-            sb.append(export.getPackageName());
-            if (!export.getVersion().equals(Version.emptyVersion)) {
-                sb.append(";version=\"");
-                sb.append(export.getVersion());
-                sb.append("\"");
+        for ( IPackageExport export : exports )
+        {
+            if ( sb.length() > 0 )
+                sb.append( "," );
+            sb.append( export.getPackageName() );
+            if ( !export.getVersion().equals( Version.emptyVersion ) )
+            {
+                sb.append( ";version=\"" );
+                sb.append( export.getVersion() );
+                sb.append( "\"" );
             }
-            list.add(export.getPackageName());
+            list.add( export.getPackageName() );
         }
 
-        if (sb.length() > 0) {
+        if ( sb.length() > 0 )
+        {
             // EXPORT_CONTENTS just sets the Export-Package manifest header;
             // it doesn't add contents like EXPORT_PACKAGE does.
-            spec.setProperty(Constants.EXPORT_CONTENTS, sb.toString());
+            spec.setProperty( Constants.EXPORT_CONTENTS, sb.toString() );
         }
 
         return list;
     }
 
-    private void addVersions(VersionRange range, StringBuilder sb) {
-        if (!range.equals(VersionRange.ANY_VERSION)) {
-            sb.append(";version=\"");
-            sb.append(range);
-            sb.append("\"");
+
+    private void addVersions( VersionRange range, StringBuilder sb )
+    {
+        if ( !range.equals( VersionRange.ANY_VERSION ) )
+        {
+            sb.append( ";version=\"" );
+            sb.append( range );
+            sb.append( "\"" );
         }
     }
 
-    private File findInClasspathDir(String file) {
-        for (File cp : classpath) {
-            if (cp.isDirectory()) {
-                File path = new File(cp, file);
-                if (path.exists()) {
+
+    private File findInClasspathDir( String file )
+    {
+        for ( File cp : classpath )
+        {
+            if ( cp.isDirectory() )
+            {
+                File path = new File( cp, file );
+                if ( path.exists() )
+                {
                     return path;
                 }
             }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/config/BldAttr.java b/sigil/common/core/src/org/apache/felix/sigil/config/BldAttr.java
index b104d8a..1a6da37 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/config/BldAttr.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/config/BldAttr.java
@@ -19,32 +19,34 @@
 
 package org.apache.felix.sigil.config;
 
-public class BldAttr {
-	// Sigil attributes
-	
-	public static final String KIND_ATTRIBUTE = "kind";
-	
-	public static final String RESOLVE_ATTRIBUTE = "resolve";
-	public static final String RESOLVE_AUTO = "auto";
-	public static final String RESOLVE_COMPILE = "compile";
-	public static final String RESOLVE_RUNTIME = "runtime";
-	public static final String RESOLVE_IGNORE = "ignore";
-	
-	public static final String PUBLISH_ATTRIBUTE = "publish";
-	public static final String PUBTYPE_ATTRIBUTE = "type";
-	public static final String PATH_ATTRIBUTE = "path";
-	public static final Object ZONE_ATTRIBUTE = "zone";
-	
-	// Sigil options
-	
-	public static final String OPTION_ADD_IMPORTS = "addMissingImports";
-	public static final String OPTION_OMIT_IMPORTS = "omitUnusedImports";
-	
-	// OSGi attributes
-	
-	public static final String RESOLUTION_ATTRIBUTE = "resolution";
-	public static final String RESOLUTION_OPTIONAL = "optional";
-	
-	public static final String VERSION_ATTRIBUTE = "version";
+
+public class BldAttr
+{
+    // Sigil attributes
+
+    public static final String KIND_ATTRIBUTE = "kind";
+
+    public static final String RESOLVE_ATTRIBUTE = "resolve";
+    public static final String RESOLVE_AUTO = "auto";
+    public static final String RESOLVE_COMPILE = "compile";
+    public static final String RESOLVE_RUNTIME = "runtime";
+    public static final String RESOLVE_IGNORE = "ignore";
+
+    public static final String PUBLISH_ATTRIBUTE = "publish";
+    public static final String PUBTYPE_ATTRIBUTE = "type";
+    public static final String PATH_ATTRIBUTE = "path";
+    public static final Object ZONE_ATTRIBUTE = "zone";
+
+    // Sigil options
+
+    public static final String OPTION_ADD_IMPORTS = "addMissingImports";
+    public static final String OPTION_OMIT_IMPORTS = "omitUnusedImports";
+
+    // OSGi attributes
+
+    public static final String RESOLUTION_ATTRIBUTE = "resolution";
+    public static final String RESOLUTION_OPTIONAL = "optional";
+
+    public static final String VERSION_ATTRIBUTE = "version";
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/config/BldConfig.java b/sigil/common/core/src/org/apache/felix/sigil/config/BldConfig.java
index caed8e1..f51bdc4 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/config/BldConfig.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/config/BldConfig.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.config;
 
+
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -31,415 +32,535 @@
 
 import org.apache.felix.sigil.core.util.QuoteUtil;
 
-public class BldConfig {
-	
-	// control properties
-	public static final String C_BUNDLES = "-bundles";
-	public static final String C_REPOSITORIES = "-repositories";
 
-	// string properties
-	public static final String S_ACTIVATOR = "-activator";
-	public static final String S_DEFAULTS = "-defaults";
-	public static final String S_ID = "id";
-	public static final String S_SYM_NAME = "name";
-	public static final String S_VERSION = "version";
-	public static final String[] STRING_KEYS = { S_ACTIVATOR, S_DEFAULTS, S_ID, S_SYM_NAME, S_VERSION };
+public class BldConfig
+{
 
-	// list properties
-	public static final String L_COMPOSITES = "-composites";
-	public static final String L_CONTENTS = "-contents";
-	public static final String L_DL_CONTENTS = "-downloads";
-	public static final String L_SRC_CONTENTS = "-sourcedirs";
-	public static final String L_RESOURCES = "-resources";
-	public static final String[] LIST_KEYS = {
-		L_COMPOSITES, L_CONTENTS, L_DL_CONTENTS, L_SRC_CONTENTS, L_RESOURCES };
+    // control properties
+    public static final String C_BUNDLES = "-bundles";
+    public static final String C_REPOSITORIES = "-repositories";
 
-	// map properties
-	public static final String M_EXPORTS = "-exports";
-	public static final String M_IMPORTS = "-imports";
-	public static final String M_REQUIRES = "-requires";
-	public static final String M_FRAGMENT = "-fragment";
-	public static final String M_LIBS = "-libs";
-	public static final String[] MAP_KEYS = { M_EXPORTS, M_IMPORTS, M_REQUIRES, M_FRAGMENT, M_LIBS };
-	
-	// property properties
-	public static final String P_HEADER = "header";
-	public static final String P_OPTION = "option";
-	public static final String P_PACKAGE_VERSION = "package";
-	public static final String P_BUNDLE_VERSION = "bundle";
-	public static final String[] PROP_KEYS = { P_HEADER, P_OPTION, P_PACKAGE_VERSION, P_BUNDLE_VERSION };
+    // string properties
+    public static final String S_ACTIVATOR = "-activator";
+    public static final String S_DEFAULTS = "-defaults";
+    public static final String S_ID = "id";
+    public static final String S_SYM_NAME = "name";
+    public static final String S_VERSION = "version";
+    public static final String[] STRING_KEYS =
+        { S_ACTIVATOR, S_DEFAULTS, S_ID, S_SYM_NAME, S_VERSION };
 
-	// private constants
-	private static final String LIST_REGEX = ",\\s*";
-	private static final String MAPATTR_REGEX = ";\\s*";
-	private static final String MAPATTR_SEP = ";";
-	private static final String SUBKEY_SEP = ";";
+    // list properties
+    public static final String L_COMPOSITES = "-composites";
+    public static final String L_CONTENTS = "-contents";
+    public static final String L_DL_CONTENTS = "-downloads";
+    public static final String L_SRC_CONTENTS = "-sourcedirs";
+    public static final String L_RESOURCES = "-resources";
+    public static final String[] LIST_KEYS =
+        { L_COMPOSITES, L_CONTENTS, L_DL_CONTENTS, L_SRC_CONTENTS, L_RESOURCES };
 
-	// configuration is stored in typed maps
-	private Map<String, String> string = new TreeMap<String, String>();
-	private Map<String, List<String>> list = new TreeMap<String, List<String>>();
-	private Map<String, Map<String, Map<String, String>>> map = new TreeMap<String, Map<String,Map<String,String>>>();
-	private Map<String, BldConfig> config = new TreeMap<String, BldConfig>();
-	private Map<String, Properties> property = new TreeMap<String, Properties>();
-	
-	// default config - not modified or saved
-	private BldConfig dflt;
-	
-	private Properties unknown = new Properties();
-	private String comment = "";
-	
-	public BldConfig() {
-	}
-		
-	public BldConfig(Properties p) throws IOException {
-		merge(p);
-	}
-	
-	public void setDefault(BldConfig dflt) {
-		this.dflt = dflt;
-	}
+    // map properties
+    public static final String M_EXPORTS = "-exports";
+    public static final String M_IMPORTS = "-imports";
+    public static final String M_REQUIRES = "-requires";
+    public static final String M_FRAGMENT = "-fragment";
+    public static final String M_LIBS = "-libs";
+    public static final String[] MAP_KEYS =
+        { M_EXPORTS, M_IMPORTS, M_REQUIRES, M_FRAGMENT, M_LIBS };
 
-	public void setComment(String comment) {
-		this.comment = comment;
-	}
-	
-	public Properties getUnknown() {
-		return unknown;
-	}
+    // property properties
+    public static final String P_HEADER = "header";
+    public static final String P_OPTION = "option";
+    public static final String P_PACKAGE_VERSION = "package";
+    public static final String P_BUNDLE_VERSION = "bundle";
+    public static final String[] PROP_KEYS =
+        { P_HEADER, P_OPTION, P_PACKAGE_VERSION, P_BUNDLE_VERSION };
 
-	public String getString(String id, String key) {
-		if (id != null && config.containsKey(id)) {
-			String value = config.get(id).getString(null, key);
-			if (value != null)
-				return value;
-		}
-		return string.containsKey(key) ? string.get(key) : (dflt != null ? dflt.getString(id, key) : null);
-	}
+    // private constants
+    private static final String LIST_REGEX = ",\\s*";
+    private static final String MAPATTR_REGEX = ";\\s*";
+    private static final String MAPATTR_SEP = ";";
+    private static final String SUBKEY_SEP = ";";
 
-	public List<String> getList(String id, String key) {
-		if (id != null && config.containsKey(id)) {
-			List<String> value = config.get(id).getList(null, key);
-			if (value != null)
-				return value;
-		}
-		return list.containsKey(key) ? list.get(key) : (dflt != null ? dflt.getList(id, key) : Collections.<String>emptyList());
-	}
+    // configuration is stored in typed maps
+    private Map<String, String> string = new TreeMap<String, String>();
+    private Map<String, List<String>> list = new TreeMap<String, List<String>>();
+    private Map<String, Map<String, Map<String, String>>> map = new TreeMap<String, Map<String, Map<String, String>>>();
+    private Map<String, BldConfig> config = new TreeMap<String, BldConfig>();
+    private Map<String, Properties> property = new TreeMap<String, Properties>();
 
-	public Map<String, Map<String,String>> getMap(String id, String key) {
-		if (id != null && config.containsKey(id)) {
-			Map<String, Map<String,String>> value = config.get(id).getMap(null, key);
-			if (value != null)
-				return value;
-		}
-		return map.containsKey(key) ? map.get(key)
-				: (dflt != null ? dflt.getMap(id, key) : Collections.<String, Map<String,String>>emptyMap());
-	}
-	
-	public void setString(String id, String key, String value) {
-		if (!value.equals(getString(id, key))) {
-			if (id != null) {
-    			if (!config.containsKey(id))
-    				config.put(id, new BldConfig());
-    			config.get(id).setString(null, key, value);
-			} else {
-				String dval = (dflt == null ? dflt.getString(null, key) : null);
-				if (value.equals("") && (dval == null || dval.equals(""))) {
-    		        string.remove(key);	
-    			} else {
-            		string.put(key, value);
-    			}
-			}
-		}
-	}
+    // default config - not modified or saved
+    private BldConfig dflt;
 
-	public void setList(String id, String key, List<String> value) {
-		if (!value.equals(getList(id, key))) {
-			if (id != null) {
-    			if (!config.containsKey(id))
-    				config.put(id, new BldConfig());
-    			config.get(id).setList(null, key, value);
-			} else if (value.isEmpty() && (dflt == null || dflt.getList(null, key).isEmpty())) {
-		        list.remove(key);	
-			} else {
-        		list.put(key, value);
-			}
-		}
-	}
+    private Properties unknown = new Properties();
+    private String comment = "";
 
-	public void setMap(String id, String key, Map<String, Map<String,String>> value) {
-		if (!value.equals(getMap(id, key))) {
-			if (id != null) {
-    			if (!config.containsKey(id))
-    				config.put(id, new BldConfig());
-    			config.get(id).setMap(null, key, value);
-			} else if (value.isEmpty() && (dflt == null || dflt.getMap(null, key).isEmpty())) {
-		        map.remove(key);	
-			} else {
-        		map.put(key, value);
-			}
-		}
-	}
-	
-	public Properties getProps(String id, String key) {
-    	// merge main and sub properties
-		Properties props = new Properties();
-		
-		if (dflt != null)
-    		props.putAll(dflt.getProps(id, key));
-		
-		if (property.containsKey(key))
-			props.putAll(property.get(key));
 
-		if (id != null && config.containsKey(id)) {
-			Properties p2 = config.get(id).getProps(null, key);
-			if (p2 != null)
-				props.putAll(p2);
-		}
+    public BldConfig()
+    {
+    }
 
-		return props;
-	}
-	
-	// only sets one property at a time
-	public void setProp(String id, String key, String k2, String v2) {
-		if (v2 == null)
-			return;
-		Properties props = getProps(id, key);
-		if (!v2.equals(props.getProperty(key))) {
-			if (id != null) {
-    			if (!config.containsKey(id))
-    				config.put(id, new BldConfig());
-    			config.get(id).setProp(null, key, k2, v2);
-			} else {
-        		if (property.containsKey(key)) {
-        			property.get(key).put(k2, v2);
-        		} else {
-            		Properties value = new Properties();
-            		value.put(k2, v2);
-            		property.put(key, value);
-        		}
-			}
-		}
-	}
 
-	/**
-	 * write config in Property file format.
-	 * This allows us to make it prettier than Properties.store().
-	 */
-	public void write(final PrintWriter out) {
-		out.println(comment);
-		
-		// Note: don't add date stamp, or file will differ each time it's saved.
-		out.println("# sigil project file, saved by plugin.\n");
-		
-		dump("", new Properties() {
-			private static final long serialVersionUID = 1L; //appease eclipse
-			@Override
-			public Object put(Object key, Object value) {
-				if (value instanceof String) {
-					out.println(key + ": " + value);
-					out.println("");
-				} else if (value instanceof List) {
-					out.println(key + ": \\");
-					for (Object k : (List<?>) value) {
-						out.println("\t" + k + ", \\");
-					}
-					out.println("");
-				}
-				else if (value instanceof Map) {
-					out.println(key + ": \\");
-					StringBuilder b = new StringBuilder();
-					for (Map.Entry<?, ?> e : ((Map<?,?>) value).entrySet()) {
-						b.append("\t");
-						b.append(e.getKey());
-						Map<?, ?> v = (Map<?, ?>) e.getValue();
-						if (!v.isEmpty()) {
-							for (Map.Entry<?, ?> e2 : v.entrySet()) {
-    							b.append(MAPATTR_SEP);
-								b.append(e2.getKey());
-								b.append("=");
-								String v2 = e2.getValue().toString();
-								if (v2.contains(",")) {
-									b.append("\"");
-									b.append(v2);
-									b.append("\"");
-								}
-								else {
-									b.append(v2);
-								}
-							}
-						}
-						b.append (", \\\n"); 
-					}
-					out.println(b.toString());
-				}
-				return null;
-			}
-		});
-		out.println("# end");
-	}
+    public BldConfig( Properties p ) throws IOException
+    {
+        merge( p );
+    }
 
-	/**
-	 * dump config in pseudo Properties format.
-	 * Note: some values are not Strings (they're List<String>).
-	 */
-	private void dump(String prefix, Properties p) {
-		for (String key : string.keySet()) {
-			p.put(prefix + key, string.get(key));
-		}
-		
-		for (String key : list.keySet()) {
-			List<String> list2 = list.get(key);
-			p.put(prefix + key, list2);
-		}
 
-		for (String key : map.keySet()) {
-			Map<String, Map<String,String>> map2 = map.get(key);
-			p.put(prefix + key, map2);
-		}
+    public void setDefault( BldConfig dflt )
+    {
+        this.dflt = dflt;
+    }
 
-		for (String key : property.keySet()) {
-			Properties props = property.get(key);
-			for (Object k2 : props.keySet()) {
-				p.put(prefix + key + SUBKEY_SEP + k2, props.get(k2));
-			}
-		}
 
-		for (String key : config.keySet()) {
-			BldConfig config2 = config.get(key);
-			config2.dump(key + SUBKEY_SEP + prefix, p);
-		}
+    public void setComment( String comment )
+    {
+        this.comment = comment;
+    }
 
-		for (Object key : unknown.keySet()) {
-			String value = unknown.getProperty((String)key);
-			if (value.length() > 0)
-    			p.put(prefix + key, value);
-		}
-	}
 
-	/**
-	 * merges properties into current configuration.
-	 * @param p
-	 * @throws IOException 
-	 */
-	public void merge(Properties p) throws IOException {
-		if (p.isEmpty())
-			return;
-		
-		final List<String> strings = Arrays.asList(STRING_KEYS);
-		final List<String> lists = Arrays.asList(LIST_KEYS);
-		final List<String> maps = Arrays.asList(MAP_KEYS);
+    public Properties getUnknown()
+    {
+        return unknown;
+    }
 
-		List<String> bundleKeys = new ArrayList<String>();
-		List<String> repoKeys = new ArrayList<String>();
 
-		String bundles = p.getProperty(C_BUNDLES);
-		if (bundles != null) {
-			bundleKeys.addAll(Arrays.asList(bundles.split(LIST_REGEX)));
-			list.put(C_BUNDLES, bundleKeys);
-		}
+    public String getString( String id, String key )
+    {
+        if ( id != null && config.containsKey( id ) )
+        {
+            String value = config.get( id ).getString( null, key );
+            if ( value != null )
+                return value;
+        }
+        return string.containsKey( key ) ? string.get( key ) : ( dflt != null ? dflt.getString( id, key ) : null );
+    }
 
-		String repos = p.getProperty(C_REPOSITORIES);
-		if (repos != null) {
-			for ( String s : repos.split(LIST_REGEX) ) {
-				repoKeys.add(s.trim());
-			}
-			list.put(C_REPOSITORIES, repoKeys);
-		}
 
-		List<String> subKeys = new ArrayList<String>();
-		subKeys.addAll(Arrays.asList(PROP_KEYS));
-		subKeys.addAll(bundleKeys);
-		subKeys.addAll(repoKeys);
+    public List<String> getList( String id, String key )
+    {
+        if ( id != null && config.containsKey( id ) )
+        {
+            List<String> value = config.get( id ).getList( null, key );
+            if ( value != null )
+                return value;
+        }
+        return list.containsKey( key ) ? list.get( key ) : ( dflt != null ? dflt.getList( id, key ) : Collections
+            .<String> emptyList() );
+    }
 
-		Map<String, Properties> sub = new TreeMap<String, Properties>();
 
-		for (Object k : p.keySet()) {
-			String key = (String) k;
-			if (key.equals(C_BUNDLES) || key.equals(C_REPOSITORIES))
-				continue;
-			
-			String value = p.getProperty(key);
-			String[] keys = key.split(SUBKEY_SEP, 2);
+    public Map<String, Map<String, String>> getMap( String id, String key )
+    {
+        if ( id != null && config.containsKey( id ) )
+        {
+            Map<String, Map<String, String>> value = config.get( id ).getMap( null, key );
+            if ( value != null )
+                return value;
+        }
+        return map.containsKey( key ) ? map.get( key ) : ( dflt != null ? dflt.getMap( id, key ) : Collections
+            .<String, Map<String, String>> emptyMap() );
+    }
 
-			if (keys.length > 1) {
-				Properties p2 = sub.get(keys[0]);
-				if (p2 == null) {
-					p2 = new Properties();
-					sub.put(keys[0], p2);
-					if (!subKeys.contains(keys[0])) {
-						unknown.setProperty(keys[0] + SUBKEY_SEP, "");
-					}
-				}
-				p2.setProperty(keys[1], value);
-			} else if (strings.contains(key)) {
-				if (!string.containsKey(key))
-					string.put(key, value);
-			} else if (lists.contains(key)) {
-				if (!list.containsKey(key)) {
-					ArrayList<String> list2 = new ArrayList<String>();
-					for (String s : value.split(LIST_REGEX)) {
-						if ( s.trim().length() > 0 ) {
-							list2.add(s.trim());
-						}
-					}
-					if ( !list2.isEmpty() ) {
-						list.put(key, list2);
-					}
-				}
-			} else if (maps.contains(key)) {
-				if (!map.containsKey(key)) {
-					Map<String, Map<String,String>> map2 = new TreeMap<String, Map<String,String>>();
 
-					for (String subValue : QuoteUtil.split(value)) {
-						if (subValue.trim().length() > 0) {
-							String[] split = subValue.split(MAPATTR_REGEX);
-							Map<String,String> map3 = new TreeMap<String,String>();
-							for (int i = 1; i < split.length; ++i){
-								String[] keyVal = split[i].split(":?=", 2);
-								if (keyVal.length != 2) {
-								    throw new IOException("attribute missing '=':" + subValue);
-								}
-								map3.put(keyVal[0], keyVal[1]);
-							}
-							map2.put(split[0], map3);
-						}
-					}
+    public void setString( String id, String key, String value )
+    {
+        if ( !value.equals( getString( id, key ) ) )
+        {
+            if ( id != null )
+            {
+                if ( !config.containsKey( id ) )
+                    config.put( id, new BldConfig() );
+                config.get( id ).setString( null, key, value );
+            }
+            else
+            {
+                String dval = ( dflt == null ? dflt.getString( null, key ) : null );
+                if ( value.equals( "" ) && ( dval == null || dval.equals( "" ) ) )
+                {
+                    string.remove( key );
+                }
+                else
+                {
+                    string.put( key, value );
+                }
+            }
+        }
+    }
 
-					map.put(key, map2);
-				}
-			} else {
-				unknown.setProperty(key, value);
-			}
-		}
-		
-		for (String subKey : sub.keySet()) {
-			Properties props = sub.get(subKey);
-			if (!props.isEmpty()) {
-				if (bundleKeys.contains(subKey)) {
-					BldConfig config2 = new BldConfig(props);
-					Properties unkProps = config2.getUnknown();
-					
-					if (config2.map.containsKey(M_IMPORTS))
-						unkProps.setProperty(M_IMPORTS, "");
-						
-					if (config2.map.containsKey(M_REQUIRES))
-						unkProps.setProperty(M_REQUIRES, "");
-						
-					for (Object unk : unkProps.keySet()) {
-						unknown.setProperty(subKey + SUBKEY_SEP + unk, "");
-					}
-					config.put(subKey, config2);
-				} else {
-					property.put(subKey, props);
-				}
-			}
-		}
-	}
-	
-	@Override
-	public String toString() {
-		return "string: " + string + " list:" + list + " map: " + map + " prop: " + property + " config:" + config;
-	}
+
+    public void setList( String id, String key, List<String> value )
+    {
+        if ( !value.equals( getList( id, key ) ) )
+        {
+            if ( id != null )
+            {
+                if ( !config.containsKey( id ) )
+                    config.put( id, new BldConfig() );
+                config.get( id ).setList( null, key, value );
+            }
+            else if ( value.isEmpty() && ( dflt == null || dflt.getList( null, key ).isEmpty() ) )
+            {
+                list.remove( key );
+            }
+            else
+            {
+                list.put( key, value );
+            }
+        }
+    }
+
+
+    public void setMap( String id, String key, Map<String, Map<String, String>> value )
+    {
+        if ( !value.equals( getMap( id, key ) ) )
+        {
+            if ( id != null )
+            {
+                if ( !config.containsKey( id ) )
+                    config.put( id, new BldConfig() );
+                config.get( id ).setMap( null, key, value );
+            }
+            else if ( value.isEmpty() && ( dflt == null || dflt.getMap( null, key ).isEmpty() ) )
+            {
+                map.remove( key );
+            }
+            else
+            {
+                map.put( key, value );
+            }
+        }
+    }
+
+
+    public Properties getProps( String id, String key )
+    {
+        // merge main and sub properties
+        Properties props = new Properties();
+
+        if ( dflt != null )
+            props.putAll( dflt.getProps( id, key ) );
+
+        if ( property.containsKey( key ) )
+            props.putAll( property.get( key ) );
+
+        if ( id != null && config.containsKey( id ) )
+        {
+            Properties p2 = config.get( id ).getProps( null, key );
+            if ( p2 != null )
+                props.putAll( p2 );
+        }
+
+        return props;
+    }
+
+
+    // only sets one property at a time
+    public void setProp( String id, String key, String k2, String v2 )
+    {
+        if ( v2 == null )
+            return;
+        Properties props = getProps( id, key );
+        if ( !v2.equals( props.getProperty( key ) ) )
+        {
+            if ( id != null )
+            {
+                if ( !config.containsKey( id ) )
+                    config.put( id, new BldConfig() );
+                config.get( id ).setProp( null, key, k2, v2 );
+            }
+            else
+            {
+                if ( property.containsKey( key ) )
+                {
+                    property.get( key ).put( k2, v2 );
+                }
+                else
+                {
+                    Properties value = new Properties();
+                    value.put( k2, v2 );
+                    property.put( key, value );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * write config in Property file format.
+     * This allows us to make it prettier than Properties.store().
+     */
+    public void write( final PrintWriter out )
+    {
+        out.println( comment );
+
+        // Note: don't add date stamp, or file will differ each time it's saved.
+        out.println( "# sigil project file, saved by plugin.\n" );
+
+        dump( "", new Properties()
+        {
+            private static final long serialVersionUID = 1L; //appease eclipse
+
+
+            @Override
+            public Object put( Object key, Object value )
+            {
+                if ( value instanceof String )
+                {
+                    out.println( key + ": " + value );
+                    out.println( "" );
+                }
+                else if ( value instanceof List )
+                {
+                    out.println( key + ": \\" );
+                    for ( Object k : ( List<?> ) value )
+                    {
+                        out.println( "\t" + k + ", \\" );
+                    }
+                    out.println( "" );
+                }
+                else if ( value instanceof Map )
+                {
+                    out.println( key + ": \\" );
+                    StringBuilder b = new StringBuilder();
+                    for ( Map.Entry<?, ?> e : ( ( Map<?, ?> ) value ).entrySet() )
+                    {
+                        b.append( "\t" );
+                        b.append( e.getKey() );
+                        Map<?, ?> v = ( Map<?, ?> ) e.getValue();
+                        if ( !v.isEmpty() )
+                        {
+                            for ( Map.Entry<?, ?> e2 : v.entrySet() )
+                            {
+                                b.append( MAPATTR_SEP );
+                                b.append( e2.getKey() );
+                                b.append( "=" );
+                                String v2 = e2.getValue().toString();
+                                if ( v2.contains( "," ) )
+                                {
+                                    b.append( "\"" );
+                                    b.append( v2 );
+                                    b.append( "\"" );
+                                }
+                                else
+                                {
+                                    b.append( v2 );
+                                }
+                            }
+                        }
+                        b.append( ", \\\n" );
+                    }
+                    out.println( b.toString() );
+                }
+                return null;
+            }
+        } );
+        out.println( "# end" );
+    }
+
+
+    /**
+     * dump config in pseudo Properties format.
+     * Note: some values are not Strings (they're List<String>).
+     */
+    private void dump( String prefix, Properties p )
+    {
+        for ( String key : string.keySet() )
+        {
+            p.put( prefix + key, string.get( key ) );
+        }
+
+        for ( String key : list.keySet() )
+        {
+            List<String> list2 = list.get( key );
+            p.put( prefix + key, list2 );
+        }
+
+        for ( String key : map.keySet() )
+        {
+            Map<String, Map<String, String>> map2 = map.get( key );
+            p.put( prefix + key, map2 );
+        }
+
+        for ( String key : property.keySet() )
+        {
+            Properties props = property.get( key );
+            for ( Object k2 : props.keySet() )
+            {
+                p.put( prefix + key + SUBKEY_SEP + k2, props.get( k2 ) );
+            }
+        }
+
+        for ( String key : config.keySet() )
+        {
+            BldConfig config2 = config.get( key );
+            config2.dump( key + SUBKEY_SEP + prefix, p );
+        }
+
+        for ( Object key : unknown.keySet() )
+        {
+            String value = unknown.getProperty( ( String ) key );
+            if ( value.length() > 0 )
+                p.put( prefix + key, value );
+        }
+    }
+
+
+    /**
+     * merges properties into current configuration.
+     * @param p
+     * @throws IOException 
+     */
+    public void merge( Properties p ) throws IOException
+    {
+        if ( p.isEmpty() )
+            return;
+
+        final List<String> strings = Arrays.asList( STRING_KEYS );
+        final List<String> lists = Arrays.asList( LIST_KEYS );
+        final List<String> maps = Arrays.asList( MAP_KEYS );
+
+        List<String> bundleKeys = new ArrayList<String>();
+        List<String> repoKeys = new ArrayList<String>();
+
+        String bundles = p.getProperty( C_BUNDLES );
+        if ( bundles != null )
+        {
+            bundleKeys.addAll( Arrays.asList( bundles.split( LIST_REGEX ) ) );
+            list.put( C_BUNDLES, bundleKeys );
+        }
+
+        String repos = p.getProperty( C_REPOSITORIES );
+        if ( repos != null )
+        {
+            for ( String s : repos.split( LIST_REGEX ) )
+            {
+                repoKeys.add( s.trim() );
+            }
+            list.put( C_REPOSITORIES, repoKeys );
+        }
+
+        List<String> subKeys = new ArrayList<String>();
+        subKeys.addAll( Arrays.asList( PROP_KEYS ) );
+        subKeys.addAll( bundleKeys );
+        subKeys.addAll( repoKeys );
+
+        Map<String, Properties> sub = new TreeMap<String, Properties>();
+
+        for ( Object k : p.keySet() )
+        {
+            String key = ( String ) k;
+            if ( key.equals( C_BUNDLES ) || key.equals( C_REPOSITORIES ) )
+                continue;
+
+            String value = p.getProperty( key );
+            String[] keys = key.split( SUBKEY_SEP, 2 );
+
+            if ( keys.length > 1 )
+            {
+                Properties p2 = sub.get( keys[0] );
+                if ( p2 == null )
+                {
+                    p2 = new Properties();
+                    sub.put( keys[0], p2 );
+                    if ( !subKeys.contains( keys[0] ) )
+                    {
+                        unknown.setProperty( keys[0] + SUBKEY_SEP, "" );
+                    }
+                }
+                p2.setProperty( keys[1], value );
+            }
+            else if ( strings.contains( key ) )
+            {
+                if ( !string.containsKey( key ) )
+                    string.put( key, value );
+            }
+            else if ( lists.contains( key ) )
+            {
+                if ( !list.containsKey( key ) )
+                {
+                    ArrayList<String> list2 = new ArrayList<String>();
+                    for ( String s : value.split( LIST_REGEX ) )
+                    {
+                        if ( s.trim().length() > 0 )
+                        {
+                            list2.add( s.trim() );
+                        }
+                    }
+                    if ( !list2.isEmpty() )
+                    {
+                        list.put( key, list2 );
+                    }
+                }
+            }
+            else if ( maps.contains( key ) )
+            {
+                if ( !map.containsKey( key ) )
+                {
+                    Map<String, Map<String, String>> map2 = new TreeMap<String, Map<String, String>>();
+
+                    for ( String subValue : QuoteUtil.split( value ) )
+                    {
+                        if ( subValue.trim().length() > 0 )
+                        {
+                            String[] split = subValue.split( MAPATTR_REGEX );
+                            Map<String, String> map3 = new TreeMap<String, String>();
+                            for ( int i = 1; i < split.length; ++i )
+                            {
+                                String[] keyVal = split[i].split( ":?=", 2 );
+                                if ( keyVal.length != 2 )
+                                {
+                                    throw new IOException( "attribute missing '=':" + subValue );
+                                }
+                                map3.put( keyVal[0], keyVal[1] );
+                            }
+                            map2.put( split[0], map3 );
+                        }
+                    }
+
+                    map.put( key, map2 );
+                }
+            }
+            else
+            {
+                unknown.setProperty( key, value );
+            }
+        }
+
+        for ( String subKey : sub.keySet() )
+        {
+            Properties props = sub.get( subKey );
+            if ( !props.isEmpty() )
+            {
+                if ( bundleKeys.contains( subKey ) )
+                {
+                    BldConfig config2 = new BldConfig( props );
+                    Properties unkProps = config2.getUnknown();
+
+                    if ( config2.map.containsKey( M_IMPORTS ) )
+                        unkProps.setProperty( M_IMPORTS, "" );
+
+                    if ( config2.map.containsKey( M_REQUIRES ) )
+                        unkProps.setProperty( M_REQUIRES, "" );
+
+                    for ( Object unk : unkProps.keySet() )
+                    {
+                        unknown.setProperty( subKey + SUBKEY_SEP + unk, "" );
+                    }
+                    config.put( subKey, config2 );
+                }
+                else
+                {
+                    property.put( subKey, props );
+                }
+            }
+        }
+    }
+
+
+    @Override
+    public String toString()
+    {
+        return "string: " + string + " list:" + list + " map: " + map + " prop: " + property + " config:" + config;
+    }
 
 }
-
diff --git a/sigil/common/core/src/org/apache/felix/sigil/config/BldConverter.java b/sigil/common/core/src/org/apache/felix/sigil/config/BldConverter.java
index ae0efdb..3c64efe 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/config/BldConverter.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/config/BldConverter.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.config;
 
+
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -47,418 +48,486 @@
 
 import aQute.lib.osgi.Constants;
 
-public class BldConverter {
-	private static final String classpathFormat = "<classpathentry kind=\"%s\" path=\"%s\"/>";
-	private BldConfig config;
-	private Properties packageDefaults;
-	private TreeSet<String> packageWildDefaults;
 
-	public BldConverter(BldConfig config) {
-		this.config = config;
-	}
+public class BldConverter
+{
+    private static final String classpathFormat = "<classpathentry kind=\"%s\" path=\"%s\"/>";
+    private BldConfig config;
+    private Properties packageDefaults;
+    private TreeSet<String> packageWildDefaults;
 
-	/**
-	 * converts to an ISigilBundle.
-	 * @param id
-	 * @param bundle
-	 * @return
-	 */
-	public ISigilBundle getBundle(String id, IBldBundle bundle) {
 
-		ISigilBundle sigilBundle = new SigilBundle();
-		IBundleModelElement info = new BundleModelElement();
-		sigilBundle.setBundleInfo(info);
+    public BldConverter( BldConfig config )
+    {
+        this.config = config;
+    }
 
-		// exports
-		// FIXME: UI doesn't understand export wildcard packages
-		for (IPackageExport export : bundle.getExports()) {
-			IPackageExport clone = (IPackageExport) export.clone();
-			clone.setParent(null);
-			info.addExport(clone);
-		}
 
-		// imports
-		for (IPackageImport import1 : bundle.getImports()) {
-			IPackageImport clone = (IPackageImport) import1.clone();
-			clone.setParent(null);
-			info.addImport(clone);
-		}
+    /**
+     * converts to an ISigilBundle.
+     * @param id
+     * @param bundle
+     * @return
+     */
+    public ISigilBundle getBundle( String id, IBldBundle bundle )
+    {
 
-		// requires
-		for (IRequiredBundle require : bundle.getRequires()) {
-			IRequiredBundle clone = (IRequiredBundle) require.clone();
-			clone.setParent(null);
-			info.addRequiredBundle(clone);
-		}
+        ISigilBundle sigilBundle = new SigilBundle();
+        IBundleModelElement info = new BundleModelElement();
+        sigilBundle.setBundleInfo( info );
 
-		// fragment
-		IRequiredBundle fragment = bundle.getFragmentHost();
-		if (fragment != null) {
-			info.setFragmentHost(fragment);
-		}
-		
-		// contents
-		for (String pkg : bundle.getContents()) {
-			sigilBundle.addPackage(pkg);
-		}
-		
-		// downloads
-		for (String pkg : bundle.getDownloadContents()) {
-			sigilBundle.addDownloadPackage(pkg);
-		}
-		
-		// sources
-		for (String source : config.getList(null, BldConfig.L_SRC_CONTENTS) ) {
-			sigilBundle.addClasspathEntry(String.format(classpathFormat, "src", source));
-		}
+        // exports
+        // FIXME: UI doesn't understand export wildcard packages
+        for ( IPackageExport export : bundle.getExports() )
+        {
+            IPackageExport clone = ( IPackageExport ) export.clone();
+            clone.setParent( null );
+            info.addExport( clone );
+        }
 
-		// libs
-		Map<String, Map<String, String>> libs = bundle.getLibs();
-		
-		for (String path : libs.keySet()) {
-			Map<String, String> attr = libs.get(path);
-			String kind = attr.get(BldAttr.KIND_ATTRIBUTE);
-			String publish = attr.get(BldAttr.PUBLISH_ATTRIBUTE);
-			
-			if (publish != null) {
-        		// FIXME: UI doesn't understand publish=name
-				BldCore.error("Can't convert -libs publish=" + publish);
-				continue;	
-			}
-			
-			if ("classpath".equals(kind)) {
-    			sigilBundle.addClasspathEntry(String.format(classpathFormat, "lib", path));
-			} else {
-				BldCore.error("Can't convert -libs kind=" + kind);
-			}
-		}
+        // imports
+        for ( IPackageImport import1 : bundle.getImports() )
+        {
+            IPackageImport clone = ( IPackageImport ) import1.clone();
+            clone.setParent( null );
+            info.addImport( clone );
+        }
 
-		// resources
-		// FIXME: UI doesn't support -resources: path1=path2
-		Map<String, String> resources = bundle.getResources();
-		for (String resource : resources.keySet()) {
-			String fsPath = resources.get(resource);
-			if (!"".equals(fsPath)) {
-    			BldCore.error("FIXME: can't convert resource: " + resource + "=" + fsPath);
-			}
-			sigilBundle.addSourcePath(new Path(resource));
-		}
-		
-		////////////////////
-		// simple headers
+        // requires
+        for ( IRequiredBundle require : bundle.getRequires() )
+        {
+            IRequiredBundle clone = ( IRequiredBundle ) require.clone();
+            clone.setParent( null );
+            info.addRequiredBundle( clone );
+        }
 
-		info.setSymbolicName(bundle.getSymbolicName());
+        // fragment
+        IRequiredBundle fragment = bundle.getFragmentHost();
+        if ( fragment != null )
+        {
+            info.setFragmentHost( fragment );
+        }
 
-		info.setVersion(Version.parseVersion(bundle.getVersion()));
+        // contents
+        for ( String pkg : bundle.getContents() )
+        {
+            sigilBundle.addPackage( pkg );
+        }
 
-		String activator = bundle.getActivator();
-		if (activator != null)
-			info.setActivator(activator);
-		
-		Properties headers = config.getProps(id, BldConfig.P_HEADER);
-		String header;
+        // downloads
+        for ( String pkg : bundle.getDownloadContents() )
+        {
+            sigilBundle.addDownloadPackage( pkg );
+        }
 
-		header = headers.getProperty("CATEGORY");
-		if (header != null)
-			info.setCategory(header);
+        // sources
+        for ( String source : config.getList( null, BldConfig.L_SRC_CONTENTS ) )
+        {
+            sigilBundle.addClasspathEntry( String.format( classpathFormat, "src", source ) );
+        }
 
-		header = headers.getProperty(Constants.BUNDLE_CONTACTADDRESS);
-		if (header != null)
-			info.setContactAddress(header);
+        // libs
+        Map<String, Map<String, String>> libs = bundle.getLibs();
 
-		header = headers.getProperty(Constants.BUNDLE_COPYRIGHT);
-		if (header != null)
-			info.setCopyright(header);
+        for ( String path : libs.keySet() )
+        {
+            Map<String, String> attr = libs.get( path );
+            String kind = attr.get( BldAttr.KIND_ATTRIBUTE );
+            String publish = attr.get( BldAttr.PUBLISH_ATTRIBUTE );
 
-		header = headers.getProperty(Constants.BUNDLE_DESCRIPTION);
-		if (header != null)
-			info.setDescription(header);
+            if ( publish != null )
+            {
+                // FIXME: UI doesn't understand publish=name
+                BldCore.error( "Can't convert -libs publish=" + publish );
+                continue;
+            }
 
-		header = headers.getProperty(Constants.BUNDLE_VENDOR);
-		if (header != null)
-			info.setVendor(header);
+            if ( "classpath".equals( kind ) )
+            {
+                sigilBundle.addClasspathEntry( String.format( classpathFormat, "lib", path ) );
+            }
+            else
+            {
+                BldCore.error( "Can't convert -libs kind=" + kind );
+            }
+        }
 
-		header = headers.getProperty(Constants.BUNDLE_NAME);
-		if (header != null)
-			info.setName(header);
+        // resources
+        // FIXME: UI doesn't support -resources: path1=path2
+        Map<String, String> resources = bundle.getResources();
+        for ( String resource : resources.keySet() )
+        {
+            String fsPath = resources.get( resource );
+            if ( !"".equals( fsPath ) )
+            {
+                BldCore.error( "FIXME: can't convert resource: " + resource + "=" + fsPath );
+            }
+            sigilBundle.addSourcePath( new Path( resource ) );
+        }
 
-		header = headers.getProperty(Constants.BUNDLE_DOCURL);
-		if (header != null)
-			info.setDocURI(URI.create(header));
+        ////////////////////
+        // simple headers
 
-		header = headers.getProperty(Constants.BUNDLE_LICENSE);
-		if (header != null)
-			info.setDocURI(URI.create(header));
+        info.setSymbolicName( bundle.getSymbolicName() );
 
-		return sigilBundle;
-	}
+        info.setVersion( Version.parseVersion( bundle.getVersion() ) );
 
-	private VersionRange defaultVersion(VersionRange current, String defaultRange) {
-		if (current.equals(VersionRange.ANY_VERSION) ||
-			current.equals(VersionRange.parseVersionRange(defaultRange))) {
-			return null;
-		}
-		return current;
-	}
-	
-	// FIXME - copied from BldProject
-	private String getDefaultPackageVersion(String name) {
-		if (packageDefaults == null) {
-    		packageDefaults = config.getProps(null, BldConfig.P_PACKAGE_VERSION);
-    		packageWildDefaults = new TreeSet<String>();
-    		
-    		for (Object key : packageDefaults.keySet()) {
-    			String pkg = (String)key;
-    			if (pkg.endsWith("*")) {
-    				packageWildDefaults.add(pkg.substring(0, pkg.length() - 1));
-    			}
-    		}
-		}
-		
-		String version = packageDefaults.getProperty(name);
-		
-		if (version == null) {
-			for (String pkg : packageWildDefaults) {
-				if (name.startsWith(pkg)) {
-					version = packageDefaults.getProperty(pkg + "*");
-					// break; -- don't break, as we want the longest match
-				}
-			}
-		}
-		
-	    return version;
-	}
-	
-	
-	/**
-	 * converts from an ISigilBundle.
-	 * 
-	 * @param id
-	 * @param bundle
-	 */
-	public void setBundle(String id, ISigilBundle bundle) {
-		IBundleModelElement info = bundle.getBundleInfo();
-		String bundleVersion = config.getString(id, BldConfig.S_VERSION);
+        String activator = bundle.getActivator();
+        if ( activator != null )
+            info.setActivator( activator );
 
-		// exports
-		Map<String, Map<String, String>> exports = new TreeMap<String, Map<String,String>>();
-		for (IPackageExport export : info.getExports()) {
-			Map<String, String> map2 = new TreeMap<String, String>();
-			String version = export.getVersion().toString();
-			if (!version.equals(bundleVersion))
-				map2.put(BldAttr.VERSION_ATTRIBUTE, version);
-			exports.put(export.getPackageName(), map2);
-		}
-		
-		if (!exports.isEmpty() || !config.getMap(id, BldConfig.M_EXPORTS).isEmpty()) {
-			config.setMap(id, BldConfig.M_EXPORTS, exports);
-		}
+        Properties headers = config.getProps( id, BldConfig.P_HEADER );
+        String header;
 
-		// imports
-		Map<String, Map<String, String>> imports = new TreeMap<String, Map<String,String>>();
+        header = headers.getProperty( "CATEGORY" );
+        if ( header != null )
+            info.setCategory( header );
 
-		// FIXME: default version logic is wrong here
-		//    if the version to be saved is the same as the default version,
-		//    then we should _remove_ the version from the value being saved,
-		//    since config.getMap() does not apply default versions.
-		for (IPackageImport import1 : info.getImports()) {
-			Map<String, String> map2 = new TreeMap<String, String>();
-			String name = import1.getPackageName();
-			VersionRange versions = defaultVersion(import1.getVersions(), getDefaultPackageVersion(name));
-			
-			boolean isDependency = import1.isDependency();
-			Map<String, String> selfImport = exports.get(name);
-			
-			if (selfImport != null) {
-    			// avoid saving self-import attributes, e.g.
-    			// org.cauldron.newton.example.fractal.engine;resolve=auto;version=1.0.0
-				isDependency = true;
-				
-				if (versions != null) {
-    				String exportVersion = selfImport.get(BldAttr.VERSION_ATTRIBUTE);
-    				if (exportVersion == null)
-    					exportVersion = bundleVersion;
-    				
-    				if (exportVersion.equals(versions.toString())) {
-    					versions = null;
-    				}
-				}
-			}
+        header = headers.getProperty( Constants.BUNDLE_CONTACTADDRESS );
+        if ( header != null )
+            info.setContactAddress( header );
 
-			if (versions != null) {
-				map2.put(BldAttr.VERSION_ATTRIBUTE, versions.toString());
-			}
-			
-			if (import1.isOptional()) {
-				map2.put(BldAttr.RESOLUTION_ATTRIBUTE, BldAttr.RESOLUTION_OPTIONAL);
-			}
-			
-			String resolve = BldProject.getResolve(import1, isDependency);
-			if (resolve != null)
-				map2.put(BldAttr.RESOLVE_ATTRIBUTE, resolve);
-			
-			imports.put(name, map2);
-		}
-		if (!imports.isEmpty() || !config.getMap(id, BldConfig.M_IMPORTS).isEmpty()) {
-			config.setMap(id, BldConfig.M_IMPORTS, imports);
-		}
+        header = headers.getProperty( Constants.BUNDLE_COPYRIGHT );
+        if ( header != null )
+            info.setCopyright( header );
 
-		// requires
-		Properties defaultBundles = config.getProps(null, BldConfig.P_BUNDLE_VERSION);
-		Map<String, Map<String, String>> requires = new TreeMap<String, Map<String,String>>();
-		
-		for (IRequiredBundle require : info.getRequiredBundles()) {
-			Map<String, String> map2 = new TreeMap<String, String>();
-			String name = require.getSymbolicName();
-			VersionRange versions = defaultVersion(require.getVersions(), defaultBundles.getProperty(name));
-			if (versions != null)
-    			map2.put(BldAttr.VERSION_ATTRIBUTE, versions.toString());
-			requires.put(name, map2);
-		}
-		if (!requires.isEmpty() || !config.getMap(id, BldConfig.M_REQUIRES).isEmpty()) {
-			config.setMap(id, BldConfig.M_REQUIRES, requires);
-		}
+        header = headers.getProperty( Constants.BUNDLE_DESCRIPTION );
+        if ( header != null )
+            info.setDescription( header );
 
-		// fragment
-		Map<String, Map<String, String>> fragments = new TreeMap<String, Map<String,String>>();
-		IRequiredBundle fragment = info.getFragmentHost();
-		if (fragment != null) {
-			Map<String, String> map2 = new TreeMap<String, String>();
-			String name = fragment.getSymbolicName();
-			VersionRange versions = defaultVersion(fragment.getVersions(), defaultBundles.getProperty(name));
-			if (versions != null)
-    			map2.put(BldAttr.VERSION_ATTRIBUTE, versions.toString());
-			fragments.put(name, map2);
-		}
-		if (!fragments.isEmpty() || !config.getMap(id, BldConfig.M_FRAGMENT).isEmpty()) {
-			config.setMap(id, BldConfig.M_FRAGMENT, fragments);
-		}
-	
-		// contents
-		List<String> contents = new ArrayList<String>();
-		for (String pkg : bundle.getPackages()) {
-			contents.add(pkg);
-		}
-		if (!contents.isEmpty() || !config.getList(id, BldConfig.L_CONTENTS).isEmpty()) {
-			config.setList(id, BldConfig.L_CONTENTS, contents);
-		}
-		
-		// dl contents
-		List<String> dlcontents = new ArrayList<String>();
-		for (String pkg : bundle.getDownloadPackages()) {
-			dlcontents.add(pkg);
-		}
-		if (!dlcontents.isEmpty() || !config.getList(id, BldConfig.L_DL_CONTENTS).isEmpty()) {
-			config.setList(id, BldConfig.L_DL_CONTENTS, dlcontents);
-		}
+        header = headers.getProperty( Constants.BUNDLE_VENDOR );
+        if ( header != null )
+            info.setVendor( header );
 
-		// libs
-		Map<String, Map<String, String>> libs = new TreeMap<String, Map<String,String>>();
-		List<String> sources = new ArrayList<String>();
+        header = headers.getProperty( Constants.BUNDLE_NAME );
+        if ( header != null )
+            info.setName( header );
 
-		// classpathEntries map to -libs or -sources
-		for (String entry : bundle.getClasspathEntrys()) {
-			// <classpathentry kind="lib" path="lib/dependee.jar"/>
-			// <classpathentry kind="src" path="src"/>
-			final String regex = ".* kind=\"([^\"]+)\" path=\"([^\"]+)\".*";
-			Pattern pattern = Pattern.compile(regex);
-			Matcher matcher = pattern.matcher(entry);
-			if (matcher.matches()) {
-				String kind = matcher.group(1);
-				String path = matcher.group(2);
-				if (kind.equals("lib")) {
-    				Map<String, String> map2 = new TreeMap<String, String>();
-    				map2.put(BldAttr.KIND_ATTRIBUTE, "classpath");
-    				libs.put(path, map2);
-				} else if (kind.equals("src")) {
-					sources.add(path);
-				} else {
-    				BldCore.error("unknown classpathentry kind=" + kind);
-				}
-			} else {
-				BldCore.error("can't match classpathEntry in: " + entry);
-			}
-		}
+        header = headers.getProperty( Constants.BUNDLE_DOCURL );
+        if ( header != null )
+            info.setDocURI( URI.create( header ) );
 
-		if (!libs.isEmpty() || !config.getMap(id, BldConfig.M_LIBS).isEmpty()) {
-			config.setMap(id, BldConfig.M_LIBS, libs);
-		}
+        header = headers.getProperty( Constants.BUNDLE_LICENSE );
+        if ( header != null )
+            info.setDocURI( URI.create( header ) );
 
-		if (!sources.isEmpty() || !config.getList(id, BldConfig.L_SRC_CONTENTS).isEmpty()) {
-			config.setList(id, BldConfig.L_SRC_CONTENTS, sources);
-		}
+        return sigilBundle;
+    }
 
-		// composites
-		ArrayList<String> composites = new ArrayList<String>();
-		for (ISCAComposite composite : bundle.getComposites()) {
-			String path = composite.getLocation().toString();
-			// TODO relativize
-			composites.add(path);
-		}
-		
-		if (!composites.isEmpty() || !config.getList(id, BldConfig.L_COMPOSITES).isEmpty()) {
-			Collections.sort(composites);
-			config.setList(id, BldConfig.L_COMPOSITES, composites);
-		}
-		
-		// resources
-		ArrayList<String> resources = new ArrayList<String>();
-		for (IPath ipath : bundle.getSourcePaths()) {
-			resources.add(ipath.toString());
-		}
-		
-		if (!resources.isEmpty() || !config.getList(id, BldConfig.L_RESOURCES).isEmpty()) {
-    		Collections.sort(resources);
-			config.setList(id, BldConfig.L_RESOURCES, resources);
-		}
-		
-		if (info.getSourceLocation() != null) {
-			BldCore.error("SourceLocation conversion not yet implemented.");
-		}
 
-		if (!info.getLibraryImports().isEmpty()) {
-			BldCore.error("LibraryImports conversion not yet implemented.");
-		}
+    private VersionRange defaultVersion( VersionRange current, String defaultRange )
+    {
+        if ( current.equals( VersionRange.ANY_VERSION )
+            || current.equals( VersionRange.parseVersionRange( defaultRange ) ) )
+        {
+            return null;
+        }
+        return current;
+    }
 
-		////////////////////
-		// simple headers
 
-		List<String> ids = config.getList(null, BldConfig.C_BUNDLES);
-		String idBsn = id != null ? id : ids.get(0);
-		String oldBsn = config.getString(id, BldConfig.S_SYM_NAME);
-		String bsn = info.getSymbolicName();
-		
-		if (!bsn.equals(idBsn) || oldBsn != null)
-			config.setString(id, BldConfig.S_SYM_NAME, bsn);
+    // FIXME - copied from BldProject
+    private String getDefaultPackageVersion( String name )
+    {
+        if ( packageDefaults == null )
+        {
+            packageDefaults = config.getProps( null, BldConfig.P_PACKAGE_VERSION );
+            packageWildDefaults = new TreeSet<String>();
 
-		String version = info.getVersion().toString();
-		if (version != null)
-			config.setString(id, BldConfig.S_VERSION, version);
+            for ( Object key : packageDefaults.keySet() )
+            {
+                String pkg = ( String ) key;
+                if ( pkg.endsWith( "*" ) )
+                {
+                    packageWildDefaults.add( pkg.substring( 0, pkg.length() - 1 ) );
+                }
+            }
+        }
 
-		String activator = info.getActivator();
-		if (activator != null)
-    		config.setString(id, BldConfig.S_ACTIVATOR, activator);
-		
-		Properties headers = config.getProps(null, BldConfig.P_HEADER);
-		
-		setHeader(headers, id, "CATEGORY", info.getCategory());
-		setHeader(headers, id, Constants.BUNDLE_CONTACTADDRESS, info.getContactAddress());
-		setHeader(headers, id, Constants.BUNDLE_COPYRIGHT, info.getCopyright());
-		setHeader(headers, id, Constants.BUNDLE_DESCRIPTION, info.getDescription());
-		setHeader(headers, id, Constants.BUNDLE_VENDOR, info.getVendor());
-		setHeader(headers, id, Constants.BUNDLE_NAME, info.getName());
+        String version = packageDefaults.getProperty( name );
 
-		if (info.getDocURI() != null)
-			config.setProp(id, BldConfig.P_HEADER, Constants.BUNDLE_DOCURL, info.getDocURI().toString());
+        if ( version == null )
+        {
+            for ( String pkg : packageWildDefaults )
+            {
+                if ( name.startsWith( pkg ) )
+                {
+                    version = packageDefaults.getProperty( pkg + "*" );
+                    // break; -- don't break, as we want the longest match
+                }
+            }
+        }
 
-		if (info.getLicenseURI() != null)
-			config.setProp(id, BldConfig.P_HEADER, Constants.BUNDLE_LICENSE, info.getLicenseURI().toString());
-	}
-	
-	private void setHeader(Properties headers, String id, String key, String value) {
-		if (value == null)
-			value = "";
-		if (!value.equals(headers.getProperty(key, "")))
-    		config.setProp(id, BldConfig.P_HEADER, key, value);
-	}
+        return version;
+    }
+
+
+    /**
+     * converts from an ISigilBundle.
+     * 
+     * @param id
+     * @param bundle
+     */
+    public void setBundle( String id, ISigilBundle bundle )
+    {
+        IBundleModelElement info = bundle.getBundleInfo();
+        String bundleVersion = config.getString( id, BldConfig.S_VERSION );
+
+        // exports
+        Map<String, Map<String, String>> exports = new TreeMap<String, Map<String, String>>();
+        for ( IPackageExport export : info.getExports() )
+        {
+            Map<String, String> map2 = new TreeMap<String, String>();
+            String version = export.getVersion().toString();
+            if ( !version.equals( bundleVersion ) )
+                map2.put( BldAttr.VERSION_ATTRIBUTE, version );
+            exports.put( export.getPackageName(), map2 );
+        }
+
+        if ( !exports.isEmpty() || !config.getMap( id, BldConfig.M_EXPORTS ).isEmpty() )
+        {
+            config.setMap( id, BldConfig.M_EXPORTS, exports );
+        }
+
+        // imports
+        Map<String, Map<String, String>> imports = new TreeMap<String, Map<String, String>>();
+
+        // FIXME: default version logic is wrong here
+        //    if the version to be saved is the same as the default version,
+        //    then we should _remove_ the version from the value being saved,
+        //    since config.getMap() does not apply default versions.
+        for ( IPackageImport import1 : info.getImports() )
+        {
+            Map<String, String> map2 = new TreeMap<String, String>();
+            String name = import1.getPackageName();
+            VersionRange versions = defaultVersion( import1.getVersions(), getDefaultPackageVersion( name ) );
+
+            boolean isDependency = import1.isDependency();
+            Map<String, String> selfImport = exports.get( name );
+
+            if ( selfImport != null )
+            {
+                // avoid saving self-import attributes, e.g.
+                // org.cauldron.newton.example.fractal.engine;resolve=auto;version=1.0.0
+                isDependency = true;
+
+                if ( versions != null )
+                {
+                    String exportVersion = selfImport.get( BldAttr.VERSION_ATTRIBUTE );
+                    if ( exportVersion == null )
+                        exportVersion = bundleVersion;
+
+                    if ( exportVersion.equals( versions.toString() ) )
+                    {
+                        versions = null;
+                    }
+                }
+            }
+
+            if ( versions != null )
+            {
+                map2.put( BldAttr.VERSION_ATTRIBUTE, versions.toString() );
+            }
+
+            if ( import1.isOptional() )
+            {
+                map2.put( BldAttr.RESOLUTION_ATTRIBUTE, BldAttr.RESOLUTION_OPTIONAL );
+            }
+
+            String resolve = BldProject.getResolve( import1, isDependency );
+            if ( resolve != null )
+                map2.put( BldAttr.RESOLVE_ATTRIBUTE, resolve );
+
+            imports.put( name, map2 );
+        }
+        if ( !imports.isEmpty() || !config.getMap( id, BldConfig.M_IMPORTS ).isEmpty() )
+        {
+            config.setMap( id, BldConfig.M_IMPORTS, imports );
+        }
+
+        // requires
+        Properties defaultBundles = config.getProps( null, BldConfig.P_BUNDLE_VERSION );
+        Map<String, Map<String, String>> requires = new TreeMap<String, Map<String, String>>();
+
+        for ( IRequiredBundle require : info.getRequiredBundles() )
+        {
+            Map<String, String> map2 = new TreeMap<String, String>();
+            String name = require.getSymbolicName();
+            VersionRange versions = defaultVersion( require.getVersions(), defaultBundles.getProperty( name ) );
+            if ( versions != null )
+                map2.put( BldAttr.VERSION_ATTRIBUTE, versions.toString() );
+            requires.put( name, map2 );
+        }
+        if ( !requires.isEmpty() || !config.getMap( id, BldConfig.M_REQUIRES ).isEmpty() )
+        {
+            config.setMap( id, BldConfig.M_REQUIRES, requires );
+        }
+
+        // fragment
+        Map<String, Map<String, String>> fragments = new TreeMap<String, Map<String, String>>();
+        IRequiredBundle fragment = info.getFragmentHost();
+        if ( fragment != null )
+        {
+            Map<String, String> map2 = new TreeMap<String, String>();
+            String name = fragment.getSymbolicName();
+            VersionRange versions = defaultVersion( fragment.getVersions(), defaultBundles.getProperty( name ) );
+            if ( versions != null )
+                map2.put( BldAttr.VERSION_ATTRIBUTE, versions.toString() );
+            fragments.put( name, map2 );
+        }
+        if ( !fragments.isEmpty() || !config.getMap( id, BldConfig.M_FRAGMENT ).isEmpty() )
+        {
+            config.setMap( id, BldConfig.M_FRAGMENT, fragments );
+        }
+
+        // contents
+        List<String> contents = new ArrayList<String>();
+        for ( String pkg : bundle.getPackages() )
+        {
+            contents.add( pkg );
+        }
+        if ( !contents.isEmpty() || !config.getList( id, BldConfig.L_CONTENTS ).isEmpty() )
+        {
+            config.setList( id, BldConfig.L_CONTENTS, contents );
+        }
+
+        // dl contents
+        List<String> dlcontents = new ArrayList<String>();
+        for ( String pkg : bundle.getDownloadPackages() )
+        {
+            dlcontents.add( pkg );
+        }
+        if ( !dlcontents.isEmpty() || !config.getList( id, BldConfig.L_DL_CONTENTS ).isEmpty() )
+        {
+            config.setList( id, BldConfig.L_DL_CONTENTS, dlcontents );
+        }
+
+        // libs
+        Map<String, Map<String, String>> libs = new TreeMap<String, Map<String, String>>();
+        List<String> sources = new ArrayList<String>();
+
+        // classpathEntries map to -libs or -sources
+        for ( String entry : bundle.getClasspathEntrys() )
+        {
+            // <classpathentry kind="lib" path="lib/dependee.jar"/>
+            // <classpathentry kind="src" path="src"/>
+            final String regex = ".* kind=\"([^\"]+)\" path=\"([^\"]+)\".*";
+            Pattern pattern = Pattern.compile( regex );
+            Matcher matcher = pattern.matcher( entry );
+            if ( matcher.matches() )
+            {
+                String kind = matcher.group( 1 );
+                String path = matcher.group( 2 );
+                if ( kind.equals( "lib" ) )
+                {
+                    Map<String, String> map2 = new TreeMap<String, String>();
+                    map2.put( BldAttr.KIND_ATTRIBUTE, "classpath" );
+                    libs.put( path, map2 );
+                }
+                else if ( kind.equals( "src" ) )
+                {
+                    sources.add( path );
+                }
+                else
+                {
+                    BldCore.error( "unknown classpathentry kind=" + kind );
+                }
+            }
+            else
+            {
+                BldCore.error( "can't match classpathEntry in: " + entry );
+            }
+        }
+
+        if ( !libs.isEmpty() || !config.getMap( id, BldConfig.M_LIBS ).isEmpty() )
+        {
+            config.setMap( id, BldConfig.M_LIBS, libs );
+        }
+
+        if ( !sources.isEmpty() || !config.getList( id, BldConfig.L_SRC_CONTENTS ).isEmpty() )
+        {
+            config.setList( id, BldConfig.L_SRC_CONTENTS, sources );
+        }
+
+        // composites
+        ArrayList<String> composites = new ArrayList<String>();
+        for ( ISCAComposite composite : bundle.getComposites() )
+        {
+            String path = composite.getLocation().toString();
+            // TODO relativize
+            composites.add( path );
+        }
+
+        if ( !composites.isEmpty() || !config.getList( id, BldConfig.L_COMPOSITES ).isEmpty() )
+        {
+            Collections.sort( composites );
+            config.setList( id, BldConfig.L_COMPOSITES, composites );
+        }
+
+        // resources
+        ArrayList<String> resources = new ArrayList<String>();
+        for ( IPath ipath : bundle.getSourcePaths() )
+        {
+            resources.add( ipath.toString() );
+        }
+
+        if ( !resources.isEmpty() || !config.getList( id, BldConfig.L_RESOURCES ).isEmpty() )
+        {
+            Collections.sort( resources );
+            config.setList( id, BldConfig.L_RESOURCES, resources );
+        }
+
+        if ( info.getSourceLocation() != null )
+        {
+            BldCore.error( "SourceLocation conversion not yet implemented." );
+        }
+
+        if ( !info.getLibraryImports().isEmpty() )
+        {
+            BldCore.error( "LibraryImports conversion not yet implemented." );
+        }
+
+        ////////////////////
+        // simple headers
+
+        List<String> ids = config.getList( null, BldConfig.C_BUNDLES );
+        String idBsn = id != null ? id : ids.get( 0 );
+        String oldBsn = config.getString( id, BldConfig.S_SYM_NAME );
+        String bsn = info.getSymbolicName();
+
+        if ( !bsn.equals( idBsn ) || oldBsn != null )
+            config.setString( id, BldConfig.S_SYM_NAME, bsn );
+
+        String version = info.getVersion().toString();
+        if ( version != null )
+            config.setString( id, BldConfig.S_VERSION, version );
+
+        String activator = info.getActivator();
+        if ( activator != null )
+            config.setString( id, BldConfig.S_ACTIVATOR, activator );
+
+        Properties headers = config.getProps( null, BldConfig.P_HEADER );
+
+        setHeader( headers, id, "CATEGORY", info.getCategory() );
+        setHeader( headers, id, Constants.BUNDLE_CONTACTADDRESS, info.getContactAddress() );
+        setHeader( headers, id, Constants.BUNDLE_COPYRIGHT, info.getCopyright() );
+        setHeader( headers, id, Constants.BUNDLE_DESCRIPTION, info.getDescription() );
+        setHeader( headers, id, Constants.BUNDLE_VENDOR, info.getVendor() );
+        setHeader( headers, id, Constants.BUNDLE_NAME, info.getName() );
+
+        if ( info.getDocURI() != null )
+            config.setProp( id, BldConfig.P_HEADER, Constants.BUNDLE_DOCURL, info.getDocURI().toString() );
+
+        if ( info.getLicenseURI() != null )
+            config.setProp( id, BldConfig.P_HEADER, Constants.BUNDLE_LICENSE, info.getLicenseURI().toString() );
+    }
+
+
+    private void setHeader( Properties headers, String id, String key, String value )
+    {
+        if ( value == null )
+            value = "";
+        if ( !value.equals( headers.getProperty( key, "" ) ) )
+            config.setProp( id, BldConfig.P_HEADER, key, value );
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/config/BldFactory.java b/sigil/common/core/src/org/apache/felix/sigil/config/BldFactory.java
index 6ce36f5..85f9261 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/config/BldFactory.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/config/BldFactory.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.config;
 
+
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
@@ -26,55 +27,70 @@
 import java.util.Map;
 import java.util.Properties;
 
-public class BldFactory {
-	private static Map<URI, BldProject> projects = new HashMap<URI, BldProject>();
-	
-	public static IBldProject getProject(URI uri) throws IOException {
-		return getProject(uri, false);
-	}
-	
-	public static IBldProject getProject(URI uri, boolean ignoreCache) throws IOException {
-		return load(uri, ignoreCache);
-	}
-	
-	public static IRepositoryConfig getConfig(URI uri) throws IOException {
-		return load(uri, false);
-	}
-	
-	/**
-	 * creates a new project file, initialised with defaults.
-	 * @param uri where the file will be saved - used to resolve relative paths.
-	 * @param defaults relative path to defaults file - default ../sigil.properties.
-	 * @return
-	 * @throws IOException
-	 */
-	public static IBldProject newProject(URI uri, String defaults) throws IOException {
-		BldProject project = new BldProject(uri);
-		Properties p = new Properties();
-		if (defaults != null)
-    		p.setProperty(BldConfig.S_DEFAULTS, defaults);
-		project.loadDefaults(p);
-		return project;
-	}
-	
-	private static BldProject load(URI uri, boolean ignoreCache) throws IOException {
-		BldProject p = null; 
-		if (!ignoreCache) {
-			p = projects.get(uri);
-		}
-		
-		if (p == null) {
-			p = new BldProject(uri);
-			p.load();
-			projects.put(uri, p);
-    			
-    		if (Boolean.getBoolean("org.apache.felix.sigil.config.test")) {
-    			File path = new File(uri.getPath() + ".tmp");
-    			System.out.println("XXX: config.test writing: " + path);
-    			p.saveAs(path);
-    		}
-		}
-		return p;
-	}
-	
+
+public class BldFactory
+{
+    private static Map<URI, BldProject> projects = new HashMap<URI, BldProject>();
+
+
+    public static IBldProject getProject( URI uri ) throws IOException
+    {
+        return getProject( uri, false );
+    }
+
+
+    public static IBldProject getProject( URI uri, boolean ignoreCache ) throws IOException
+    {
+        return load( uri, ignoreCache );
+    }
+
+
+    public static IRepositoryConfig getConfig( URI uri ) throws IOException
+    {
+        return load( uri, false );
+    }
+
+
+    /**
+     * creates a new project file, initialised with defaults.
+     * @param uri where the file will be saved - used to resolve relative paths.
+     * @param defaults relative path to defaults file - default ../sigil.properties.
+     * @return
+     * @throws IOException
+     */
+    public static IBldProject newProject( URI uri, String defaults ) throws IOException
+    {
+        BldProject project = new BldProject( uri );
+        Properties p = new Properties();
+        if ( defaults != null )
+            p.setProperty( BldConfig.S_DEFAULTS, defaults );
+        project.loadDefaults( p );
+        return project;
+    }
+
+
+    private static BldProject load( URI uri, boolean ignoreCache ) throws IOException
+    {
+        BldProject p = null;
+        if ( !ignoreCache )
+        {
+            p = projects.get( uri );
+        }
+
+        if ( p == null )
+        {
+            p = new BldProject( uri );
+            p.load();
+            projects.put( uri, p );
+
+            if ( Boolean.getBoolean( "org.apache.felix.sigil.config.test" ) )
+            {
+                File path = new File( uri.getPath() + ".tmp" );
+                System.out.println( "XXX: config.test writing: " + path );
+                p.saveAs( path );
+            }
+        }
+        return p;
+    }
+
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/config/BldProject.java b/sigil/common/core/src/org/apache/felix/sigil/config/BldProject.java
index 9e1a031..d959ebb 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/config/BldProject.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/config/BldProject.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.config;
 
+
 import java.io.BufferedInputStream;
 import java.io.BufferedReader;
 import java.io.File;
@@ -56,7 +57,9 @@
 import org.apache.felix.sigil.model.osgi.IPackageImport.OSGiImport;
 import org.osgi.framework.Version;
 
-public class BldProject implements IBldProject, IRepositoryConfig {
+
+public class BldProject implements IBldProject, IRepositoryConfig
+{
     private static final String OVERRIDE_PREFIX = "sigil.";
     private static final int MAX_HEADER = 10240;
     // cache to avoid loading the same default config for each project
@@ -73,132 +76,152 @@
     private TreeSet<String> packageWildDefaults;
     private long lastModified;
 
-    /* package */BldProject(URI relLoc) {
+
+    /* package */BldProject( URI relLoc )
+    {
         config = new BldConfig();
-        convert = new BldConverter(config);
-        loc = new File(".").toURI().resolve(relLoc).normalize();
-        File f = new File(loc);
+        convert = new BldConverter( config );
+        loc = new File( "." ).toURI().resolve( relLoc ).normalize();
+        File f = new File( loc );
         lastModified = f.lastModified();
         baseDir = f.getParentFile();
     }
 
-    /* package */void load() throws IOException {
+
+    /* package */void load() throws IOException
+    {
         // allow System property overrides, e.g.
         // ANT_OPTS='-Dsigil.option\;addMissingImports=false' ant
-        config.merge(getOverrides());
+        config.merge( getOverrides() );
 
         InputStream in = null;
-        try {
-        	in = loc.toURL().openStream();
-	        BufferedInputStream bis = new BufferedInputStream(in);
-	        bis.mark(MAX_HEADER);
-	        readHeader(bis);
-	        bis.reset();
-	
-	        Properties p = new Properties();
-	        p.load(bis);
-	        config.merge(p);
-	
-	        Properties unknown = config.getUnknown();
-	        if (!unknown.isEmpty())
-	            System.err.println("WARN: unknown keys " + unknown.keySet() + " in " + loc);
-	
-	        loadDefaults(p);
-	        requirements = parseRequirements();
+        try
+        {
+            in = loc.toURL().openStream();
+            BufferedInputStream bis = new BufferedInputStream( in );
+            bis.mark( MAX_HEADER );
+            readHeader( bis );
+            bis.reset();
+
+            Properties p = new Properties();
+            p.load( bis );
+            config.merge( p );
+
+            Properties unknown = config.getUnknown();
+            if ( !unknown.isEmpty() )
+                System.err.println( "WARN: unknown keys " + unknown.keySet() + " in " + loc );
+
+            loadDefaults( p );
+            requirements = parseRequirements();
         }
-        finally {
-        	if ( in != null ) {
-        		in.close();
-        	}
+        finally
+        {
+            if ( in != null )
+            {
+                in.close();
+            }
         }
     }
 
-    /* package */void loadDefaults(Properties p) throws IOException {
-        BldConfig c = loadDefaults(p, baseDir, null);
-        config.setDefault(c);
 
-        Properties options = config.getProps(null, BldConfig.P_OPTION);
+    /* package */void loadDefaults( Properties p ) throws IOException
+    {
+        BldConfig c = loadDefaults( p, baseDir, null );
+        config.setDefault( c );
 
-        if (!options.containsKey(BldAttr.OPTION_ADD_IMPORTS))
-            c.setProp(null, BldConfig.P_OPTION, BldAttr.OPTION_ADD_IMPORTS, "true");
+        Properties options = config.getProps( null, BldConfig.P_OPTION );
+
+        if ( !options.containsKey( BldAttr.OPTION_ADD_IMPORTS ) )
+            c.setProp( null, BldConfig.P_OPTION, BldAttr.OPTION_ADD_IMPORTS, "true" );
 
         // default omitUnusedImports option depends on number of bundles...
         // we set it here to avoid it being written by save(),
         // but as this may alter cached defaults, once set we have to reset it
         // for each project.
 
-        boolean omitSet = options.containsKey("__omit_set__");
+        boolean omitSet = options.containsKey( "__omit_set__" );
         boolean multiple = getBundleIds().size() > 1;
 
-        if (multiple || omitSet) {
-            if (!options.containsKey(BldAttr.OPTION_OMIT_IMPORTS) || omitSet) {
-                c.setProp(null, BldConfig.P_OPTION, BldAttr.OPTION_OMIT_IMPORTS, multiple + "");
-                c.setProp(null, BldConfig.P_OPTION, "__omit_set__", "true");
+        if ( multiple || omitSet )
+        {
+            if ( !options.containsKey( BldAttr.OPTION_OMIT_IMPORTS ) || omitSet )
+            {
+                c.setProp( null, BldConfig.P_OPTION, BldAttr.OPTION_OMIT_IMPORTS, multiple + "" );
+                c.setProp( null, BldConfig.P_OPTION, "__omit_set__", "true" );
             }
         }
     }
 
-    private synchronized BldConfig loadDefaults(Properties props, File base, BldConfig dflt)
-            throws IOException {
+
+    private synchronized BldConfig loadDefaults( Properties props, File base, BldConfig dflt ) throws IOException
+    {
         boolean cached = false;
-        String defaults = props.getProperty(BldConfig.S_DEFAULTS, "-"
-                + IBldProject.PROJECT_DEFAULTS);
+        String defaults = props.getProperty( BldConfig.S_DEFAULTS, "-" + IBldProject.PROJECT_DEFAULTS );
 
-        if (base != null && defaults.length() > 0) {
-            boolean ignore = defaults.startsWith("-");
+        if ( base != null && defaults.length() > 0 )
+        {
+            boolean ignore = defaults.startsWith( "-" );
 
-            if (ignore)
-                defaults = defaults.substring(1);
+            if ( ignore )
+                defaults = defaults.substring( 1 );
 
-            try {
-                File file = new File(base, defaults).getCanonicalFile();
+            try
+            {
+                File file = new File( base, defaults ).getCanonicalFile();
                 URL url = file.toURL();
 
-                if (dflt == null) {
-                    dflt = defaultsCache.get(url);
-                    if (dflt != null)
+                if ( dflt == null )
+                {
+                    dflt = defaultsCache.get( url );
+                    if ( dflt != null )
                         return dflt;
 
                     dflt = new BldConfig();
-                    defaultsCache.put(url, dflt);
+                    defaultsCache.put( url, dflt );
                     cached = true;
                 }
 
                 Properties p = new Properties();
-                p.load(url.openStream());
-                dflt.merge(p);
+                p.load( url.openStream() );
+                dflt.merge( p );
 
                 ignore = false;
-                loadDefaults(p, file.getParentFile(), dflt);
-            } catch (IOException e) {
-                if (!ignore)
+                loadDefaults( p, file.getParentFile(), dflt );
+            }
+            catch ( IOException e )
+            {
+                if ( !ignore )
                     throw e;
             }
         }
 
-        if (dflt == null)
+        if ( dflt == null )
             return new BldConfig();
 
-        if (cached) {
+        if ( cached )
+        {
             Properties unknown = dflt.getUnknown();
-            if (!unknown.isEmpty())
-                System.err.println("WARN: unknown keys " + unknown.keySet() + " in defaults for "
-                        + loc);
+            if ( !unknown.isEmpty() )
+                System.err.println( "WARN: unknown keys " + unknown.keySet() + " in defaults for " + loc );
         }
 
         return dflt;
     }
 
-    private static Properties getOverrides() {
-        if (overrides == null) {
+
+    private static Properties getOverrides()
+    {
+        if ( overrides == null )
+        {
             overrides = new Properties();
             Properties sysProps = System.getProperties();
 
-            for (Object okey : sysProps.keySet()) {
-                String key = (String) okey;
-                if (key.startsWith(OVERRIDE_PREFIX)) {
-                    overrides.setProperty(key.substring(OVERRIDE_PREFIX.length()), sysProps
-                            .getProperty(key));
+            for ( Object okey : sysProps.keySet() )
+            {
+                String key = ( String ) okey;
+                if ( key.startsWith( OVERRIDE_PREFIX ) )
+                {
+                    overrides.setProperty( key.substring( OVERRIDE_PREFIX.length() ), sysProps.getProperty( key ) );
                 }
             }
         }
@@ -206,78 +229,101 @@
         return overrides;
     }
 
-    private void readHeader(InputStream in) throws IOException {
-        BufferedReader r = new BufferedReader(new InputStreamReader(in));
+
+    private void readHeader( InputStream in ) throws IOException
+    {
+        BufferedReader r = new BufferedReader( new InputStreamReader( in ) );
         StringBuffer header = new StringBuffer();
         String line;
-        while ((line = r.readLine()) != null) {
-            if (line.startsWith("#")) {
-                header.append(line);
-                header.append("\n");
-            } else {
-                config.setComment(header.toString());
+        while ( ( line = r.readLine() ) != null )
+        {
+            if ( line.startsWith( "#" ) )
+            {
+                header.append( line );
+                header.append( "\n" );
+            }
+            else
+            {
+                config.setComment( header.toString() );
                 break;
             }
         }
     }
 
-    public File resolve(String path) {
-        File file = new File(path);
-        if (!file.isAbsolute()) {
+
+    public File resolve( String path )
+    {
+        File file = new File( path );
+        if ( !file.isAbsolute() )
+        {
             // can't use loc.resolve(value), as value may not be valid URI.
-            file = new File(baseDir, path);
+            file = new File( baseDir, path );
         }
         return file;
     }
 
-    public String getVersion() {
-        String version = config.getString(null, BldConfig.S_VERSION);
+
+    public String getVersion()
+    {
+        String version = config.getString( null, BldConfig.S_VERSION );
         return version == null ? "0" : version;
     }
 
-    public IBundleModelElement getDependencies() {
+
+    public IBundleModelElement getDependencies()
+    {
         IBundleModelElement dependencies = new BundleModelElement();
 
-        for (IModelElement element : getRequirements().children()) {
-            if (element instanceof IPackageImport) {
-                IPackageImport import1 = (IPackageImport) element;
-                if (!import1.isDependency())
+        for ( IModelElement element : getRequirements().children() )
+        {
+            if ( element instanceof IPackageImport )
+            {
+                IPackageImport import1 = ( IPackageImport ) element;
+                if ( !import1.isDependency() )
                     continue;
 
-                IPackageImport pi = (IPackageImport) (element.clone());
-                pi.setParent(null);
-                dependencies.addImport(pi);
-            } else {
-                IRequiredBundle rb = (IRequiredBundle) (element.clone());
-                rb.setParent(null);
-                dependencies.addRequiredBundle(rb);
+                IPackageImport pi = ( IPackageImport ) ( element.clone() );
+                pi.setParent( null );
+                dependencies.addImport( pi );
+            }
+            else
+            {
+                IRequiredBundle rb = ( IRequiredBundle ) ( element.clone() );
+                rb.setParent( null );
+                dependencies.addRequiredBundle( rb );
             }
         }
 
         boolean containsComposite = false;
 
-        for (IBldBundle bundle : getBundles()) {
-            if (!bundle.getComposites().isEmpty()) {
+        for ( IBldBundle bundle : getBundles() )
+        {
+            if ( !bundle.getComposites().isEmpty() )
+            {
                 containsComposite = true;
                 break;
             }
         }
 
         // add dependency on component activator
-        if (containsComposite) {
+        if ( containsComposite )
+        {
             PackageImport pi = new PackageImport();
-            pi.setPackageName(BundleBuilder.COMPONENT_ACTIVATOR_PKG);
-            pi.setOSGiImport(OSGiImport.NEVER);
-            dependencies.addImport(pi);
+            pi.setPackageName( BundleBuilder.COMPONENT_ACTIVATOR_PKG );
+            pi.setOSGiImport( OSGiImport.NEVER );
+            dependencies.addImport( pi );
         }
 
         return dependencies;
     }
 
-    private IBundleModelElement getRequirements() {
+
+    private IBundleModelElement getRequirements()
+    {
         return requirements;
     }
 
+
     /*
      * private boolean globMatch(String pkg, Set<String> set) { // exact match
      * if (set.contains(pkg)) return true;
@@ -296,75 +342,98 @@
      * auto runtime ignore
      * 
      */
-    private void setResolve(IPackageImport pi, String resolve) throws IOException {
-        if (pi.isOptional())
-            pi.setDependency(false);
+    private void setResolve( IPackageImport pi, String resolve ) throws IOException
+    {
+        if ( pi.isOptional() )
+            pi.setDependency( false );
 
-        if (BldAttr.RESOLVE_COMPILE.equals(resolve)) {
-            if (pi.isOptional())
-                pi.setDependency(true);
+        if ( BldAttr.RESOLVE_COMPILE.equals( resolve ) )
+        {
+            if ( pi.isOptional() )
+                pi.setDependency( true );
             else
-                pi.setOSGiImport(OSGiImport.NEVER);
-        } else if (BldAttr.RESOLVE_RUNTIME.equals(resolve)) {
-            pi.setDependency(false);
-            pi.setOSGiImport(OSGiImport.ALWAYS);
-        } else if (BldAttr.RESOLVE_AUTO.equals(resolve)) {
-            pi.setDependency(false);
-        } else if (BldAttr.RESOLVE_IGNORE.equals(resolve)) {
-            pi.setDependency(false);
-            pi.setOSGiImport(OSGiImport.NEVER);
-        } else if (resolve != null) {
-            throw new IOException("Bad attribute value: " + BldAttr.RESOLVE_ATTRIBUTE + "="
-                    + resolve);
+                pi.setOSGiImport( OSGiImport.NEVER );
+        }
+        else if ( BldAttr.RESOLVE_RUNTIME.equals( resolve ) )
+        {
+            pi.setDependency( false );
+            pi.setOSGiImport( OSGiImport.ALWAYS );
+        }
+        else if ( BldAttr.RESOLVE_AUTO.equals( resolve ) )
+        {
+            pi.setDependency( false );
+        }
+        else if ( BldAttr.RESOLVE_IGNORE.equals( resolve ) )
+        {
+            pi.setDependency( false );
+            pi.setOSGiImport( OSGiImport.NEVER );
+        }
+        else if ( resolve != null )
+        {
+            throw new IOException( "Bad attribute value: " + BldAttr.RESOLVE_ATTRIBUTE + "=" + resolve );
         }
     }
 
+
     /**
      * get external resolve= attribute from internal PackageImport flags. This
      * is called from BldConverter.setBundle().
      */
-    public static String getResolve(IPackageImport pi, boolean isDependency) {
+    public static String getResolve( IPackageImport pi, boolean isDependency )
+    {
         OSGiImport osgiImport = pi.getOSGiImport();
         String resolve = null;
 
-        if (isDependency) {
-            if (osgiImport.equals(OSGiImport.NEVER) || pi.isOptional())
+        if ( isDependency )
+        {
+            if ( osgiImport.equals( OSGiImport.NEVER ) || pi.isOptional() )
                 resolve = BldAttr.RESOLVE_COMPILE;
-        } else {
-            switch (osgiImport) {
-            case ALWAYS:
-                resolve = BldAttr.RESOLVE_RUNTIME;
-                break;
-            case AUTO:
-                resolve = BldAttr.RESOLVE_AUTO;
-                break;
-            case NEVER:
-                resolve = BldAttr.RESOLVE_IGNORE;
-                break;
+        }
+        else
+        {
+            switch ( osgiImport )
+            {
+                case ALWAYS:
+                    resolve = BldAttr.RESOLVE_RUNTIME;
+                    break;
+                case AUTO:
+                    resolve = BldAttr.RESOLVE_AUTO;
+                    break;
+                case NEVER:
+                    resolve = BldAttr.RESOLVE_IGNORE;
+                    break;
             }
         }
         return resolve;
     }
 
-    public String getDefaultPackageVersion(String name) {
-        if (packageDefaults == null) {
-            packageDefaults = config.getProps(null, BldConfig.P_PACKAGE_VERSION);
+
+    public String getDefaultPackageVersion( String name )
+    {
+        if ( packageDefaults == null )
+        {
+            packageDefaults = config.getProps( null, BldConfig.P_PACKAGE_VERSION );
             packageWildDefaults = new TreeSet<String>();
 
-            for (Object key : packageDefaults.keySet()) {
-                String pkg = (String) key;
-                if (pkg.endsWith("*")) {
-                    packageWildDefaults.add(pkg.substring(0, pkg.length() - 1));
+            for ( Object key : packageDefaults.keySet() )
+            {
+                String pkg = ( String ) key;
+                if ( pkg.endsWith( "*" ) )
+                {
+                    packageWildDefaults.add( pkg.substring( 0, pkg.length() - 1 ) );
                 }
             }
         }
 
-        String version = packageDefaults.getProperty(name);
+        String version = packageDefaults.getProperty( name );
 
-        if (version == null) {
-            for (String pkg : packageWildDefaults) {
-                if (name.startsWith(pkg)) {
-                    version = packageDefaults.getProperty(pkg + "*");
+        if ( version == null )
+        {
+            for ( String pkg : packageWildDefaults )
+            {
+                if ( name.startsWith( pkg ) )
+                {
+                    version = packageDefaults.getProperty( pkg + "*" );
                     // break; -- don't break, as we want the longest match
                 }
             }
@@ -373,399 +442,511 @@
         return version;
     }
 
-    private synchronized BundleModelElement parseRequirements() throws IOException {
+
+    private synchronized BundleModelElement parseRequirements() throws IOException
+    {
         BundleModelElement reqs = new BundleModelElement();
 
         List<String> sourceContents = getSourcePkgs();
         HashSet<String> exports = new HashSet<String>();
 
-        for (IBldBundle bundle : getBundles()) {
-            for (IPackageExport export : bundle.getExports()) {
-                exports.add(export.getPackageName());
+        for ( IBldBundle bundle : getBundles() )
+        {
+            for ( IPackageExport export : bundle.getExports() )
+            {
+                exports.add( export.getPackageName() );
             }
         }
 
-        Map<String, Map<String, String>> imports = config.getMap(null, BldConfig.M_IMPORTS);
+        Map<String, Map<String, String>> imports = config.getMap( null, BldConfig.M_IMPORTS );
 
-        for (String name : imports.keySet()) {
-            Map<String, String> attr = imports.get(name);
+        for ( String name : imports.keySet() )
+        {
+            Map<String, String> attr = imports.get( name );
 
-            String resolve = attr.get(BldAttr.RESOLVE_ATTRIBUTE);
-            String resolution = attr.get(BldAttr.RESOLUTION_ATTRIBUTE);
-            String versions = attr.containsKey(BldAttr.VERSION_ATTRIBUTE) ? attr
-                    .get(BldAttr.VERSION_ATTRIBUTE) : getDefaultPackageVersion(name);
+            String resolve = attr.get( BldAttr.RESOLVE_ATTRIBUTE );
+            String resolution = attr.get( BldAttr.RESOLUTION_ATTRIBUTE );
+            String versions = attr.containsKey( BldAttr.VERSION_ATTRIBUTE ) ? attr.get( BldAttr.VERSION_ATTRIBUTE )
+                : getDefaultPackageVersion( name );
 
             PackageImport pi = new PackageImport();
-            pi.setPackageName(name);
+            pi.setPackageName( name );
 
             // avoid dependency on self-exports
             // XXX: BldConverter.setBundle contains similar logic
-            if (exports.contains(name)
-                    && (sourceContents.contains(name) || sourceContents.isEmpty())) {
-                pi.setDependency(false);
-                if (versions == null)
+            if ( exports.contains( name ) && ( sourceContents.contains( name ) || sourceContents.isEmpty() ) )
+            {
+                pi.setDependency( false );
+                if ( versions == null )
                     versions = getVersion();
             }
 
-            if (!checkVersionRange(versions)) {
-                throw new IOException("Failed to parse version range for " + resolve
-                        + " missing \"'s around version range?");
+            if ( !checkVersionRange( versions ) )
+            {
+                throw new IOException( "Failed to parse version range for " + resolve
+                    + " missing \"'s around version range?" );
             }
 
-            pi.setVersions(VersionRange.parseVersionRange(versions));
+            pi.setVersions( VersionRange.parseVersionRange( versions ) );
 
-            if (BldAttr.RESOLUTION_OPTIONAL.equals(resolution)) {
-                pi.setOptional(true);
-            } else if (resolution != null) {
-                throw new IOException("Bad attribute value: " + BldAttr.RESOLUTION_ATTRIBUTE + "="
-                        + resolution);
+            if ( BldAttr.RESOLUTION_OPTIONAL.equals( resolution ) )
+            {
+                pi.setOptional( true );
+            }
+            else if ( resolution != null )
+            {
+                throw new IOException( "Bad attribute value: " + BldAttr.RESOLUTION_ATTRIBUTE + "=" + resolution );
             }
 
-            setResolve(pi, resolve);
+            setResolve( pi, resolve );
 
-            reqs.addImport(pi);
+            reqs.addImport( pi );
         }
 
-        Map<String, Map<String, String>> requires = config.getMap(null, BldConfig.M_REQUIRES);
-        Properties bundleDefaults = config.getProps(null, BldConfig.P_BUNDLE_VERSION);
+        Map<String, Map<String, String>> requires = config.getMap( null, BldConfig.M_REQUIRES );
+        Properties bundleDefaults = config.getProps( null, BldConfig.P_BUNDLE_VERSION );
 
-        if (requires != null) {
-            for (String name : requires.keySet()) {
-                Map<String, String> attr = requires.get(name);
-                String versions = attr.containsKey(BldAttr.VERSION_ATTRIBUTE) ? attr
-                        .get(BldAttr.VERSION_ATTRIBUTE) : bundleDefaults.getProperty(name);
+        if ( requires != null )
+        {
+            for ( String name : requires.keySet() )
+            {
+                Map<String, String> attr = requires.get( name );
+                String versions = attr.containsKey( BldAttr.VERSION_ATTRIBUTE ) ? attr.get( BldAttr.VERSION_ATTRIBUTE )
+                    : bundleDefaults.getProperty( name );
 
                 RequiredBundle rb = new RequiredBundle();
-                rb.setSymbolicName(name);
-                rb.setVersions(VersionRange.parseVersionRange(versions));
+                rb.setSymbolicName( name );
+                rb.setVersions( VersionRange.parseVersionRange( versions ) );
 
-                reqs.addRequiredBundle(rb);
+                reqs.addRequiredBundle( rb );
             }
         }
 
-        for (IBldBundle bundle : getBundles()) {
+        for ( IBldBundle bundle : getBundles() )
+        {
             IRequiredBundle fh = bundle.getFragmentHost();
-            if (fh != null)
-                reqs.addRequiredBundle(fh);
+            if ( fh != null )
+                reqs.addRequiredBundle( fh );
         }
 
         return reqs;
     }
 
-    private boolean checkVersionRange(String versions) {
-        if (versions == null || versions.length() == 0) {
+
+    private boolean checkVersionRange( String versions )
+    {
+        if ( versions == null || versions.length() == 0 )
+        {
             return true;
-        } else {
-            switch (versions.charAt(0)) {
-            case '(':
-            case '[':
-                switch (versions.charAt(versions.length() - 1)) {
-                case ')':
-                case ']':
-                    return true;
+        }
+        else
+        {
+            switch ( versions.charAt( 0 ) )
+            {
+                case '(':
+                case '[':
+                    switch ( versions.charAt( versions.length() - 1 ) )
+                    {
+                        case ')':
+                        case ']':
+                            return true;
+                        default:
+                            return false;
+                    }
                 default:
-                    return false;
-                }
-            default:
-                return true;
+                    return true;
             }
         }
     }
 
-    public List<String> getBundleIds() {
-        List<String> ids = config.getList(null, BldConfig.C_BUNDLES);
-        if (ids == null)
+
+    public List<String> getBundleIds()
+    {
+        List<String> ids = config.getList( null, BldConfig.C_BUNDLES );
+        if ( ids == null )
             return Collections.emptyList();
         return ids;
     }
 
-    public List<IBldBundle> getBundles() {
+
+    public List<IBldBundle> getBundles()
+    {
         ArrayList<IBldBundle> list = new ArrayList<IBldBundle>();
 
-        for (String id : getBundleIds()) {
-            list.add(new BldBundle(id));
+        for ( String id : getBundleIds() )
+        {
+            list.add( new BldBundle( id ) );
         }
 
         return list;
     }
 
+
     // Implement IBldConfig: getRepositoryConfig
 
-    public Map<String, Properties> getRepositoryConfig() {
+    public Map<String, Properties> getRepositoryConfig()
+    {
         HashMap<String, Properties> map = new HashMap<String, Properties>();
 
         final Map<String, String> env = System.getenv();
         final Properties props = new Properties();
-        try {
+        try
+        {
             // supports ${.} and ${..} expansions
-            props.setProperty(".", resolve(".").getCanonicalPath());
-            props.setProperty("..", resolve("..").getCanonicalPath());
-        } catch (IOException e) {
+            props.setProperty( ".", resolve( "." ).getCanonicalPath() );
+            props.setProperty( "..", resolve( ".." ).getCanonicalPath() );
+        }
+        catch ( IOException e )
+        {
         }
 
-        for (String name : config.getList(null, BldConfig.C_REPOSITORIES)) {
-            Properties repo = config.getProps(null, name);
+        for ( String name : config.getList( null, BldConfig.C_REPOSITORIES ) )
+        {
+            Properties repo = config.getProps( null, name );
 
-            for (Object k : repo.keySet()) {
-                String key = (String) k;
-                String value = repo.getProperty(key);
+            for ( Object k : repo.keySet() )
+            {
+                String key = ( String ) k;
+                String value = repo.getProperty( key );
 
-                String expand = BldUtil.expand(value, new Properties() {
-                    public String getProperty(String name) {
-                        return props.getProperty(name, env.get(name));
+                String expand = BldUtil.expand( value, new Properties()
+                {
+                    public String getProperty( String name )
+                    {
+                        return props.getProperty( name, env.get( name ) );
                     }
-                });
+                } );
 
-                if (!value.equals(expand)) {
+                if ( !value.equals( expand ) )
+                {
                     value = expand;
-                    repo.setProperty(key, value);
+                    repo.setProperty( key, value );
                 }
 
                 // backwards compatible support before ${.} and ${..} was added
-                if (value.startsWith("./") || value.startsWith("../")) {
-                    try {
+                if ( value.startsWith( "./" ) || value.startsWith( "../" ) )
+                {
+                    try
+                    {
                         // need canonical path, to normalise
-                        value = resolve(value).getCanonicalPath();
-                    } catch (IOException e) {
+                        value = resolve( value ).getCanonicalPath();
                     }
-                    repo.setProperty(key, value);
+                    catch ( IOException e )
+                    {
+                    }
+                    repo.setProperty( key, value );
                 }
             }
 
-            map.put(name, repo);
+            map.put( name, repo );
         }
         return map;
     }
 
-    public Properties getOptions() {
-        return config.getProps(null, BldConfig.P_OPTION);
+
+    public Properties getOptions()
+    {
+        return config.getProps( null, BldConfig.P_OPTION );
     }
 
-    public Properties getDefaultPackageVersions() {
-        return config.getProps(null, BldConfig.P_PACKAGE_VERSION);
+
+    public Properties getDefaultPackageVersions()
+    {
+        return config.getProps( null, BldConfig.P_PACKAGE_VERSION );
     }
 
-    public ISigilBundle getDefaultBundle() {
+
+    public ISigilBundle getDefaultBundle()
+    {
         List<String> bundles = getBundleIds();
-        if (bundles.isEmpty())
+        if ( bundles.isEmpty() )
             return null;
 
-        String id = bundles.get(0);
-        return getSigilBundle(id);
+        String id = bundles.get( 0 );
+        return getSigilBundle( id );
     }
 
-    public ISigilBundle getSigilBundle(String id) {
-        BldBundle bundle = new BldBundle(id);
-        return convert.getBundle(id, bundle);
+
+    public ISigilBundle getSigilBundle( String id )
+    {
+        BldBundle bundle = new BldBundle( id );
+        return convert.getBundle( id, bundle );
     }
 
-    public void setDefaultBundle(ISigilBundle bundle) {
-        setSigilBundle(null, bundle);
+
+    public void setDefaultBundle( ISigilBundle bundle )
+    {
+        setSigilBundle( null, bundle );
     }
 
-    public void setSigilBundle(String id, ISigilBundle bundle) {
+
+    public void setSigilBundle( String id, ISigilBundle bundle )
+    {
         List<String> ids = getBundleIds();
 
-        if (ids.isEmpty()) {
+        if ( ids.isEmpty() )
+        {
             ArrayList<String> list = new ArrayList<String>();
-            list.add(id == null ? bundle.getBundleInfo().getSymbolicName() : id);
-            config.setList(null, BldConfig.C_BUNDLES, list);
-        } else if (id == null) {
-            id = ids.get(0);
-        } else if (!ids.contains(id)) {
-            List<String> list = config.getList(null, BldConfig.C_BUNDLES);
-            list.add(id);
-            config.setList(null, BldConfig.C_BUNDLES, list);
+            list.add( id == null ? bundle.getBundleInfo().getSymbolicName() : id );
+            config.setList( null, BldConfig.C_BUNDLES, list );
+        }
+        else if ( id == null )
+        {
+            id = ids.get( 0 );
+        }
+        else if ( !ids.contains( id ) )
+        {
+            List<String> list = config.getList( null, BldConfig.C_BUNDLES );
+            list.add( id );
+            config.setList( null, BldConfig.C_BUNDLES, list );
         }
 
-        if (ids.size() == 1)
+        if ( ids.size() == 1 )
             id = null; // don't prefix default bundle with id
 
-        convert.setBundle(id, bundle);
+        convert.setBundle( id, bundle );
     }
 
-    public void save() throws IOException {
-        saveAs(new File(loc));
+
+    public void save() throws IOException
+    {
+        saveAs( new File( loc ) );
     }
 
-    public void saveAs(File path) throws IOException {
-        File part = new File(path.getPath() + ".part");
-        saveTo(new FileOutputStream((part)));
+
+    public void saveAs( File path ) throws IOException
+    {
+        File part = new File( path.getPath() + ".part" );
+        saveTo( new FileOutputStream( ( part ) ) );
 
         path.delete();
-        if (!part.renameTo(path))
-            throw new IOException("failed to rename " + part + " to " + path);
+        if ( !part.renameTo( path ) )
+            throw new IOException( "failed to rename " + part + " to " + path );
     }
 
-    public void saveTo(OutputStream out) {
-        PrintWriter writer = new PrintWriter(new OutputStreamWriter(out));
-        config.write(writer);
+
+    public void saveTo( OutputStream out )
+    {
+        PrintWriter writer = new PrintWriter( new OutputStreamWriter( out ) );
+        config.write( writer );
         writer.close();
     }
 
-    public List<String> getSourceDirs() {
-        List<String> list = config.getList(null, BldConfig.L_SRC_CONTENTS);
+
+    public List<String> getSourceDirs()
+    {
+        List<String> list = config.getList( null, BldConfig.L_SRC_CONTENTS );
         return list != null ? list : Collections.<String> emptyList();
     }
 
-    public List<String> getSourcePkgs() {
-        if (sourcePkgs == null) {
+
+    public List<String> getSourcePkgs()
+    {
+        if ( sourcePkgs == null )
+        {
             sourcePkgs = new ArrayList<String>();
-            for (String src : getSourceDirs()) {
-                File dir = resolve(src);
-                if (!dir.isDirectory()) {
-                    System.err.println("WARN: sourcedir does not exist: " + dir);
+            for ( String src : getSourceDirs() )
+            {
+                File dir = resolve( src );
+                if ( !dir.isDirectory() )
+                {
+                    System.err.println( "WARN: sourcedir does not exist: " + dir );
                     continue;
                     // throw new RuntimeException("sourcedir: " + dir +
                     // " : is not a directory.");
                 }
-                findSrcPkgs(dir, null, sourcePkgs);
+                findSrcPkgs( dir, null, sourcePkgs );
             }
         }
 
         return sourcePkgs;
     }
 
-    private void findSrcPkgs(File dir, String pkg, List<String> result) {
+
+    private void findSrcPkgs( File dir, String pkg, List<String> result )
+    {
         ArrayList<File> dirs = new ArrayList<File>();
         boolean found = false;
 
-        for (String name : dir.list()) {
-            if (name.endsWith(".java")) {
+        for ( String name : dir.list() )
+        {
+            if ( name.endsWith( ".java" ) )
+            {
                 found = true;
-            } else if (!name.equals(".svn")) {
-                File d = new File(dir, name);
-                if (d.isDirectory())
-                    dirs.add(d);
+            }
+            else if ( !name.equals( ".svn" ) )
+            {
+                File d = new File( dir, name );
+                if ( d.isDirectory() )
+                    dirs.add( d );
             }
         }
 
-        if (pkg == null) {
+        if ( pkg == null )
+        {
             pkg = "";
-        } else if (pkg.equals("")) {
+        }
+        else if ( pkg.equals( "" ) )
+        {
             pkg = dir.getName();
-        } else {
+        }
+        else
+        {
             pkg = pkg + "." + dir.getName();
         }
 
-        if (found)
-            result.add(pkg);
+        if ( found )
+            result.add( pkg );
 
-        for (File d : dirs)
-            findSrcPkgs(d, pkg, result);
+        for ( File d : dirs )
+            findSrcPkgs( d, pkg, result );
     }
 
     /**
      * BldBundle
      * 
      */
-    class BldBundle implements IBldBundle {
+    class BldBundle implements IBldBundle
+    {
         private String id;
 
-        public BldBundle(String id) {
+
+        public BldBundle( String id )
+        {
             this.id = id;
         }
 
-        public File resolve(String path) {
-            return BldProject.this.resolve(path);
+
+        public File resolve( String path )
+        {
+            return BldProject.this.resolve( path );
         }
 
-        private String getString(String key) {
-            return config.getString(id, key);
+
+        private String getString( String key )
+        {
+            return config.getString( id, key );
         }
 
-        private List<String> getList(String key) {
-            List<String> list = config.getList(id, key);
+
+        private List<String> getList( String key )
+        {
+            List<String> list = config.getList( id, key );
             return list != null ? list : Collections.<String> emptyList();
         }
 
-        private Map<String, Map<String, String>> getMap(String key) {
-            Map<String, Map<String, String>> map = config.getMap(id, key);
+
+        private Map<String, Map<String, String>> getMap( String key )
+        {
+            Map<String, Map<String, String>> map = config.getMap( id, key );
             return map != null ? map : Collections.<String, Map<String, String>> emptyMap();
         }
 
-        public String getActivator() {
-            return getString(BldConfig.S_ACTIVATOR);
+
+        public String getActivator()
+        {
+            return getString( BldConfig.S_ACTIVATOR );
         }
 
-        public String getId() {
-            String name = getString("id");
+
+        public String getId()
+        {
+            String name = getString( "id" );
             return name != null ? name : id;
         }
 
-        public String getVersion() {
-            String ver = getString(BldConfig.S_VERSION);
-            if (ver == null) {
+
+        public String getVersion()
+        {
+            String ver = getString( BldConfig.S_VERSION );
+            if ( ver == null )
+            {
                 ver = BldProject.this.getVersion();
             }
             return ver;
         }
 
-        public String getSymbolicName() {
-            String name = getString(BldConfig.S_SYM_NAME);
+
+        public String getSymbolicName()
+        {
+            String name = getString( BldConfig.S_SYM_NAME );
             return name != null ? name : getId();
         }
 
-        public List<IPackageExport> getExports() {
+
+        public List<IPackageExport> getExports()
+        {
             ArrayList<IPackageExport> list = new ArrayList<IPackageExport>();
-            Map<String, Map<String, String>> exports = getMap(BldConfig.M_EXPORTS);
+            Map<String, Map<String, String>> exports = getMap( BldConfig.M_EXPORTS );
 
-            if (exports != null) {
-                for (String name : exports.keySet()) {
-                    Map<String, String> attrs = exports.get(name);
+            if ( exports != null )
+            {
+                for ( String name : exports.keySet() )
+                {
+                    Map<String, String> attrs = exports.get( name );
                     PackageExport pkgExport = new PackageExport();
-                    pkgExport.setPackageName(name);
+                    pkgExport.setPackageName( name );
 
-                    String version = attrs.get(BldAttr.VERSION_ATTRIBUTE);
+                    String version = attrs.get( BldAttr.VERSION_ATTRIBUTE );
                     // only default export version from local packages
-                    if (version == null
-                            && (getSourcePkgs().isEmpty() || getSourcePkgs().contains(name))) {
+                    if ( version == null && ( getSourcePkgs().isEmpty() || getSourcePkgs().contains( name ) ) )
+                    {
                         version = getVersion();
                     }
 
-                    if (version != null)
-                        pkgExport.setVersion(new Version(version));
+                    if ( version != null )
+                        pkgExport.setVersion( new Version( version ) );
 
-                    list.add(pkgExport);
+                    list.add( pkgExport );
                 }
             }
 
             return list;
         }
 
-        public List<IPackageImport> getImports() {
+
+        public List<IPackageImport> getImports()
+        {
             ArrayList<IPackageImport> list = new ArrayList<IPackageImport>();
 
-            for (IPackageImport import1 : getRequirements().childrenOfType(IPackageImport.class)) {
-                list.add(import1);
+            for ( IPackageImport import1 : getRequirements().childrenOfType( IPackageImport.class ) )
+            {
+                list.add( import1 );
             }
 
             return list;
         }
 
-        public List<IRequiredBundle> getRequires() {
+
+        public List<IRequiredBundle> getRequires()
+        {
             ArrayList<IRequiredBundle> list = new ArrayList<IRequiredBundle>();
-            list.addAll(Arrays.asList(getRequirements().childrenOfType(IRequiredBundle.class)));
+            list.addAll( Arrays.asList( getRequirements().childrenOfType( IRequiredBundle.class ) ) );
 
-            for (IBldBundle bundle : getBundles()) {
+            for ( IBldBundle bundle : getBundles() )
+            {
                 IRequiredBundle fh = bundle.getFragmentHost();
-                if (fh != null)
-                    list.remove(fh);
+                if ( fh != null )
+                    list.remove( fh );
             }
 
             return list;
         }
 
-        public IRequiredBundle getFragmentHost() {
+
+        public IRequiredBundle getFragmentHost()
+        {
             IRequiredBundle fragment = null;
-            Map<String, Map<String, String>> fragments = getMap(BldConfig.M_FRAGMENT);
-            if (fragments != null) {
-                for (String name : fragments.keySet()) {
-                    Map<String, String> attr = fragments.get(name);
-                    String versions = attr.isEmpty() ? null : attr.get(BldAttr.VERSION_ATTRIBUTE);
+            Map<String, Map<String, String>> fragments = getMap( BldConfig.M_FRAGMENT );
+            if ( fragments != null )
+            {
+                for ( String name : fragments.keySet() )
+                {
+                    Map<String, String> attr = fragments.get( name );
+                    String versions = attr.isEmpty() ? null : attr.get( BldAttr.VERSION_ATTRIBUTE );
                     fragment = new RequiredBundle();
-                    fragment.setSymbolicName(name);
-                    fragment.setVersions(VersionRange.parseVersionRange(versions));
+                    fragment.setSymbolicName( name );
+                    fragment.setVersions( VersionRange.parseVersionRange( versions ) );
                     break;
                 }
             }
@@ -773,50 +954,67 @@
             return fragment;
         }
 
-        public Map<String, Map<String, String>> getLibs() {
-            Map<String, Map<String, String>> libs = getMap(BldConfig.M_LIBS);
-            return (libs != null) ? libs : Collections.<String, Map<String, String>> emptyMap();
+
+        public Map<String, Map<String, String>> getLibs()
+        {
+            Map<String, Map<String, String>> libs = getMap( BldConfig.M_LIBS );
+            return ( libs != null ) ? libs : Collections.<String, Map<String, String>> emptyMap();
         }
 
-        public List<String> getContents() {
-            return getList(BldConfig.L_CONTENTS);
+
+        public List<String> getContents()
+        {
+            return getList( BldConfig.L_CONTENTS );
         }
 
-        public List<String> getDownloadContents() {
-            return getList(BldConfig.L_DL_CONTENTS);
+
+        public List<String> getDownloadContents()
+        {
+            return getList( BldConfig.L_DL_CONTENTS );
         }
 
-        public List<String> getComposites() {
+
+        public List<String> getComposites()
+        {
             ArrayList<String> list = new ArrayList<String>();
-            for (String composite : getList(BldConfig.L_COMPOSITES)) {
-                list.add(composite);
+            for ( String composite : getList( BldConfig.L_COMPOSITES ) )
+            {
+                list.add( composite );
             }
 
             return list;
         }
 
-        public Map<String, String> getResources() {
-            HashMap<String, String> map = new HashMap<String, String>();
-            List<String> resources = getList(BldConfig.L_RESOURCES);
 
-            if (resources != null) {
-                for (String resource : resources) {
-                    String[] paths = resource.split("=", 2);
-                    String fsPath = (paths.length > 1 ? paths[1] : "");
-                    map.put(paths[0], fsPath);
+        public Map<String, String> getResources()
+        {
+            HashMap<String, String> map = new HashMap<String, String>();
+            List<String> resources = getList( BldConfig.L_RESOURCES );
+
+            if ( resources != null )
+            {
+                for ( String resource : resources )
+                {
+                    String[] paths = resource.split( "=", 2 );
+                    String fsPath = ( paths.length > 1 ? paths[1] : "" );
+                    map.put( paths[0], fsPath );
                 }
             }
             return map;
         }
 
-        public Properties getHeaders() {
-            Properties headers = config.getProps(id, BldConfig.P_HEADER);
+
+        public Properties getHeaders()
+        {
+            Properties headers = config.getProps( id, BldConfig.P_HEADER );
             return headers;
         }
 
     }
 
-    public long getLastModified() {
+
+    public long getLastModified()
+    {
         return lastModified;
     }
 
diff --git a/sigil/common/core/src/org/apache/felix/sigil/config/BldUtil.java b/sigil/common/core/src/org/apache/felix/sigil/config/BldUtil.java
index 211b63d..fd02745 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/config/BldUtil.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/config/BldUtil.java
@@ -19,14 +19,17 @@
 
 package org.apache.felix.sigil.config;
 
+
 import java.util.Map;
 import java.util.Properties;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+
 // taken from Newton Launcher
 
-public class BldUtil {
+public class BldUtil
+{
     /**
      * expands property references embedded in strings. Each occurrence of ${name} is replaced with the value of
      * p.getProperty("name"); If the property is not set, then the original reference, is returned as follows "?<name>".
@@ -54,72 +57,86 @@
      *      with word as the message.
      * </pre>
      */
-    public static String expand(String s, Properties p) {
+    public static String expand( String s, Properties p )
+    {
         // regex to match property references e.g. ${name}
         // TODO this is very simplistic, so strings to be expanded should not
         // contain $ or }, except where substitution is expected.
-	// Update: propRef regex now allows substitutions to contain $,
-	// e.g. where a Windows ${user.name} is $Admin or similar.
-        final Pattern propRef = Pattern.compile("\\$\\{(((\\$[^\\{\\}])|[^\\$\\}])+\\$?)\\}");
-        final Pattern backslash = Pattern.compile("\\\\");
-        final Pattern dollar = Pattern.compile("\\$");
+        // Update: propRef regex now allows substitutions to contain $,
+        // e.g. where a Windows ${user.name} is $Admin or similar.
+        final Pattern propRef = Pattern.compile( "\\$\\{(((\\$[^\\{\\}])|[^\\$\\}])+\\$?)\\}" );
+        final Pattern backslash = Pattern.compile( "\\\\" );
+        final Pattern dollar = Pattern.compile( "\\$" );
 
-        if (s == null) {
+        if ( s == null )
+        {
             return null;
         }
 
-        if (s.indexOf("${") == -1) { // shortcut if no expansions
+        if ( s.indexOf( "${" ) == -1 )
+        { // shortcut if no expansions
             return s;
         }
 
-        for (int i = 0; i < 20; i++) { // avoids self-referencing expansions
+        for ( int i = 0; i < 20; i++ )
+        { // avoids self-referencing expansions
             // System.out.println("XXX expand[" + i + "] = [" + s + "]");
-            Matcher matcher = propRef.matcher(s);
+            Matcher matcher = propRef.matcher( s );
 
-            if (!matcher.find()) {
+            if ( !matcher.find() )
+            {
                 // replace unmatched items
-                s = s.replaceAll("\\Q??[\\E", "\\${");
-                s = s.replaceAll("\\Q??]\\E", "}");
+                s = s.replaceAll( "\\Q??[\\E", "\\${" );
+                s = s.replaceAll( "\\Q??]\\E", "}" );
                 // debug("expanded: " + s);
-                if (s.indexOf("${") != -1) {
-                    throw new RuntimeException("Can't expand: " + s);
+                if ( s.indexOf( "${" ) != -1 )
+                {
+                    throw new RuntimeException( "Can't expand: " + s );
                 }
                 return s;
             }
 
-            String key = matcher.group(1);
-            String[] keydef = key.split(":[=+-?@]", 2);
+            String key = matcher.group( 1 );
+            String[] keydef = key.split( ":[=+-?@]", 2 );
             String replace;
 
-            if (keydef.length != 2) {
-                replace = key.length() == 0 ? null : p.getProperty(key);
+            if ( keydef.length != 2 )
+            {
+                replace = key.length() == 0 ? null : p.getProperty( key );
             }
-            else {
-                replace = keydef[0].length() == 0 ? null : p.getProperty(keydef[0]);
+            else
+            {
+                replace = keydef[0].length() == 0 ? null : p.getProperty( keydef[0] );
 
-                if (replace != null && (replace.length() == 0 || replace.indexOf("${") != -1)) {
+                if ( replace != null && ( replace.length() == 0 || replace.indexOf( "${" ) != -1 ) )
+                {
                     // don't want unexpanded replacement, as it may stop ${...:-default}
                     replace = null;
                 }
 
-                if (key.indexOf(":+") != -1) {
-                    replace = ((replace == null) ? "" : keydef[1]);
+                if ( key.indexOf( ":+" ) != -1 )
+                {
+                    replace = ( ( replace == null ) ? "" : keydef[1] );
                 }
-                else if (replace == null) {
+                else if ( replace == null )
+                {
                     replace = keydef[1];
 
-                    if (key.indexOf(":?") != -1) {
+                    if ( key.indexOf( ":?" ) != -1 )
+                    {
                         String msg = "${" + keydef[0] + ":?" + keydef[1] + "} property not set";
-                        throw new RuntimeException(msg);
+                        throw new RuntimeException( msg );
                     }
 
-                    if (key.indexOf(":=") != -1) {
-                        p.setProperty(keydef[0], keydef[1]);
+                    if ( key.indexOf( ":=" ) != -1 )
+                    {
+                        p.setProperty( keydef[0], keydef[1] );
                     }
                 }
             }
 
-            if (replace == null) {
+            if ( replace == null )
+            {
                 // TODO: this is a hack to avoid looping on unmatched references
                 // should really leave unchanged and process rest of string.
                 // We use "]" as delimiter to avoid non-matched "}"
@@ -138,23 +155,27 @@
             // to
             // escape literal characters in the replacement string.
             // escape any \ or $ in replacement string
-            replace = backslash.matcher(replace).replaceAll("\\\\\\\\");
-            replace = dollar.matcher(replace).replaceAll("\\\\\\$");
+            replace = backslash.matcher( replace ).replaceAll( "\\\\\\\\" );
+            replace = dollar.matcher( replace ).replaceAll( "\\\\\\$" );
 
-            s = s.replaceAll("\\Q${" + key + "}\\E", replace);
+            s = s.replaceAll( "\\Q${" + key + "}\\E", replace );
         }
 
-        throw new RuntimeException("expand: loop expanding: " + s);
+        throw new RuntimeException( "expand: loop expanding: " + s );
     }
 
-    public static String expand(String s) {
+
+    public static String expand( String s )
+    {
         final Map<String, String> env = System.getenv();
 
-        return expand(s, new Properties() {
-            public String getProperty(String name) {
-                return System.getProperty(name, env.get(name));
+        return expand( s, new Properties()
+        {
+            public String getProperty( String name )
+            {
+                return System.getProperty( name, env.get( name ) );
             }
-        });
+        } );
     }
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/config/IBldProject.java b/sigil/common/core/src/org/apache/felix/sigil/config/IBldProject.java
index e66cc19..4790779 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/config/IBldProject.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/config/IBldProject.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.config;
 
+
 import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
@@ -32,176 +33,211 @@
 import org.apache.felix.sigil.model.osgi.IPackageImport;
 import org.apache.felix.sigil.model.osgi.IRequiredBundle;
 
-public interface IBldProject {
-	
-	static final String PROJECT_FILE = "sigil.properties";
-	static final String PROJECT_DEFAULTS = "../sigil-defaults.properties";
-	
-	void save() throws IOException;
-	
-	void saveAs(File path) throws IOException;
-	
-	void saveTo(OutputStream out) throws IOException;
-	
-	/**
-	 * gets default package version ranges.
-	 */
-	Properties getDefaultPackageVersions();
-	
-	/**
-	 * gets default package version range for named package.
-	 * Also handles wildcards in defaults.
-	 */
-	String getDefaultPackageVersion(String name);
-	
-	/**
-	 * get project options.
-	 */
-	Properties getOptions();
-	
-	/**
-	 * get project version.
-	 */
-	String getVersion();
-	
-	/**
-	 * gets dependencies (Package-Import and Require-Bundle) needed to compile.
-	 */
-	IBundleModelElement getDependencies();
-	
-	/**
-	 * gets project source directories.
-	 * This is a convenient way to specify bundle contents
-	 * when the project doesn't contains multiple bundles.
-	 */
-	List<String> getSourceDirs();
-	
-	/**
-	 * gets the list of packages represented by getSourceDirs().
-	 * @throws IOException 
-	 */
-	List<String> getSourcePkgs();
-	
-	/**
-	 * gets bundle ids.
-	 */
-	List<String> getBundleIds();
-	
-	/**
-	 * gets bundles.
-	 */
-	List<IBldBundle> getBundles();
-	
-	/**
-	 * convert specified bundle to SigilBundle.
-	 */
-	ISigilBundle getSigilBundle(String id);
-	
-	/**
-	 * convert SigilBundle to specified bundle.
-	 */
-	void setSigilBundle(String id, ISigilBundle sb);
-	
-	/**
-	 * converts default bundle to SigilBundle.
-	 */
-	ISigilBundle getDefaultBundle();
-	
-	/**
-	 * converts SigilBundle to default bundle.
-	 */
-	void setDefaultBundle(ISigilBundle sb);
-	
-	/**
-	 * resolves a relative path against the project file location.
-	 */
-	File resolve(String path);
-	
-	/**
-	 * gets the last modification date of the project file.
-	 */
-	long getLastModified();
-	
-	interface IBldBundle {
-		/**
-		 * gets bundle activator
-		 */
-		String getActivator();
-		
-		/**
-		 * gets bundle id within project.
-		 */
-		String getId();
-		
-		/**
-		 * gets bundle version.
-		 */
-		String getVersion();
-		
-		/**
-		 * gets the Bundle-SymbolicName.
-		 */
-		String getSymbolicName();
 
-		/**
-		 * gets bundles export-packages.
-		 */
-		List<IPackageExport> getExports();
-		
-		/**
-		 * gets project import-packages. 
-		 */
-		List<IPackageImport> getImports();
-		
-		/**
-		 * gets project require-bundles. 
-		 */
-		List<IRequiredBundle> getRequires();
-		
-		/**
-		 * get bundle fragment-host. 
-		 */
-		IRequiredBundle getFragmentHost();
-		
-		/**
-		 * gets bundle libs. 
-		 */
-		Map<String, Map<String, String>> getLibs();
-	
-		/**
-		 * gets the bundle contents
-		 * @return list of package patterns.
-		 */
-		List<String> getContents();
-		
-		/**
-		 * gets the bundle's associated dljar contents.
-		 * This is a convenience which avoids having to define another bundle
-		 * just for the dljar, which is then added to the parent bundle.
-		 * @return list of package patterns.
-		 */
-		List<String> getDownloadContents();
-	
-		/**
-		 * gets SCA composites.
-		 */
-		List<String> getComposites();
-		
-		/**
-		 * gets the additional resources.
-		 * @return map with key as path in bundle, value as path in file system.
-		 * Paths are resolved relative to location of project file and also from classpath.
-		 */
-		Map<String,String> getResources();
-		
-		/**
-		 * gets additional bundle headers.
-		 */
-		Properties getHeaders();
-		
-		/**
-		 * resolves a relative path against the project file location.
-		 */
-		File resolve(String path);
-	}
+public interface IBldProject
+{
+
+    static final String PROJECT_FILE = "sigil.properties";
+    static final String PROJECT_DEFAULTS = "../sigil-defaults.properties";
+
+
+    void save() throws IOException;
+
+
+    void saveAs( File path ) throws IOException;
+
+
+    void saveTo( OutputStream out ) throws IOException;
+
+
+    /**
+     * gets default package version ranges.
+     */
+    Properties getDefaultPackageVersions();
+
+
+    /**
+     * gets default package version range for named package.
+     * Also handles wildcards in defaults.
+     */
+    String getDefaultPackageVersion( String name );
+
+
+    /**
+     * get project options.
+     */
+    Properties getOptions();
+
+
+    /**
+     * get project version.
+     */
+    String getVersion();
+
+
+    /**
+     * gets dependencies (Package-Import and Require-Bundle) needed to compile.
+     */
+    IBundleModelElement getDependencies();
+
+
+    /**
+     * gets project source directories.
+     * This is a convenient way to specify bundle contents
+     * when the project doesn't contains multiple bundles.
+     */
+    List<String> getSourceDirs();
+
+
+    /**
+     * gets the list of packages represented by getSourceDirs().
+     * @throws IOException 
+     */
+    List<String> getSourcePkgs();
+
+
+    /**
+     * gets bundle ids.
+     */
+    List<String> getBundleIds();
+
+
+    /**
+     * gets bundles.
+     */
+    List<IBldBundle> getBundles();
+
+
+    /**
+     * convert specified bundle to SigilBundle.
+     */
+    ISigilBundle getSigilBundle( String id );
+
+
+    /**
+     * convert SigilBundle to specified bundle.
+     */
+    void setSigilBundle( String id, ISigilBundle sb );
+
+
+    /**
+     * converts default bundle to SigilBundle.
+     */
+    ISigilBundle getDefaultBundle();
+
+
+    /**
+     * converts SigilBundle to default bundle.
+     */
+    void setDefaultBundle( ISigilBundle sb );
+
+
+    /**
+     * resolves a relative path against the project file location.
+     */
+    File resolve( String path );
+
+
+    /**
+     * gets the last modification date of the project file.
+     */
+    long getLastModified();
+
+    interface IBldBundle
+    {
+        /**
+         * gets bundle activator
+         */
+        String getActivator();
+
+
+        /**
+         * gets bundle id within project.
+         */
+        String getId();
+
+
+        /**
+         * gets bundle version.
+         */
+        String getVersion();
+
+
+        /**
+         * gets the Bundle-SymbolicName.
+         */
+        String getSymbolicName();
+
+
+        /**
+         * gets bundles export-packages.
+         */
+        List<IPackageExport> getExports();
+
+
+        /**
+         * gets project import-packages. 
+         */
+        List<IPackageImport> getImports();
+
+
+        /**
+         * gets project require-bundles. 
+         */
+        List<IRequiredBundle> getRequires();
+
+
+        /**
+         * get bundle fragment-host. 
+         */
+        IRequiredBundle getFragmentHost();
+
+
+        /**
+         * gets bundle libs. 
+         */
+        Map<String, Map<String, String>> getLibs();
+
+
+        /**
+         * gets the bundle contents
+         * @return list of package patterns.
+         */
+        List<String> getContents();
+
+
+        /**
+         * gets the bundle's associated dljar contents.
+         * This is a convenience which avoids having to define another bundle
+         * just for the dljar, which is then added to the parent bundle.
+         * @return list of package patterns.
+         */
+        List<String> getDownloadContents();
+
+
+        /**
+         * gets SCA composites.
+         */
+        List<String> getComposites();
+
+
+        /**
+         * gets the additional resources.
+         * @return map with key as path in bundle, value as path in file system.
+         * Paths are resolved relative to location of project file and also from classpath.
+         */
+        Map<String, String> getResources();
+
+
+        /**
+         * gets additional bundle headers.
+         */
+        Properties getHeaders();
+
+
+        /**
+         * resolves a relative path against the project file location.
+         */
+        File resolve( String path );
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/config/IRepositoryConfig.java b/sigil/common/core/src/org/apache/felix/sigil/config/IRepositoryConfig.java
index b3a7d0c..57567b6 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/config/IRepositoryConfig.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/config/IRepositoryConfig.java
@@ -19,18 +19,22 @@
 
 package org.apache.felix.sigil.config;
 
+
 import java.util.Map;
 import java.util.Properties;
 
-public interface IRepositoryConfig {
-	static final String REPOSITORY_PROVIDER = "provider";
-	static final String REPOSITORY_LEVEL = "level";
 
-	/**
-	 * get properties with which to instantiate repositories.
-	 * The key REPOSITORY_PROVIDER will be set to the fully qualified class name of the IRepositoryProvider.
-	 * The key REPOSITORY_LEVEL indicates repository search order.
-	 * @return
-	 */
-	Map<String,Properties> getRepositoryConfig();
+public interface IRepositoryConfig
+{
+    static final String REPOSITORY_PROVIDER = "provider";
+    static final String REPOSITORY_LEVEL = "level";
+
+
+    /**
+     * get properties with which to instantiate repositories.
+     * The key REPOSITORY_PROVIDER will be set to the fully qualified class name of the IRepositoryProvider.
+     * The key REPOSITORY_LEVEL indicates repository search order.
+     * @return
+     */
+    Map<String, Properties> getRepositoryConfig();
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/BldCore.java b/sigil/common/core/src/org/apache/felix/sigil/core/BldCore.java
index 6488e9f..6041ea4 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/BldCore.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/BldCore.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core;
 
+
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -46,53 +47,64 @@
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 
-public class BldCore implements BundleActivator {
-	private static LicenseManager licenceManager = new LicenseManager();
-	
-	private static final Logger log = Logger.getLogger(BldCore.class.getName());
 
-	public static void error(String string, Throwable e) {
-		// TODO 
-		log.log( Level.WARNING, string, e );
-	}
+public class BldCore implements BundleActivator
+{
+    private static LicenseManager licenceManager = new LicenseManager();
 
-	public static void error(String string) {
-		log.log( Level.WARNING, string );
-	}
+    private static final Logger log = Logger.getLogger( BldCore.class.getName() );
 
-	public static ILicenseManager getLicenseManager() {
-		return licenceManager;
-	}
 
-	public void start(BundleContext context) throws Exception {
-		init();
-	}
-	
-	public static void init() throws Exception {
-		String uri = "http://sigil.codecauldron.org/xml/sigil-namespace";
-		ModelElementFactory.getInstance().register(ISigilBundle.class,
-				SigilBundle.class, "bundle", "sigil", uri);
-		ModelElementFactory.getInstance().register(IDownloadJar.class,
-				DownloadJar.class, "download", "sigil", uri);
-		ModelElementFactory.getInstance().register(ILibrary.class,
-				Library.class, "library", "sigil", uri);
-		ModelElementFactory.getInstance().register(ILibraryImport.class,
-				LibraryImport.class, "library-import", "sigil", uri);
-		
-		// osgi elements
-		ModelElementFactory.getInstance().register(IBundleModelElement.class,
-				BundleModelElement.class, "bundle", null, null);
-		ModelElementFactory.getInstance().register(IPackageExport.class,
-				PackageExport.class, "package.export", null, null);
-		ModelElementFactory.getInstance().register(IPackageImport.class,
-				PackageImport.class, "package.import", null, null);
-		ModelElementFactory.getInstance().register(IRequiredBundle.class,
-				RequiredBundle.class, "required.bundle", null, null);
-	}
+    public static void error( String string, Throwable e )
+    {
+        // TODO 
+        log.log( Level.WARNING, string, e );
+    }
 
-	public void stop(BundleContext context) throws Exception {
-		// TODO Auto-generated method stub
-		
-	}
+
+    public static void error( String string )
+    {
+        log.log( Level.WARNING, string );
+    }
+
+
+    public static ILicenseManager getLicenseManager()
+    {
+        return licenceManager;
+    }
+
+
+    public void start( BundleContext context ) throws Exception
+    {
+        init();
+    }
+
+
+    public static void init() throws Exception
+    {
+        String uri = "http://sigil.codecauldron.org/xml/sigil-namespace";
+        ModelElementFactory.getInstance().register( ISigilBundle.class, SigilBundle.class, "bundle", "sigil", uri );
+        ModelElementFactory.getInstance().register( IDownloadJar.class, DownloadJar.class, "download", "sigil", uri );
+        ModelElementFactory.getInstance().register( ILibrary.class, Library.class, "library", "sigil", uri );
+        ModelElementFactory.getInstance().register( ILibraryImport.class, LibraryImport.class, "library-import",
+            "sigil", uri );
+
+        // osgi elements
+        ModelElementFactory.getInstance().register( IBundleModelElement.class, BundleModelElement.class, "bundle",
+            null, null );
+        ModelElementFactory.getInstance().register( IPackageExport.class, PackageExport.class, "package.export", null,
+            null );
+        ModelElementFactory.getInstance().register( IPackageImport.class, PackageImport.class, "package.import", null,
+            null );
+        ModelElementFactory.getInstance().register( IRequiredBundle.class, RequiredBundle.class, "required.bundle",
+            null, null );
+    }
+
+
+    public void stop( BundleContext context ) throws Exception
+    {
+        // TODO Auto-generated method stub
+
+    }
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/license/LicenseManager.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/license/LicenseManager.java
index 236a78f..3de3346 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/license/LicenseManager.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/license/LicenseManager.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core.internal.license;
 
+
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Set;
@@ -27,43 +28,55 @@
 import org.apache.felix.sigil.core.licence.ILicenseManager;
 import org.apache.felix.sigil.core.licence.ILicensePolicy;
 
-public class LicenseManager implements ILicenseManager {
 
-	private HashMap<String, Pattern> licenses = new HashMap<String, Pattern>();
-	private HashMap<String, LicensePolicy> policies = new HashMap<String, LicensePolicy>();
-	private LicensePolicy defaultPolicy = new LicensePolicy(this);
-	
-	public void addLicense(String name, Pattern pattern) {
-		licenses.put( name, pattern );
-	}
+public class LicenseManager implements ILicenseManager
+{
 
-	public void removeLicense(String name) {
-		licenses.remove(name);
-	}
+    private HashMap<String, Pattern> licenses = new HashMap<String, Pattern>();
+    private HashMap<String, LicensePolicy> policies = new HashMap<String, LicensePolicy>();
+    private LicensePolicy defaultPolicy = new LicensePolicy( this );
 
-	public Set<String> getLicenseNames() {
-		return Collections.unmodifiableSet(licenses.keySet());
-	}
 
-	public Pattern getLicensePattern(String name) {
-		return licenses.get( name );
-	}
+    public void addLicense( String name, Pattern pattern )
+    {
+        licenses.put( name, pattern );
+    }
 
-	public ILicensePolicy getDefaultPolicy() {
-		return defaultPolicy;
-	}
 
-	//public ILicensePolicy getPolicy(ISigilProjectModel project) {
-	//	synchronized( policies ) {
-	//		LicensePolicy p = policies.get(project.getName());
-	//		
-	//		if ( p == null ) {
-	//			p = new LicensePolicy(this, project);
-	//			policies.put( project.getName(), p );
-	//		}
-	//		
-	//		return p;
-	//	}
-	//}
+    public void removeLicense( String name )
+    {
+        licenses.remove( name );
+    }
+
+
+    public Set<String> getLicenseNames()
+    {
+        return Collections.unmodifiableSet( licenses.keySet() );
+    }
+
+
+    public Pattern getLicensePattern( String name )
+    {
+        return licenses.get( name );
+    }
+
+
+    public ILicensePolicy getDefaultPolicy()
+    {
+        return defaultPolicy;
+    }
+
+    //public ILicensePolicy getPolicy(ISigilProjectModel project) {
+    //	synchronized( policies ) {
+    //		LicensePolicy p = policies.get(project.getName());
+    //		
+    //		if ( p == null ) {
+    //			p = new LicensePolicy(this, project);
+    //			policies.put( project.getName(), p );
+    //		}
+    //		
+    //		return p;
+    //	}
+    //}
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/license/LicensePolicy.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/license/LicensePolicy.java
index 19645ba..c813ad8 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/license/LicensePolicy.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/license/LicensePolicy.java
@@ -19,35 +19,48 @@
 
 package org.apache.felix.sigil.core.internal.license;
 
+
 import org.apache.felix.sigil.core.licence.ILicensePolicy;
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
 import org.eclipse.core.runtime.IProgressMonitor;
 
-public class LicensePolicy implements ILicensePolicy {
 
-	private LicenseManager licenseManager;
-	
-	public LicensePolicy(LicenseManager licenseManager) {
-		this.licenseManager = licenseManager;
-	}
+public class LicensePolicy implements ILicensePolicy
+{
 
-	public boolean accept(ISigilBundle bundle) {
-		return true;
-	}
+    private LicenseManager licenseManager;
 
-	public void addAllowed(String licenseName) {
-		// TODO Auto-generated method stub
-		
-	}
 
-	public void removeAllowed(String licenseName) {
-		// TODO Auto-generated method stub
-		
-	}
+    public LicensePolicy( LicenseManager licenseManager )
+    {
+        this.licenseManager = licenseManager;
+    }
 
-	public void save(IProgressMonitor monitor) {
-		// TODO Auto-generated method stub
-		
-	}
+
+    public boolean accept( ISigilBundle bundle )
+    {
+        return true;
+    }
+
+
+    public void addAllowed( String licenseName )
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void removeAllowed( String licenseName )
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void save( IProgressMonitor monitor )
+    {
+        // TODO Auto-generated method stub
+
+    }
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/DownloadJar.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/DownloadJar.java
index 349d71a..37f3fc2 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/DownloadJar.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/DownloadJar.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core.internal.model.eclipse;
 
+
 import java.util.HashSet;
 import java.util.Set;
 
@@ -26,29 +27,41 @@
 import org.apache.felix.sigil.model.eclipse.IDownloadJar;
 import org.eclipse.core.runtime.IPath;
 
-public class DownloadJar extends AbstractCompoundModelElement implements IDownloadJar {
 
-	private static final long serialVersionUID = 1L;
+public class DownloadJar extends AbstractCompoundModelElement implements IDownloadJar
+{
 
-	private Set<IPath> entries = new HashSet<IPath>();
-	
-	public DownloadJar() {
-		super("RMI Classpath Download Jar");
-	}
-	
-	public void addEntry(IPath entry) {
-		entries.add( entry );
-	}
-	
-	public void removeEntry(IPath entry) {
-		entries.remove( entry );
-	}
-	
-	public Set<IPath> getEntrys() {
-		return entries;
-	}
+    private static final long serialVersionUID = 1L;
 
-	public void clearEntries() {
-		entries.clear();
-	}
+    private Set<IPath> entries = new HashSet<IPath>();
+
+
+    public DownloadJar()
+    {
+        super( "RMI Classpath Download Jar" );
+    }
+
+
+    public void addEntry( IPath entry )
+    {
+        entries.add( entry );
+    }
+
+
+    public void removeEntry( IPath entry )
+    {
+        entries.remove( entry );
+    }
+
+
+    public Set<IPath> getEntrys()
+    {
+        return entries;
+    }
+
+
+    public void clearEntries()
+    {
+        entries.clear();
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/Library.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/Library.java
index 97b3d2f..8b20955 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/Library.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/Library.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core.internal.model.eclipse;
 
+
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
@@ -29,58 +30,82 @@
 import org.apache.felix.sigil.model.osgi.IRequiredBundle;
 import org.osgi.framework.Version;
 
-public class Library extends AbstractCompoundModelElement implements ILibrary {
 
-	private static final long serialVersionUID = 1L;
-	
-	private String name;
-	private Version version;
-	private Set<IRequiredBundle> bundles;
-	private Set<IPackageImport> imports;
-	
-	public Library() {
-		super("Library");
-		bundles = new HashSet<IRequiredBundle>();
-		imports = new HashSet<IPackageImport>();
-	}
-	
-	public void addBundle(IRequiredBundle bundle) {
-		bundles.add(bundle);
-	}
+public class Library extends AbstractCompoundModelElement implements ILibrary
+{
 
-	public void addImport(IPackageImport pi) {
-		imports.add(pi);
-	}
+    private static final long serialVersionUID = 1L;
 
-	public Collection<IRequiredBundle> getBundles() {
-		return bundles;
-	}
+    private String name;
+    private Version version;
+    private Set<IRequiredBundle> bundles;
+    private Set<IPackageImport> imports;
 
-	public Collection<IPackageImport> getImports() {
-		return imports;
-	}
 
-	public String getName() {
-		return name;
-	}
+    public Library()
+    {
+        super( "Library" );
+        bundles = new HashSet<IRequiredBundle>();
+        imports = new HashSet<IPackageImport>();
+    }
 
-	public Version getVersion() {
-		return version;
-	}
 
-	public void removeBundle(IRequiredBundle bundle) {
-		bundles.remove(bundle);
-	}
+    public void addBundle( IRequiredBundle bundle )
+    {
+        bundles.add( bundle );
+    }
 
-	public void removeImport(IPackageImport pi) {
-		imports.remove(pi);
-	}
 
-	public void setName(String name) {
-		this.name = name;
-	}
+    public void addImport( IPackageImport pi )
+    {
+        imports.add( pi );
+    }
 
-	public void setVersion(Version version) {
-		this.version = version;
-	}
+
+    public Collection<IRequiredBundle> getBundles()
+    {
+        return bundles;
+    }
+
+
+    public Collection<IPackageImport> getImports()
+    {
+        return imports;
+    }
+
+
+    public String getName()
+    {
+        return name;
+    }
+
+
+    public Version getVersion()
+    {
+        return version;
+    }
+
+
+    public void removeBundle( IRequiredBundle bundle )
+    {
+        bundles.remove( bundle );
+    }
+
+
+    public void removeImport( IPackageImport pi )
+    {
+        imports.remove( pi );
+    }
+
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+
+    public void setVersion( Version version )
+    {
+        this.version = version;
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/LibraryImport.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/LibraryImport.java
index d44196d..2c48601 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/LibraryImport.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/LibraryImport.java
@@ -19,35 +19,48 @@
 
 package org.apache.felix.sigil.core.internal.model.eclipse;
 
+
 import org.apache.felix.sigil.model.AbstractModelElement;
 import org.apache.felix.sigil.model.common.VersionRange;
 import org.apache.felix.sigil.model.eclipse.ILibraryImport;
 
-public class LibraryImport extends AbstractModelElement implements ILibraryImport {
 
-	private static final long serialVersionUID = 1L;
+public class LibraryImport extends AbstractModelElement implements ILibraryImport
+{
 
-	public LibraryImport() {
-		super("Library Import");
-	}
+    private static final long serialVersionUID = 1L;
 
-	private String libraryName;
-	private VersionRange range = VersionRange.ANY_VERSION;
-	
-	public String getLibraryName() {
-		return libraryName;
-	}
 
-	public VersionRange getVersions() {
-		return range;
-	}
+    public LibraryImport()
+    {
+        super( "Library Import" );
+    }
 
-	public void setLibraryName(String name) {
-		this.libraryName = name;
-	}
+    private String libraryName;
+    private VersionRange range = VersionRange.ANY_VERSION;
 
-	public void setVersions(VersionRange range) {
-		this.range = range;
-	}
+
+    public String getLibraryName()
+    {
+        return libraryName;
+    }
+
+
+    public VersionRange getVersions()
+    {
+        return range;
+    }
+
+
+    public void setLibraryName( String name )
+    {
+        this.libraryName = name;
+    }
+
+
+    public void setVersions( VersionRange range )
+    {
+        this.range = range;
+    }
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/SigilBundle.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/SigilBundle.java
index 1166e16..ee038c0 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/SigilBundle.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/eclipse/SigilBundle.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core.internal.model.eclipse;
 
+
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -45,14 +46,16 @@
 import org.eclipse.core.runtime.SubMonitor;
 import org.osgi.framework.Version;
 
+
 /**
  * @author dave
  *
  */
-public class SigilBundle extends AbstractCompoundModelElement implements ISigilBundle {
-    
-	private static final long serialVersionUID = 1L;
-	
+public class SigilBundle extends AbstractCompoundModelElement implements ISigilBundle
+{
+
+    private static final long serialVersionUID = 1L;
+
     private IBundleModelElement bundle;
     private IDownloadJar download;
     private Set<IPath> sourcePaths;
@@ -63,13 +66,15 @@
     private Set<String> dlPackages;
     private IPath location;
 
-	private IPath sourcePathLocation;
-	private IPath licencePathLocation;
-	private IPath sourceRootPath;
-	private String bundleHost;
-    
-    public SigilBundle() {
-    	super( "Sigil Bundle" );
+    private IPath sourcePathLocation;
+    private IPath licencePathLocation;
+    private IPath sourceRootPath;
+    private String bundleHost;
+
+
+    public SigilBundle()
+    {
+        super( "Sigil Bundle" );
         sourcePaths = new HashSet<IPath>();
         libraryPaths = new HashSet<IPath>();
         composites = new HashSet<ISCAComposite>();
@@ -77,280 +82,410 @@
         packages = new HashSet<String>();
         dlPackages = new HashSet<String>();
     }
-            
-    public void synchronize(IProgressMonitor monitor) throws IOException {
-    	SubMonitor progress = SubMonitor.convert(monitor, 100);
-    	progress.subTask("Synchronizing " + bundle.getSymbolicName() + " binary" );
-    	sync(location, bundle.getUpdateLocation(), progress.newChild(45));
-    	
-    	try {
-        	progress.subTask("Synchronizing " + bundle.getSymbolicName() + " source" );
-			sync(sourcePathLocation, bundle.getSourceLocation(), progress.newChild(45));
-		} catch (IOException e) {
-			BldCore.error( "Failed to download source for " + bundle.getSymbolicName() + " " + bundle.getVersion(), e.getCause() );
-		}
-		
-    	try {
-        	progress.subTask("Synchronizing " + bundle.getSymbolicName() + " licence" );
-			sync(licencePathLocation, bundle.getLicenseURI(), progress.newChild(10));
-		} catch (IOException e) {
-			BldCore.error( "Failed to download licence for " + bundle.getSymbolicName() + " " + bundle.getVersion(), e.getCause() );
-		}
-	}
 
-	public boolean isSynchronized() {
-		return location == null || location.toFile().exists();
-	}
 
-	private static void sync(IPath local, URI remote, IProgressMonitor monitor) throws IOException {
-		try {
-	    	if ( local != null && !local.toFile().exists() ) {
-	    		if ( remote != null ) {
-	    			URL url = remote.toURL();
-	    			URLConnection connection = url.openConnection();
-	    			int contentLength = connection.getContentLength();
-	    			
-	    			monitor.beginTask("Downloading from " + url.getHost(), contentLength);
-	    			
-	    			InputStream in = null;
-	    			OutputStream out = null;
-	    			try {
-	    				URLConnection conn = url.openConnection();
-	    				if ( conn instanceof HttpURLConnection ) {
-	    					HttpURLConnection http = (HttpURLConnection) conn;
-	    					http.setConnectTimeout(10000);
-	    					http.setReadTimeout(5000);
-	    				}
-	    				in = conn.getInputStream();
-	    				File f = local.toFile();
-	    				f.getParentFile().mkdirs();
-	    				out = new FileOutputStream( f );
-	    				stream( in, out, monitor );
-	    			}
-	    			finally {
-	    				if ( in != null ) {
-	    					in.close();
-	    				}
-	    				if ( out != null ) {
-	    					out.close();
-	    				}
-	    				monitor.done();
-	    			}
-	    		}
-	    	}
-		}
-		catch (IOException e) {
-			local.toFile().delete();
-			throw e;
-		}
-	}
+    public void synchronize( IProgressMonitor monitor ) throws IOException
+    {
+        SubMonitor progress = SubMonitor.convert( monitor, 100 );
+        progress.subTask( "Synchronizing " + bundle.getSymbolicName() + " binary" );
+        sync( location, bundle.getUpdateLocation(), progress.newChild( 45 ) );
 
-	private static void stream(InputStream in, OutputStream out, IProgressMonitor monitor) throws IOException {
-		byte[] b = new byte[1024];
-		for ( ;; ) {
-			if ( monitor.isCanceled() ) {
-				throw new InterruptedIOException( "User canceled download" );
-			}
-			int r = in.read( b );
-			if ( r == -1 ) break;
-			out.write(b, 0, r);
-			monitor.worked(r);
-		}
-		
-		out.flush();
-	}
-    
-    public IBundleModelElement getBundleInfo() {
+        try
+        {
+            progress.subTask( "Synchronizing " + bundle.getSymbolicName() + " source" );
+            sync( sourcePathLocation, bundle.getSourceLocation(), progress.newChild( 45 ) );
+        }
+        catch ( IOException e )
+        {
+            BldCore.error( "Failed to download source for " + bundle.getSymbolicName() + " " + bundle.getVersion(), e
+                .getCause() );
+        }
+
+        try
+        {
+            progress.subTask( "Synchronizing " + bundle.getSymbolicName() + " licence" );
+            sync( licencePathLocation, bundle.getLicenseURI(), progress.newChild( 10 ) );
+        }
+        catch ( IOException e )
+        {
+            BldCore.error( "Failed to download licence for " + bundle.getSymbolicName() + " " + bundle.getVersion(), e
+                .getCause() );
+        }
+    }
+
+
+    public boolean isSynchronized()
+    {
+        return location == null || location.toFile().exists();
+    }
+
+
+    private static void sync( IPath local, URI remote, IProgressMonitor monitor ) throws IOException
+    {
+        try
+        {
+            if ( local != null && !local.toFile().exists() )
+            {
+                if ( remote != null )
+                {
+                    URL url = remote.toURL();
+                    URLConnection connection = url.openConnection();
+                    int contentLength = connection.getContentLength();
+
+                    monitor.beginTask( "Downloading from " + url.getHost(), contentLength );
+
+                    InputStream in = null;
+                    OutputStream out = null;
+                    try
+                    {
+                        URLConnection conn = url.openConnection();
+                        if ( conn instanceof HttpURLConnection )
+                        {
+                            HttpURLConnection http = ( HttpURLConnection ) conn;
+                            http.setConnectTimeout( 10000 );
+                            http.setReadTimeout( 5000 );
+                        }
+                        in = conn.getInputStream();
+                        File f = local.toFile();
+                        f.getParentFile().mkdirs();
+                        out = new FileOutputStream( f );
+                        stream( in, out, monitor );
+                    }
+                    finally
+                    {
+                        if ( in != null )
+                        {
+                            in.close();
+                        }
+                        if ( out != null )
+                        {
+                            out.close();
+                        }
+                        monitor.done();
+                    }
+                }
+            }
+        }
+        catch ( IOException e )
+        {
+            local.toFile().delete();
+            throw e;
+        }
+    }
+
+
+    private static void stream( InputStream in, OutputStream out, IProgressMonitor monitor ) throws IOException
+    {
+        byte[] b = new byte[1024];
+        for ( ;; )
+        {
+            if ( monitor.isCanceled() )
+            {
+                throw new InterruptedIOException( "User canceled download" );
+            }
+            int r = in.read( b );
+            if ( r == -1 )
+                break;
+            out.write( b, 0, r );
+            monitor.worked( r );
+        }
+
+        out.flush();
+    }
+
+
+    public IBundleModelElement getBundleInfo()
+    {
         return bundle;
     }
-    
-    public void setBundleInfo(IBundleModelElement bundle) {
-    	if ( bundle == null ) {
-    		if (this.bundle != null) {
-    			this.bundle.setParent(null);
-    		}
-    	}
-    	else {
-    		bundle.setParent(this);
-    	}
+
+
+    public void setBundleInfo( IBundleModelElement bundle )
+    {
+        if ( bundle == null )
+        {
+            if ( this.bundle != null )
+            {
+                this.bundle.setParent( null );
+            }
+        }
+        else
+        {
+            bundle.setParent( this );
+        }
         this.bundle = bundle;
     }
-    
-    public IDownloadJar getDownloadJar() {
-    	return download;
+
+
+    public IDownloadJar getDownloadJar()
+    {
+        return download;
     }
-    
-    public void setDownloadJar(IDownloadJar download) {
-    	this.download = download;
+
+
+    public void setDownloadJar( IDownloadJar download )
+    {
+        this.download = download;
     }
-        
-    public void addLibraryPath( IPath path ) {
+
+
+    public void addLibraryPath( IPath path )
+    {
         libraryPaths.add( path );
     }
-    
-    public void removeLibraryPath( IPath path ) {
+
+
+    public void removeLibraryPath( IPath path )
+    {
         libraryPaths.remove( path );
     }
-    
-    public Set<IPath> getLibraryPaths() {
+
+
+    public Set<IPath> getLibraryPaths()
+    {
         return libraryPaths;
     }
-    
-    public void addSourcePath( IPath path ) {
+
+
+    public void addSourcePath( IPath path )
+    {
         sourcePaths.add( path );
     }
-    
-    public void removeSourcePath( IPath path ) {
+
+
+    public void removeSourcePath( IPath path )
+    {
         sourcePaths.remove( path );
     }
-    
-    public Set<IPath> getSourcePaths() {
+
+
+    public Set<IPath> getSourcePaths()
+    {
         return sourcePaths;
     }
 
-    public void clearSourcePaths() {
-    	sourcePaths.clear();
-	}
-    
-	public void addComposite(ISCAComposite composite) {
-        composites.add( composite );
-        composite.setParent(this);
+
+    public void clearSourcePaths()
+    {
+        sourcePaths.clear();
     }
 
-    public Set<ISCAComposite> getComposites() {
+
+    public void addComposite( ISCAComposite composite )
+    {
+        composites.add( composite );
+        composite.setParent( this );
+    }
+
+
+    public Set<ISCAComposite> getComposites()
+    {
         return composites;
     }
 
-    public void removeComposite(ISCAComposite composite) {
-        if ( composites.remove( composite ) ) {
-        	composite.setParent(null);
+
+    public void removeComposite( ISCAComposite composite )
+    {
+        if ( composites.remove( composite ) )
+        {
+            composite.setParent( null );
         }
     }
-	public void addClasspathEntry(String encodedClasspath) {
-		classpath.add( encodedClasspath.trim() );
-	}
-	
-	public Set<String> getClasspathEntrys() {
-		return classpath;
-	}
-	
-	public void removeClasspathEntry(String encodedClasspath) {
-		classpath.remove(encodedClasspath.trim());
-	}
 
-	public IPath getLocation() {
-		return location;
-	}
-	
-	public void setLocation(IPath location) {
-		this.location = location;
-	}
-	
-	public IPath getSourcePathLocation() {
-		return sourcePathLocation;
-	}
-	public IPath getSourceRootPath() {
-		return sourceRootPath;
-	}
-	public void setSourcePathLocation(IPath location) {
-		this.sourcePathLocation = location;
-	}
-	public void setSourceRootPath(IPath location) {
-		this.sourceRootPath = location;
-	}
-		
-	@Override
-	public String toString() {
-		return "SigilBundle[" + (getBundleInfo() == null ? null : (getBundleInfo().getSymbolicName() + ":" + getBundleInfo().getVersion())) + "]";
-	}
-	
-	@Override
-	public boolean equals(Object obj) {
-		if ( obj == null ) return false;
-		if ( obj == this ) return true;
-		
-		if ( obj instanceof SigilBundle) {
-			return obj.toString().equals( toString() );
-		}
-		
-		return false;
-	}
-	@Override
-	public int hashCode() {
-		return 31 * toString().hashCode();
-	}
 
-	public IPath getLicencePathLocation() {
-		return licencePathLocation;
-	}
+    public void addClasspathEntry( String encodedClasspath )
+    {
+        classpath.add( encodedClasspath.trim() );
+    }
 
-	public void setLicencePathLocation(IPath licencePathLocation) {
-		this.licencePathLocation = licencePathLocation;
-	}
-    
-	public String getFragmentHost() {
-		return bundleHost;
-	}
 
-	public void setFragmentHost(String symbolicName) {
-		this.bundleHost = symbolicName;
-	}
+    public Set<String> getClasspathEntrys()
+    {
+        return classpath;
+    }
 
-	public String getElementName() {
-		return bundle.getSymbolicName();
-	}
 
-	public Version getVersion() {
-		return bundle.getVersion();
-	}
+    public void removeClasspathEntry( String encodedClasspath )
+    {
+        classpath.remove( encodedClasspath.trim() );
+    }
 
-	public void setVersion(Version version) {
-		this.bundle.setVersion(version);
-	}
-	
-	public String getSymbolicName() {
-		return bundle.getSymbolicName();
-	}
 
-	public Set<String> getPackages() {
-		return packages;
-	}
+    public IPath getLocation()
+    {
+        return location;
+    }
 
-	public void addPackage(String pkg) {
-		packages.add(pkg);
-	}
 
-	public boolean removePackage(String pkg) {
-		return packages.remove(pkg);
-	}
-	
-	public Set<String> getDownloadPackages() {
-		return dlPackages;
-	}
+    public void setLocation( IPath location )
+    {
+        this.location = location;
+    }
 
-	public void addDownloadPackage(String pkg) {
-		dlPackages.add(pkg);
-	}
 
-	public boolean removeDownloadPackage(String pkg) {
-		return dlPackages.remove(pkg);
-	}
+    public IPath getSourcePathLocation()
+    {
+        return sourcePathLocation;
+    }
 
-	public IPackageExport findExport(String packageName) {
-		for ( IPackageExport e : bundle.getExports() ) {
-			if ( packageName.equals( e.getPackageName() ) ) {
-				return e;
-			}
-		}
-		return null;
-	}
 
-	public IPackageImport findImport(String packageName) {
-		for ( IPackageImport i : bundle.getImports() ) {
-			if ( packageName.equals( i.getPackageName() ) ) {
-				return i;
-			}
-		}
-		return null;
-	}
+    public IPath getSourceRootPath()
+    {
+        return sourceRootPath;
+    }
+
+
+    public void setSourcePathLocation( IPath location )
+    {
+        this.sourcePathLocation = location;
+    }
+
+
+    public void setSourceRootPath( IPath location )
+    {
+        this.sourceRootPath = location;
+    }
+
+
+    @Override
+    public String toString()
+    {
+        return "SigilBundle["
+            + ( getBundleInfo() == null ? null : ( getBundleInfo().getSymbolicName() + ":" + getBundleInfo()
+                .getVersion() ) ) + "]";
+    }
+
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        if ( obj == null )
+            return false;
+        if ( obj == this )
+            return true;
+
+        if ( obj instanceof SigilBundle )
+        {
+            return obj.toString().equals( toString() );
+        }
+
+        return false;
+    }
+
+
+    @Override
+    public int hashCode()
+    {
+        return 31 * toString().hashCode();
+    }
+
+
+    public IPath getLicencePathLocation()
+    {
+        return licencePathLocation;
+    }
+
+
+    public void setLicencePathLocation( IPath licencePathLocation )
+    {
+        this.licencePathLocation = licencePathLocation;
+    }
+
+
+    public String getFragmentHost()
+    {
+        return bundleHost;
+    }
+
+
+    public void setFragmentHost( String symbolicName )
+    {
+        this.bundleHost = symbolicName;
+    }
+
+
+    public String getElementName()
+    {
+        return bundle.getSymbolicName();
+    }
+
+
+    public Version getVersion()
+    {
+        return bundle.getVersion();
+    }
+
+
+    public void setVersion( Version version )
+    {
+        this.bundle.setVersion( version );
+    }
+
+
+    public String getSymbolicName()
+    {
+        return bundle.getSymbolicName();
+    }
+
+
+    public Set<String> getPackages()
+    {
+        return packages;
+    }
+
+
+    public void addPackage( String pkg )
+    {
+        packages.add( pkg );
+    }
+
+
+    public boolean removePackage( String pkg )
+    {
+        return packages.remove( pkg );
+    }
+
+
+    public Set<String> getDownloadPackages()
+    {
+        return dlPackages;
+    }
+
+
+    public void addDownloadPackage( String pkg )
+    {
+        dlPackages.add( pkg );
+    }
+
+
+    public boolean removeDownloadPackage( String pkg )
+    {
+        return dlPackages.remove( pkg );
+    }
+
+
+    public IPackageExport findExport( String packageName )
+    {
+        for ( IPackageExport e : bundle.getExports() )
+        {
+            if ( packageName.equals( e.getPackageName() ) )
+            {
+                return e;
+            }
+        }
+        return null;
+    }
+
+
+    public IPackageImport findImport( String packageName )
+    {
+        for ( IPackageImport i : bundle.getImports() )
+        {
+            if ( packageName.equals( i.getPackageName() ) )
+            {
+                return i;
+            }
+        }
+        return null;
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/BundleModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/BundleModelElement.java
index b2270f8..4a8cc44 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/BundleModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/BundleModelElement.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core.internal.model.osgi;
 
+
 import java.net.URI;
 import java.util.Collection;
 import java.util.Collections;
@@ -34,7 +35,9 @@
 import org.apache.felix.sigil.model.osgi.IRequiredBundle;
 import org.osgi.framework.Version;
 
-public class BundleModelElement extends AbstractCompoundModelElement implements IBundleModelElement {
+
+public class BundleModelElement extends AbstractCompoundModelElement implements IBundleModelElement
+{
     /**
      * 
      */
@@ -59,13 +62,15 @@
     private String vendor;
     private String contactAddress;
     private String copyright;
-    
+
     // internal values
     private String activator;
     private Set<ILibraryImport> libraries;
 
-    public BundleModelElement() {
-    	super( "OSGi Bundle" );
+
+    public BundleModelElement()
+    {
+        super( "OSGi Bundle" );
         this.imports = new HashSet<IPackageImport>();
         this.exports = new HashSet<IPackageExport>();
         this.requires = new HashSet<IRequiredBundle>();
@@ -73,223 +78,321 @@
         this.libraries = new HashSet<ILibraryImport>();
     }
 
-	public String getActivator() {
-		return activator;
-	}
 
-	public void setActivator(String activator) {
-		this.activator = activator;
-	}
-	
-	public void addLibraryImport(ILibraryImport library) {
-    	libraries.add(library);
-	}
+    public String getActivator()
+    {
+        return activator;
+    }
 
-	public Set<ILibraryImport> getLibraryImports() {
-		return libraries;
-	}
 
-	public void removeLibraryImport(ILibraryImport library) {
-		libraries.remove(library);
-	}
+    public void setActivator( String activator )
+    {
+        this.activator = activator;
+    }
 
-    public String getCategory() {
+
+    public void addLibraryImport( ILibraryImport library )
+    {
+        libraries.add( library );
+    }
+
+
+    public Set<ILibraryImport> getLibraryImports()
+    {
+        return libraries;
+    }
+
+
+    public void removeLibraryImport( ILibraryImport library )
+    {
+        libraries.remove( library );
+    }
+
+
+    public String getCategory()
+    {
         return category;
     }
 
-    public void setCategory(String category) {
+
+    public void setCategory( String category )
+    {
         this.category = category;
     }
 
-    public String getContactAddress() {
+
+    public String getContactAddress()
+    {
         return contactAddress;
     }
 
-    public void setContactAddress(String contactAddress) {
+
+    public void setContactAddress( String contactAddress )
+    {
         this.contactAddress = contactAddress;
     }
 
-    public String getCopyright() {
+
+    public String getCopyright()
+    {
         return copyright;
     }
 
-    public void setCopyright(String copyright) {
+
+    public void setCopyright( String copyright )
+    {
         this.copyright = copyright;
     }
 
-    public URI getDocURI() {
+
+    public URI getDocURI()
+    {
         return docURI;
     }
 
-    public void setDocURI(URI docURI) {
+
+    public void setDocURI( URI docURI )
+    {
         this.docURI = docURI;
     }
 
-    public Set<IPackageExport> getExports() {
+
+    public Set<IPackageExport> getExports()
+    {
         return exports;
     }
 
-    public void addExport(IPackageExport packageExport) {
-        exports.add(packageExport);
-        packageExport.setParent(this);
+
+    public void addExport( IPackageExport packageExport )
+    {
+        exports.add( packageExport );
+        packageExport.setParent( this );
     }
 
-    public void removeExport(IPackageExport packageExport) {
-    	if ( exports.remove(packageExport) ) {
-    		packageExport.setParent(null);
-    	}
+
+    public void removeExport( IPackageExport packageExport )
+    {
+        if ( exports.remove( packageExport ) )
+        {
+            packageExport.setParent( null );
+        }
     }
-    
-    public Set<IPackageImport> getImports() {
+
+
+    public Set<IPackageImport> getImports()
+    {
         return imports;
     }
 
-    public void addImport(IPackageImport packageImport) {
-        imports.add(packageImport);
-        packageImport.setParent(this);
+
+    public void addImport( IPackageImport packageImport )
+    {
+        imports.add( packageImport );
+        packageImport.setParent( this );
     }
-    
-    public void removeImport(IPackageImport packageImport) {
-    	if ( imports.remove( packageImport ) ) {
-    		packageImport.setParent(null);
-    	}
+
+
+    public void removeImport( IPackageImport packageImport )
+    {
+        if ( imports.remove( packageImport ) )
+        {
+            packageImport.setParent( null );
+        }
     }
-    
-    public Set<IRequiredBundle> getRequiredBundles() {
+
+
+    public Set<IRequiredBundle> getRequiredBundles()
+    {
         return requires;
     }
 
-    public void addRequiredBundle(IRequiredBundle bundle) {
+
+    public void addRequiredBundle( IRequiredBundle bundle )
+    {
         requires.add( bundle );
-        bundle.setParent(this);
+        bundle.setParent( this );
     }
 
-    public void removeRequiredBundle(IRequiredBundle bundle) {
-    	if ( requires.remove(bundle) ) {
-    		bundle.setParent(null);
-    	}
+
+    public void removeRequiredBundle( IRequiredBundle bundle )
+    {
+        if ( requires.remove( bundle ) )
+        {
+            bundle.setParent( null );
+        }
     }
-    
-    public URI getLicenseURI() {
+
+
+    public URI getLicenseURI()
+    {
         return licenseURI;
     }
 
-    public void setLicenseURI(URI licenseURI) {
+
+    public void setLicenseURI( URI licenseURI )
+    {
         this.licenseURI = licenseURI;
     }
 
-    public URI getSourceLocation() {
+
+    public URI getSourceLocation()
+    {
         return sourceLocation;
     }
 
-    public void setSourceLocation(URI sourceLocation) {
+
+    public void setSourceLocation( URI sourceLocation )
+    {
         this.sourceLocation = sourceLocation;
     }
 
-    public String getSymbolicName() {
+
+    public String getSymbolicName()
+    {
         return symbolicName;
     }
 
-    public void setSymbolicName(String symbolicName) {
+
+    public void setSymbolicName( String symbolicName )
+    {
         this.symbolicName = symbolicName == null ? null : symbolicName.intern();
     }
 
-    public URI getUpdateLocation() {
+
+    public URI getUpdateLocation()
+    {
         return updateLocation;
     }
 
-    public void setUpdateLocation(URI updateLocation) {
+
+    public void setUpdateLocation( URI updateLocation )
+    {
         this.updateLocation = updateLocation;
     }
 
-    public String getVendor() {
-    		return vendor;
+
+    public String getVendor()
+    {
+        return vendor;
     }
 
-    public void setVendor(String vendor) {
+
+    public void setVendor( String vendor )
+    {
         this.vendor = vendor;
     }
 
-    public Version getVersion() {
-    	return version;
+
+    public Version getVersion()
+    {
+        return version;
     }
 
-    public void setVersion(Version version) {
+
+    public void setVersion( Version version )
+    {
         this.version = version == null ? Version.emptyVersion : version;
     }
 
-    public void checkValid() throws InvalidModelException {
-        if (symbolicName == null)
-            throw new InvalidModelException(this, "Bundle symbolic name not set");
+
+    public void checkValid() throws InvalidModelException
+    {
+        if ( symbolicName == null )
+            throw new InvalidModelException( this, "Bundle symbolic name not set" );
     }
 
-    public BundleModelElement clone() {
-        BundleModelElement bd = (BundleModelElement) super.clone();
+
+    public BundleModelElement clone()
+    {
+        BundleModelElement bd = ( BundleModelElement ) super.clone();
 
         bd.imports = new HashSet<IPackageImport>();
         bd.exports = new HashSet<IPackageExport>();
         bd.requires = new HashSet<IRequiredBundle>();
-        
-        for (IPackageImport pi : imports ) {
-            bd.imports.add((IPackageImport) pi.clone());
+
+        for ( IPackageImport pi : imports )
+        {
+            bd.imports.add( ( IPackageImport ) pi.clone() );
         }
 
-        for (IPackageExport pe : exports ) {
-            bd.exports.add((IPackageExport) pe.clone());
+        for ( IPackageExport pe : exports )
+        {
+            bd.exports.add( ( IPackageExport ) pe.clone() );
         }
-        
-        for ( IRequiredBundle rb : requires ) {
-            bd.requires.add((IRequiredBundle) rb.clone());
+
+        for ( IRequiredBundle rb : requires )
+        {
+            bd.requires.add( ( IRequiredBundle ) rb.clone() );
         }
 
         return bd;
     }
 
-    public String toString() {
+
+    public String toString()
+    {
         StringBuffer buf = new StringBuffer();
 
-        buf.append("BundleModelElement[");
-        buf.append(symbolicName);
-        buf.append(", ");
-        buf.append(version);
-        buf.append("]");
+        buf.append( "BundleModelElement[" );
+        buf.append( symbolicName );
+        buf.append( ", " );
+        buf.append( version );
+        buf.append( "]" );
 
         return buf.toString();
     }
 
-	public String getName() {
-		return name;
-	}
 
-	public void setName(String name) {
-		this.name = name;
-	}
+    public String getName()
+    {
+        return name;
+    }
 
-	public String getDescription() {
-		return description;
-	}
 
-	public void setDescription(String description) {
-		this.description = description;
-	}
+    public void setName( String name )
+    {
+        this.name = name;
+    }
 
-	public void addClasspath(String path) {
-		classpathElements.add( path );
-	}
 
-	public Collection<String> getClasspaths() {
-		return classpathElements.isEmpty() ? Collections.singleton( "." ) : classpathElements;
-	}
+    public String getDescription()
+    {
+        return description;
+    }
 
-	public void removeClasspath(String path) {
-		classpathElements.remove( path );
-	}
 
-	public IRequiredBundle getFragmentHost() {
-		return fragmentHost;
-	}
+    public void setDescription( String description )
+    {
+        this.description = description;
+    }
 
-	public void setFragmentHost(IRequiredBundle fragmentHost) {
-		this.fragmentHost = fragmentHost;
-	}
+
+    public void addClasspath( String path )
+    {
+        classpathElements.add( path );
+    }
+
+
+    public Collection<String> getClasspaths()
+    {
+        return classpathElements.isEmpty() ? Collections.singleton( "." ) : classpathElements;
+    }
+
+
+    public void removeClasspath( String path )
+    {
+        classpathElements.remove( path );
+    }
+
+
+    public IRequiredBundle getFragmentHost()
+    {
+        return fragmentHost;
+    }
+
+
+    public void setFragmentHost( IRequiredBundle fragmentHost )
+    {
+        this.fragmentHost = fragmentHost;
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageExport.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageExport.java
index 5af3251..70051ee 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageExport.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageExport.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core.internal.model.osgi;
 
+
 import java.util.Collection;
 import java.util.HashSet;
 
@@ -27,97 +28,138 @@
 import org.apache.felix.sigil.model.osgi.IPackageExport;
 import org.osgi.framework.Version;
 
-public class PackageExport extends AbstractModelElement implements IPackageExport {
 
-	private static final long serialVersionUID = 1L;
+public class PackageExport extends AbstractModelElement implements IPackageExport
+{
 
-	private String name;
+    private static final long serialVersionUID = 1L;
+
+    private String name;
     private Version version;
     private HashSet<String> uses = new HashSet<String>();
 
-	public PackageExport() {
-		super("OSGi Package Export");
-	}
 
-    public String getPackageName() {
+    public PackageExport()
+    {
+        super( "OSGi Package Export" );
+    }
+
+
+    public String getPackageName()
+    {
         return name;
     }
 
-    public void setPackageName(String packageName) {
+
+    public void setPackageName( String packageName )
+    {
         this.name = packageName;
     }
 
-    public Version getVersion() {
-    	Version result;
-        if(version != null) {
-        	result = version;
-        } else {
-	        ISigilBundle owningBundle = getAncestor(ISigilBundle.class);
-	        if(owningBundle == null) {
-	        	result = Version.emptyVersion;
-	        } else {
-	        	result = owningBundle.getVersion();
-	        }
+
+    public Version getVersion()
+    {
+        Version result;
+        if ( version != null )
+        {
+            result = version;
+        }
+        else
+        {
+            ISigilBundle owningBundle = getAncestor( ISigilBundle.class );
+            if ( owningBundle == null )
+            {
+                result = Version.emptyVersion;
+            }
+            else
+            {
+                result = owningBundle.getVersion();
+            }
         }
         return result;
     }
-    
-    public Version getRawVersion() {
-    	return version;
+
+
+    public Version getRawVersion()
+    {
+        return version;
     }
 
-    public void setVersion(Version version) {
+
+    public void setVersion( Version version )
+    {
         this.version = version; // == null ? Version.emptyVersion : version;
     }
-    
-    public void addUse(String use) {
-    	uses.add(use);
-	}
 
-	public Collection<String> getUses() {
-		return uses;
-	}
 
-	public void removeUse(String use) {
-		uses.remove(use);
-	}
-
-	@Override
-    public String toString() {
-    	return "PackageExport[" + name + ":" + version + ":uses=" + uses + "]";
+    public void addUse( String use )
+    {
+        uses.add( use );
     }
 
-	public void setUses(Collection<String> uses) {
-		this.uses.clear();
-		this.uses.addAll(uses);
-	}
 
-	public int compareTo(IPackageExport o) {
-		int i = name.compareTo(o.getPackageName());
-		
-		if ( i == 0 ) {
-			i = compareVersion(o.getVersion());
-		}
-		
-		return i;
-	}
+    public Collection<String> getUses()
+    {
+        return uses;
+    }
 
-	private int compareVersion(Version other) {
-		if ( version == null ) {
-			if ( other == null ) {
-				return 0;
-			}
-			else {
-				return 1;
-			}
-		}
-		else {
-			if ( other == null ) {
-				return -1;
-			}
-			else {
-				return version.compareTo(other);
-			}
-		}
-	}	
+
+    public void removeUse( String use )
+    {
+        uses.remove( use );
+    }
+
+
+    @Override
+    public String toString()
+    {
+        return "PackageExport[" + name + ":" + version + ":uses=" + uses + "]";
+    }
+
+
+    public void setUses( Collection<String> uses )
+    {
+        this.uses.clear();
+        this.uses.addAll( uses );
+    }
+
+
+    public int compareTo( IPackageExport o )
+    {
+        int i = name.compareTo( o.getPackageName() );
+
+        if ( i == 0 )
+        {
+            i = compareVersion( o.getVersion() );
+        }
+
+        return i;
+    }
+
+
+    private int compareVersion( Version other )
+    {
+        if ( version == null )
+        {
+            if ( other == null )
+            {
+                return 0;
+            }
+            else
+            {
+                return 1;
+            }
+        }
+        else
+        {
+            if ( other == null )
+            {
+                return -1;
+            }
+            else
+            {
+                return version.compareTo( other );
+            }
+        }
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageImport.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageImport.java
index 15db4c2..adf6314 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageImport.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/PackageImport.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core.internal.model.osgi;
 
+
 import org.apache.felix.sigil.model.AbstractModelElement;
 import org.apache.felix.sigil.model.IModelElement;
 import org.apache.felix.sigil.model.InvalidModelException;
@@ -26,138 +27,189 @@
 import org.apache.felix.sigil.model.osgi.IPackageExport;
 import org.apache.felix.sigil.model.osgi.IPackageImport;
 
-public class PackageImport extends AbstractModelElement implements IPackageImport {
 
-	private static final long serialVersionUID = 1L;
-	
-	private String name;
+public class PackageImport extends AbstractModelElement implements IPackageImport
+{
+
+    private static final long serialVersionUID = 1L;
+
+    private String name;
     private VersionRange versions = VersionRange.ANY_VERSION;
-    
+
     // resolution directive
     private boolean optional;
-	private boolean dependency = true;
-	private OSGiImport osgiImport = OSGiImport.AUTO;
+    private boolean dependency = true;
+    private OSGiImport osgiImport = OSGiImport.AUTO;
 
-    public PackageImport() {
-    	super( "OSGi Package Import" );
+
+    public PackageImport()
+    {
+        super( "OSGi Package Import" );
     }
 
-    @Override
-	public void checkValid() throws InvalidModelException {
-    	if ( name == null ) {
-    		throw new InvalidModelException( this, "Package name must be set" );
-    	}
-	}
 
-    public boolean isOptional() {
+    @Override
+    public void checkValid() throws InvalidModelException
+    {
+        if ( name == null )
+        {
+            throw new InvalidModelException( this, "Package name must be set" );
+        }
+    }
+
+
+    public boolean isOptional()
+    {
         return optional;
     }
 
-    public void setOptional(boolean optional) {
+
+    public void setOptional( boolean optional )
+    {
         this.optional = optional;
     }
 
-	public boolean isDependency() {
-		return dependency;
-	}
 
-	public void setDependency(boolean dependency) {
-		this.dependency  = dependency;
-	}
-    
-	public OSGiImport getOSGiImport() {
-		return osgiImport;
-	}
+    public boolean isDependency()
+    {
+        return dependency;
+    }
 
-	public void setOSGiImport(OSGiImport osgiHeader) {
-		this.osgiImport = osgiHeader;
-	}
 
-    public String getPackageName() {
+    public void setDependency( boolean dependency )
+    {
+        this.dependency = dependency;
+    }
+
+
+    public OSGiImport getOSGiImport()
+    {
+        return osgiImport;
+    }
+
+
+    public void setOSGiImport( OSGiImport osgiHeader )
+    {
+        this.osgiImport = osgiHeader;
+    }
+
+
+    public String getPackageName()
+    {
         return name;
     }
 
-    public void setPackageName(String name) {
+
+    public void setPackageName( String name )
+    {
         this.name = name;
     }
 
-    public VersionRange getVersions() {
+
+    public VersionRange getVersions()
+    {
         return versions;
     }
 
-    public void setVersions(VersionRange versions) {
+
+    public void setVersions( VersionRange versions )
+    {
         this.versions = versions == null ? VersionRange.ANY_VERSION : versions;
     }
 
-	@Override
-	public String toString() {
-		return "Package-Import[" + name + ":" + versions + ":" + (optional ? "optional" : "mandatory") + "]";
-	}
 
-	@Override
-	public boolean equals(Object obj) {
-        if (this == obj)
+    @Override
+    public String toString()
+    {
+        return "Package-Import[" + name + ":" + versions + ":" + ( optional ? "optional" : "mandatory" ) + "]";
+    }
+
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
             return true;
-        if (obj == null)
+        if ( obj == null )
             return false;
-        
-		if ( obj instanceof PackageImport ) {
-			PackageImport pi = (PackageImport) obj;
-			return name.equals( pi.name ) && versions.equals( pi.versions ) && optional == pi.optional;
-		}
-		else {
-			return false;
-		}
-	}
 
-	@Override
-	public int hashCode() {
-		int hc = name.hashCode() * versions.hashCode();
-		
-		if ( optional ) {
-			hc *= -1;
-		}
-		
-		return hc;
-	}
+        if ( obj instanceof PackageImport )
+        {
+            PackageImport pi = ( PackageImport ) obj;
+            return name.equals( pi.name ) && versions.equals( pi.versions ) && optional == pi.optional;
+        }
+        else
+        {
+            return false;
+        }
+    }
 
-	public boolean accepts(IModelElement provider) {
-		if ( provider instanceof IPackageExport ) {
-			IPackageExport pe = (IPackageExport) provider;
-			return pe.getPackageName().equals( name ) && versions.contains( pe.getVersion() );
-		}
-		else {
-			return false;
-		}
-	}
 
-	public int compareTo(IPackageImport o) {
-		int i = name.compareTo(o.getPackageName());
-		
-		if ( i == 0 ) {
-			i = compareVersion(o.getVersions());
-		}
-		
-		return i;
-	}
+    @Override
+    public int hashCode()
+    {
+        int hc = name.hashCode() * versions.hashCode();
 
-	private int compareVersion(VersionRange range) {
-		if ( versions == null ) {
-			if ( range == null ) {
-				return 0;
-			}
-			else {
-				return 1;
-			}
-		}
-		else {
-			if ( range == null ) {
-				return -1;
-			}
-			else {
-				return versions.getCeiling().compareTo(range.getCeiling());
-			}
-		}
-	}
+        if ( optional )
+        {
+            hc *= -1;
+        }
+
+        return hc;
+    }
+
+
+    public boolean accepts( IModelElement provider )
+    {
+        if ( provider instanceof IPackageExport )
+        {
+            IPackageExport pe = ( IPackageExport ) provider;
+            return pe.getPackageName().equals( name ) && versions.contains( pe.getVersion() );
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    public int compareTo( IPackageImport o )
+    {
+        int i = name.compareTo( o.getPackageName() );
+
+        if ( i == 0 )
+        {
+            i = compareVersion( o.getVersions() );
+        }
+
+        return i;
+    }
+
+
+    private int compareVersion( VersionRange range )
+    {
+        if ( versions == null )
+        {
+            if ( range == null )
+            {
+                return 0;
+            }
+            else
+            {
+                return 1;
+            }
+        }
+        else
+        {
+            if ( range == null )
+            {
+                return -1;
+            }
+            else
+            {
+                return versions.getCeiling().compareTo( range.getCeiling() );
+            }
+        }
+    }
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/RequiredBundle.java b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/RequiredBundle.java
index 451f241..af41438 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/RequiredBundle.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/internal/model/osgi/RequiredBundle.java
@@ -19,115 +19,156 @@
 
 package org.apache.felix.sigil.core.internal.model.osgi;
 
+
 import org.apache.felix.sigil.model.AbstractModelElement;
 import org.apache.felix.sigil.model.IModelElement;
 import org.apache.felix.sigil.model.common.VersionRange;
 import org.apache.felix.sigil.model.osgi.IBundleModelElement;
 import org.apache.felix.sigil.model.osgi.IRequiredBundle;
 
-public class RequiredBundle extends AbstractModelElement implements IRequiredBundle {
-	private static final long serialVersionUID = 1L;
-	
-	private String symbolicName;
+
+public class RequiredBundle extends AbstractModelElement implements IRequiredBundle
+{
+    private static final long serialVersionUID = 1L;
+
+    private String symbolicName;
     private VersionRange versions = VersionRange.ANY_VERSION;
     private boolean optional;
-    
-	public RequiredBundle() {
-		super("OSGi Bundle Requirement");
-	}
 
-    public String getSymbolicName() {
+
+    public RequiredBundle()
+    {
+        super( "OSGi Bundle Requirement" );
+    }
+
+
+    public String getSymbolicName()
+    {
         return symbolicName;
     }
 
-    public void setSymbolicName(String symbolicName) {
+
+    public void setSymbolicName( String symbolicName )
+    {
         this.symbolicName = symbolicName == null ? null : symbolicName.intern();
     }
 
-    public VersionRange getVersions() {
+
+    public VersionRange getVersions()
+    {
         return versions;
     }
 
-    public void setVersions(VersionRange versions) {
+
+    public void setVersions( VersionRange versions )
+    {
         this.versions = versions == null ? VersionRange.ANY_VERSION : versions;
     }
 
-	public boolean isOptional() {
-		return optional;
-	}
 
-	public void setOptional(boolean optional) {
-		this.optional = optional;
-	}
-	
-	@Override
-	public String toString() {
-		return "RequiredBundle[" + symbolicName + ":" + versions + ":" + (optional ? "optional" : "mandatory") + "]";
-	}
+    public boolean isOptional()
+    {
+        return optional;
+    }
 
-	@Override
-	public boolean equals(Object obj) {
-        if (this == obj)
+
+    public void setOptional( boolean optional )
+    {
+        this.optional = optional;
+    }
+
+
+    @Override
+    public String toString()
+    {
+        return "RequiredBundle[" + symbolicName + ":" + versions + ":" + ( optional ? "optional" : "mandatory" ) + "]";
+    }
+
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
             return true;
-        if (obj == null)
+        if ( obj == null )
             return false;
-        
-		if ( obj instanceof RequiredBundle ) {
-			RequiredBundle rb = (RequiredBundle) obj;
-			return symbolicName.equals( rb.symbolicName ) && versions.equals( rb.versions ) && optional == rb.optional;
-		}
-		else {
-			return false;
-		}
-	}
 
-	@Override
-	public int hashCode() {
-		int hc = symbolicName.hashCode() * versions.hashCode();
-		
-		if ( optional ) {
-			hc *= -1;
-		}
-		
-		return hc;
-	}
+        if ( obj instanceof RequiredBundle )
+        {
+            RequiredBundle rb = ( RequiredBundle ) obj;
+            return symbolicName.equals( rb.symbolicName ) && versions.equals( rb.versions ) && optional == rb.optional;
+        }
+        else
+        {
+            return false;
+        }
+    }
 
-	public boolean accepts(IModelElement provider) {
-		if ( provider instanceof IBundleModelElement ) {
-			IBundleModelElement bndl = (IBundleModelElement) provider;
-			return symbolicName.equals( bndl.getSymbolicName() ) && versions.contains( bndl.getVersion() );
-		}
-		else {
-			return false;
-		}
-	}
-	
-	public int compareTo(IRequiredBundle o) {
-		int i = symbolicName.compareTo(o.getSymbolicName());
-		
-		if ( i == 0 ) {
-			i = compareVersion(o.getVersions());
-		}
-		
-		return i;
-	}
 
-	private int compareVersion(VersionRange range) {
-		if ( versions == null ) {
-			if ( range == null ) {
-				return 0;
-			}
-			else {
-				return 1;
-			}
-		}
-		else {
-			if ( range == null ) {
-				return -1;
-			}
-			else {
-				return versions.getCeiling().compareTo(range.getCeiling());
-			}
-		}
-	}
+    @Override
+    public int hashCode()
+    {
+        int hc = symbolicName.hashCode() * versions.hashCode();
+
+        if ( optional )
+        {
+            hc *= -1;
+        }
+
+        return hc;
+    }
+
+
+    public boolean accepts( IModelElement provider )
+    {
+        if ( provider instanceof IBundleModelElement )
+        {
+            IBundleModelElement bndl = ( IBundleModelElement ) provider;
+            return symbolicName.equals( bndl.getSymbolicName() ) && versions.contains( bndl.getVersion() );
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    public int compareTo( IRequiredBundle o )
+    {
+        int i = symbolicName.compareTo( o.getSymbolicName() );
+
+        if ( i == 0 )
+        {
+            i = compareVersion( o.getVersions() );
+        }
+
+        return i;
+    }
+
+
+    private int compareVersion( VersionRange range )
+    {
+        if ( versions == null )
+        {
+            if ( range == null )
+            {
+                return 0;
+            }
+            else
+            {
+                return 1;
+            }
+        }
+        else
+        {
+            if ( range == null )
+            {
+                return -1;
+            }
+            else
+            {
+                return versions.getCeiling().compareTo( range.getCeiling() );
+            }
+        }
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/licence/ILicenseManager.java b/sigil/common/core/src/org/apache/felix/sigil/core/licence/ILicenseManager.java
index 9fec40c..c78bd16 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/licence/ILicenseManager.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/licence/ILicenseManager.java
@@ -19,14 +19,25 @@
 
 package org.apache.felix.sigil.core.licence;
 
+
 import java.util.Set;
 import java.util.regex.Pattern;
 
-public interface ILicenseManager {
-	void addLicense(String name, Pattern pattern);
-	void removeLicense(String name);
-	Set<String> getLicenseNames();
-	Pattern getLicensePattern(String name);
-	ILicensePolicy getDefaultPolicy();
-	//ILicensePolicy getPolicy(ISigilProjectModel project);
+
+public interface ILicenseManager
+{
+    void addLicense( String name, Pattern pattern );
+
+
+    void removeLicense( String name );
+
+
+    Set<String> getLicenseNames();
+
+
+    Pattern getLicensePattern( String name );
+
+
+    ILicensePolicy getDefaultPolicy();
+    //ILicensePolicy getPolicy(ISigilProjectModel project);
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/licence/ILicensePolicy.java b/sigil/common/core/src/org/apache/felix/sigil/core/licence/ILicensePolicy.java
index b242f02..1180c21 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/licence/ILicensePolicy.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/licence/ILicensePolicy.java
@@ -19,12 +19,21 @@
 
 package org.apache.felix.sigil.core.licence;
 
+
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
 import org.eclipse.core.runtime.IProgressMonitor;
 
-public interface ILicensePolicy {
-	void addAllowed(String licenseName);
-	void removeAllowed(String licenseName);
-	boolean accept(ISigilBundle bundle);
-	void save(IProgressMonitor monitor);
+
+public interface ILicensePolicy
+{
+    void addAllowed( String licenseName );
+
+
+    void removeAllowed( String licenseName );
+
+
+    boolean accept( ISigilBundle bundle );
+
+
+    void save( IProgressMonitor monitor );
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/repository/BundleResolver.java b/sigil/common/core/src/org/apache/felix/sigil/core/repository/BundleResolver.java
index 3c10bea..fcc4c57 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/repository/BundleResolver.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/repository/BundleResolver.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core.repository;
 
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -51,394 +52,529 @@
 import org.eclipse.core.runtime.SubMonitor;
 import org.osgi.framework.Version;
 
-public class BundleResolver implements IBundleResolver {
 
-	private class BundleOrderComparator implements Comparator<ISigilBundle> {
-		private IModelElement requirement;
-		
-		public BundleOrderComparator(IModelElement requirement) {
-			this.requirement = requirement;
-		}
+public class BundleResolver implements IBundleResolver
+{
 
-		public int compare(ISigilBundle o1, ISigilBundle o2) {
-			int c = compareVersions(o1, o2);
-			
-			if ( c == 0 ) {
-				c = compareImports(o1, o2);
-			}
-			
-			return c;
-		}
+    private class BundleOrderComparator implements Comparator<ISigilBundle>
+    {
+        private IModelElement requirement;
 
-		private int compareImports(ISigilBundle o1, ISigilBundle o2) {
-			int c1 = o1.getBundleInfo().getImports().size();
-			int c2 = o2.getBundleInfo().getImports().size();
-			
-			if ( c1 < c2 ) {
-				return -1;
-			}
-			else if ( c2 > c1 ) {
-				return 1;
-			}
-			else {
-				return 0;
-			}
-		}
 
-		private int compareVersions(ISigilBundle o1, ISigilBundle o2) {
-			Version v1 = null;
-			Version v2 = null;
-			if ( requirement instanceof IPackageImport ) {
-				v1 = findExportVersion( (IPackageImport) requirement, o1 );
-				v2 = findExportVersion( (IPackageImport) requirement, o2 );
-			}
-			else if ( requirement instanceof IRequiredBundle ) {
-				v1 = o1.getBundleInfo().getVersion();
-				v2 = o1.getBundleInfo().getVersion();
-			}
-			
-			if ( v1 == null ) {
-				if ( v2 == null ) {
-					return 0;
-				}
-				else {
-					return 1;
-				}
-			}
-			else {
-				if ( v2 == null ) {
-					return -1;
-				}
-				else {
-					return v2.compareTo(v1);
-				}
-			}
-		}
+        public BundleOrderComparator( IModelElement requirement )
+        {
+            this.requirement = requirement;
+        }
 
-		private Version findExportVersion(IPackageImport pi, ISigilBundle o1) {
-			for ( IPackageExport pe : o1.getBundleInfo().getExports() ) {
-				if ( pi.getPackageName().equals( pi.getPackageName() ) ) {
-					return pe.getVersion();
-				}
-			}
-			
-			return null;
-		}
 
-	}
+        public int compare( ISigilBundle o1, ISigilBundle o2 )
+        {
+            int c = compareVersions( o1, o2 );
 
-	private class ResolutionContext {
-		private final IModelElement root;
-		private final ResolutionConfig config;
-		private final IResolutionMonitor monitor;
-		
-		private final Resolution resolution = new Resolution();
-		private final Set<IModelElement> parsed = new HashSet<IModelElement>();
-		private final LinkedList<IModelElement> requirements = new LinkedList<IModelElement>();
-		
-		public ResolutionContext(IModelElement root, ResolutionConfig config, IResolutionMonitor monitor) {
-			this.root = root;
-			this.config = config;
-			this.monitor = monitor;
-		}
+            if ( c == 0 )
+            {
+                c = compareImports( o1, o2 );
+            }
 
-		public void enterModelElement(IModelElement element) {
-			parsed.add(element);
-		}
-		
-		public void exitModelElement(IModelElement element) {
-			parsed.remove(element);
-		}
-		
-		public boolean isNewModelElement(IModelElement element) {
-			return !parsed.contains(element);
-		}
-		
-		public boolean isValid() {
-			return resolution.isSuccess();
-		}
+            return c;
+        }
 
-		public void setValid(boolean valid) {
-			resolution.setSuccess(valid);
-		}
 
-		public ResolutionException newResolutionException() {
-			return new ResolutionException(root, requirements.toArray( new IModelElement[requirements.size()]) );
-		}
+        private int compareImports( ISigilBundle o1, ISigilBundle o2 )
+        {
+            int c1 = o1.getBundleInfo().getImports().size();
+            int c2 = o2.getBundleInfo().getImports().size();
 
-		public void startRequirement(IModelElement element) {
-			requirements.add(element);
-			monitor.startResolution(element);
-		}
-		
-		public void endRequirement(IModelElement element) {
-			ISigilBundle provider = resolution.getProvider(element);
-			
-			setValid( provider != null || isOptional(element) || config.isIgnoreErrors() );
-		
-			if ( isValid() ) {
-				// only clear stack if valid
-				// else use it as an aid to trace errors
-				requirements.remove(element);
-			}
-			
-			monitor.endResolution( element, provider );	
-		}		
-	}
-	
-	private class Resolution implements IResolution {
-		private Map<ISigilBundle, List<IModelElement>> providees = new HashMap<ISigilBundle, List<IModelElement>>();
-		private Map<IModelElement, ISigilBundle> providers = new HashMap<IModelElement, ISigilBundle>();
-		private boolean success = true; // assume success
-		
-		boolean addProvider(IModelElement element, ISigilBundle provider) {
-			providers.put( element, provider );
-			
-			List<IModelElement> requirements = providees.get( provider );
-			
-			boolean isNewProvider = requirements == null;
-			
-			if ( isNewProvider ) {
-				requirements = new ArrayList<IModelElement>();
-				providees.put( provider, requirements );
-			}
-			
-			requirements.add( element );
-			
-			return isNewProvider;
-		}
-		
-		void removeProvider(IModelElement element, ISigilBundle provider) {
-			providers.remove(element);
-			List<IModelElement> e = providees.get(provider);
-			e.remove(element);
-			if ( e.isEmpty() ) {
-				providees.remove(provider);
-			}
-		}
-		
-		void setSuccess(boolean success) {
-			this.success = success;
-		}
+            if ( c1 < c2 )
+            {
+                return -1;
+            }
+            else if ( c2 > c1 )
+            {
+                return 1;
+            }
+            else
+            {
+                return 0;
+            }
+        }
 
-		public boolean isSuccess() {
-			return success;
-		}
-		
-		public ISigilBundle getProvider(IModelElement requirement) {
-			return providers.get(requirement);
-		}
-		
-		public Set<ISigilBundle> getBundles() {
-			return providees.keySet();
-		}
 
-		public List<IModelElement> getMatchedRequirements(ISigilBundle bundle) {
-			return providees.get(bundle);
-		}
-		
-		public boolean isSynchronized() {
-			for ( ISigilBundle b : getBundles() ) {
-				if ( !b.isSynchronized() ) {
-					return false;
-				}
-			}
-			
-			return true;
-		}
-		
-		public void synchronize(IProgressMonitor monitor) {
-			Set<ISigilBundle> bundles = getBundles();
-			SubMonitor progress = SubMonitor.convert(monitor, bundles.size());
-			
-			for ( ISigilBundle b : bundles ) {
-				if ( monitor.isCanceled() ) {
-					break;
-				}
-				
-				try {
-					b.synchronize(progress.newChild(1));
-				} catch (IOException e) {
-					BldCore.error( "Failed to synchronize " + b, e );
-				}
-			}
-		}
-	}
+        private int compareVersions( ISigilBundle o1, ISigilBundle o2 )
+        {
+            Version v1 = null;
+            Version v2 = null;
+            if ( requirement instanceof IPackageImport )
+            {
+                v1 = findExportVersion( ( IPackageImport ) requirement, o1 );
+                v2 = findExportVersion( ( IPackageImport ) requirement, o2 );
+            }
+            else if ( requirement instanceof IRequiredBundle )
+            {
+                v1 = o1.getBundleInfo().getVersion();
+                v2 = o1.getBundleInfo().getVersion();
+            }
 
-	private static final IResolutionMonitor NULL_MONITOR = new IResolutionMonitor() {
-		public void endResolution(IModelElement requirement,
-				ISigilBundle sigilBundle) {
-		}
+            if ( v1 == null )
+            {
+                if ( v2 == null )
+                {
+                    return 0;
+                }
+                else
+                {
+                    return 1;
+                }
+            }
+            else
+            {
+                if ( v2 == null )
+                {
+                    return -1;
+                }
+                else
+                {
+                    return v2.compareTo( v1 );
+                }
+            }
+        }
 
-		public boolean isCanceled() {
-			return false;
-		}
 
-		public void startResolution(IModelElement requirement) {
-		}		
-	};
-	
-	private IRepositoryManager repositoryManager;
-	
-	public BundleResolver(IRepositoryManager repositoryManager) {
-		this.repositoryManager = repositoryManager;
-	}
+        private Version findExportVersion( IPackageImport pi, ISigilBundle o1 )
+        {
+            for ( IPackageExport pe : o1.getBundleInfo().getExports() )
+            {
+                if ( pi.getPackageName().equals( pi.getPackageName() ) )
+                {
+                    return pe.getVersion();
+                }
+            }
 
-	public IResolution resolve(IModelElement element, ResolutionConfig config, IResolutionMonitor monitor) throws ResolutionException {
-		if ( monitor == null ) {
-			monitor = NULL_MONITOR;
-		}
-		ResolutionContext ctx = new ResolutionContext(element, config, monitor);
+            return null;
+        }
 
-		resolveElement(element, ctx);
-		
-		if ( !ctx.isValid() ) {
-			throw ctx.newResolutionException();
-		}
-		
-		return ctx.resolution;
-	}
+    }
 
-	private void resolveElement(IModelElement element, ResolutionContext ctx) throws ResolutionException {
-		if ( isRequirement(element) ) {
-			resolveRequirement(element, ctx);
-		}
-		
-		if ( ctx.isValid() && element instanceof ICompoundModelElement ) {
-			resolveCompound((ICompoundModelElement) element, ctx);
-		}
-	}
+    private class ResolutionContext
+    {
+        private final IModelElement root;
+        private final ResolutionConfig config;
+        private final IResolutionMonitor monitor;
 
-	private void resolveCompound(ICompoundModelElement compound, ResolutionContext ctx) throws ResolutionException {
-		for ( IModelElement element : compound.children() ) {
-			if ( ctx.isNewModelElement(element) ) {
-				if ( isRequirement(element) ) {
-					resolveRequirement(element, ctx);
-				}
-				else if ( element instanceof ICompoundModelElement ) {
-					if ( !ctx.monitor.isCanceled() ) {
-						ctx.enterModelElement( element );
-						resolveElement((ICompoundModelElement) element, ctx);	
-						ctx.exitModelElement(element);
-					}
-				}
+        private final Resolution resolution = new Resolution();
+        private final Set<IModelElement> parsed = new HashSet<IModelElement>();
+        private final LinkedList<IModelElement> requirements = new LinkedList<IModelElement>();
 
-				if ( !ctx.isValid() ) {
-					break;					
-				}
-			}
-		}
-	}
 
-	private void resolveRequirement(IModelElement requirement, ResolutionContext ctx) throws ResolutionException {
-		if ( ctx.config.isOptional() || !isOptional(requirement) ) {
-			ctx.startRequirement(requirement );
-	
-			try {
-				int[] priorities = repositoryManager.getPriorityLevels();
-				
-				outer: for ( int i = 0; i< priorities.length; i++ ) {
-					List<ISigilBundle> providers = findProvidersAtPriority(priorities[i], requirement, ctx);
-					
-					if ( !providers.isEmpty() && !ctx.monitor.isCanceled() ) {
-						if ( providers.size() > 1 ) {
-							Collections.sort(providers, new BundleOrderComparator(requirement));
-						}
-		
-						for ( ISigilBundle provider : providers ) {
-							// reset validity - if there's another provider it can still be solved
-							ctx.setValid(true);
-							if ( ctx.resolution.addProvider(requirement, provider) ) {
-								if ( ctx.config.isDependents() ) {
-									resolveElement(provider, ctx);
-								}
-								
-								if ( ctx.isValid() ) {
-									break outer;
-								}
-								else {
-									ctx.resolution.removeProvider(requirement, provider);
-								}
-							}
-							else {
-								break outer;
-							}
-						}
-					}
-				}
-			}
-			finally {
-				ctx.endRequirement(requirement);
-			}
-		}
-	}
+        public ResolutionContext( IModelElement root, ResolutionConfig config, IResolutionMonitor monitor )
+        {
+            this.root = root;
+            this.config = config;
+            this.monitor = monitor;
+        }
 
-	private List<ISigilBundle> findProvidersAtPriority(int i, IModelElement requirement, ResolutionContext ctx) throws ResolutionException {
-		ArrayList<ISigilBundle> providers = new ArrayList<ISigilBundle>();
-		
-		for (IBundleRepository rep : repositoryManager.getRepositories(i)) {
-			if ( ctx.monitor.isCanceled() ) {
-				break;
-			}
-			providers.addAll( findProviders( requirement, ctx.config, rep ) );
-		}
-		
-		return providers;
-	}
 
-	private Collection<ISigilBundle> findProviders(IModelElement requirement, ResolutionConfig config, IBundleRepository rep) throws ResolutionException {
-		ArrayList<ISigilBundle> found = new ArrayList<ISigilBundle>();
-		
-		if ( requirement instanceof IPackageImport ) {
-			IPackageImport pi = (IPackageImport) requirement;
-			found.addAll( rep.findAllProviders( pi, config.getOptions() ) );
-		}
-		else if ( requirement instanceof IRequiredBundle ) {
-			IRequiredBundle rb = (IRequiredBundle) requirement;
-			found.addAll( rep.findAllProviders( rb, config.getOptions() ) );
-		}
-		else if ( requirement instanceof ILibraryImport ) {
-			ILibrary lib = repositoryManager.resolveLibrary((ILibraryImport) requirement);
-			if (lib != null) {
-				found.addAll( rep.findProviders(lib, config.getOptions()) );
-			}
-		}
-		else {
-			// shouldn't get here - developer error if do
-			// use isRequirement before getting anywhere near this logic...
-			throw new IllegalStateException( "Invalid requirement type " + requirement );
-		}
+        public void enterModelElement( IModelElement element )
+        {
+            parsed.add( element );
+        }
 
-		return found;
-	}
-	
 
-	private boolean isOptional(IModelElement element) {
-		if ( element instanceof IPackageImport ) {
-			return ((IPackageImport) element).isOptional();
-		}
-		else if ( element instanceof IRequiredBundle ) {
-			return ((IRequiredBundle) element).isOptional();
-		}
-		else if ( element instanceof ILibraryImport ) {
-			ILibrary lib = repositoryManager.resolveLibrary((ILibraryImport) element);
-			for ( IPackageImport pi : lib.getImports() ) {
-				if ( !isOptional(pi) ) {
-					return false;
-				}
-			}
-			return true;
-		}
-		else {
-			// should never get this due to isRequirement test prior to calling this
-			// developer error if found
-			throw new IllegalStateException( "Invalid optional element test for " + element);
-		}
-	}
+        public void exitModelElement( IModelElement element )
+        {
+            parsed.remove( element );
+        }
 
-	private boolean isRequirement(IModelElement element) {
-		return element instanceof IPackageImport || element instanceof IRequiredBundle || element instanceof ILibraryImport;
-	}
-	
-	
+
+        public boolean isNewModelElement( IModelElement element )
+        {
+            return !parsed.contains( element );
+        }
+
+
+        public boolean isValid()
+        {
+            return resolution.isSuccess();
+        }
+
+
+        public void setValid( boolean valid )
+        {
+            resolution.setSuccess( valid );
+        }
+
+
+        public ResolutionException newResolutionException()
+        {
+            return new ResolutionException( root, requirements.toArray( new IModelElement[requirements.size()] ) );
+        }
+
+
+        public void startRequirement( IModelElement element )
+        {
+            requirements.add( element );
+            monitor.startResolution( element );
+        }
+
+
+        public void endRequirement( IModelElement element )
+        {
+            ISigilBundle provider = resolution.getProvider( element );
+
+            setValid( provider != null || isOptional( element ) || config.isIgnoreErrors() );
+
+            if ( isValid() )
+            {
+                // only clear stack if valid
+                // else use it as an aid to trace errors
+                requirements.remove( element );
+            }
+
+            monitor.endResolution( element, provider );
+        }
+    }
+
+    private class Resolution implements IResolution
+    {
+        private Map<ISigilBundle, List<IModelElement>> providees = new HashMap<ISigilBundle, List<IModelElement>>();
+        private Map<IModelElement, ISigilBundle> providers = new HashMap<IModelElement, ISigilBundle>();
+        private boolean success = true; // assume success
+
+
+        boolean addProvider( IModelElement element, ISigilBundle provider )
+        {
+            providers.put( element, provider );
+
+            List<IModelElement> requirements = providees.get( provider );
+
+            boolean isNewProvider = requirements == null;
+
+            if ( isNewProvider )
+            {
+                requirements = new ArrayList<IModelElement>();
+                providees.put( provider, requirements );
+            }
+
+            requirements.add( element );
+
+            return isNewProvider;
+        }
+
+
+        void removeProvider( IModelElement element, ISigilBundle provider )
+        {
+            providers.remove( element );
+            List<IModelElement> e = providees.get( provider );
+            e.remove( element );
+            if ( e.isEmpty() )
+            {
+                providees.remove( provider );
+            }
+        }
+
+
+        void setSuccess( boolean success )
+        {
+            this.success = success;
+        }
+
+
+        public boolean isSuccess()
+        {
+            return success;
+        }
+
+
+        public ISigilBundle getProvider( IModelElement requirement )
+        {
+            return providers.get( requirement );
+        }
+
+
+        public Set<ISigilBundle> getBundles()
+        {
+            return providees.keySet();
+        }
+
+
+        public List<IModelElement> getMatchedRequirements( ISigilBundle bundle )
+        {
+            return providees.get( bundle );
+        }
+
+
+        public boolean isSynchronized()
+        {
+            for ( ISigilBundle b : getBundles() )
+            {
+                if ( !b.isSynchronized() )
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+
+        public void synchronize( IProgressMonitor monitor )
+        {
+            Set<ISigilBundle> bundles = getBundles();
+            SubMonitor progress = SubMonitor.convert( monitor, bundles.size() );
+
+            for ( ISigilBundle b : bundles )
+            {
+                if ( monitor.isCanceled() )
+                {
+                    break;
+                }
+
+                try
+                {
+                    b.synchronize( progress.newChild( 1 ) );
+                }
+                catch ( IOException e )
+                {
+                    BldCore.error( "Failed to synchronize " + b, e );
+                }
+            }
+        }
+    }
+
+    private static final IResolutionMonitor NULL_MONITOR = new IResolutionMonitor()
+    {
+        public void endResolution( IModelElement requirement, ISigilBundle sigilBundle )
+        {
+        }
+
+
+        public boolean isCanceled()
+        {
+            return false;
+        }
+
+
+        public void startResolution( IModelElement requirement )
+        {
+        }
+    };
+
+    private IRepositoryManager repositoryManager;
+
+
+    public BundleResolver( IRepositoryManager repositoryManager )
+    {
+        this.repositoryManager = repositoryManager;
+    }
+
+
+    public IResolution resolve( IModelElement element, ResolutionConfig config, IResolutionMonitor monitor )
+        throws ResolutionException
+    {
+        if ( monitor == null )
+        {
+            monitor = NULL_MONITOR;
+        }
+        ResolutionContext ctx = new ResolutionContext( element, config, monitor );
+
+        resolveElement( element, ctx );
+
+        if ( !ctx.isValid() )
+        {
+            throw ctx.newResolutionException();
+        }
+
+        return ctx.resolution;
+    }
+
+
+    private void resolveElement( IModelElement element, ResolutionContext ctx ) throws ResolutionException
+    {
+        if ( isRequirement( element ) )
+        {
+            resolveRequirement( element, ctx );
+        }
+
+        if ( ctx.isValid() && element instanceof ICompoundModelElement )
+        {
+            resolveCompound( ( ICompoundModelElement ) element, ctx );
+        }
+    }
+
+
+    private void resolveCompound( ICompoundModelElement compound, ResolutionContext ctx ) throws ResolutionException
+    {
+        for ( IModelElement element : compound.children() )
+        {
+            if ( ctx.isNewModelElement( element ) )
+            {
+                if ( isRequirement( element ) )
+                {
+                    resolveRequirement( element, ctx );
+                }
+                else if ( element instanceof ICompoundModelElement )
+                {
+                    if ( !ctx.monitor.isCanceled() )
+                    {
+                        ctx.enterModelElement( element );
+                        resolveElement( ( ICompoundModelElement ) element, ctx );
+                        ctx.exitModelElement( element );
+                    }
+                }
+
+                if ( !ctx.isValid() )
+                {
+                    break;
+                }
+            }
+        }
+    }
+
+
+    private void resolveRequirement( IModelElement requirement, ResolutionContext ctx ) throws ResolutionException
+    {
+        if ( ctx.config.isOptional() || !isOptional( requirement ) )
+        {
+            ctx.startRequirement( requirement );
+
+            try
+            {
+                int[] priorities = repositoryManager.getPriorityLevels();
+
+                outer: for ( int i = 0; i < priorities.length; i++ )
+                {
+                    List<ISigilBundle> providers = findProvidersAtPriority( priorities[i], requirement, ctx );
+
+                    if ( !providers.isEmpty() && !ctx.monitor.isCanceled() )
+                    {
+                        if ( providers.size() > 1 )
+                        {
+                            Collections.sort( providers, new BundleOrderComparator( requirement ) );
+                        }
+
+                        for ( ISigilBundle provider : providers )
+                        {
+                            // reset validity - if there's another provider it can still be solved
+                            ctx.setValid( true );
+                            if ( ctx.resolution.addProvider( requirement, provider ) )
+                            {
+                                if ( ctx.config.isDependents() )
+                                {
+                                    resolveElement( provider, ctx );
+                                }
+
+                                if ( ctx.isValid() )
+                                {
+                                    break outer;
+                                }
+                                else
+                                {
+                                    ctx.resolution.removeProvider( requirement, provider );
+                                }
+                            }
+                            else
+                            {
+                                break outer;
+                            }
+                        }
+                    }
+                }
+            }
+            finally
+            {
+                ctx.endRequirement( requirement );
+            }
+        }
+    }
+
+
+    private List<ISigilBundle> findProvidersAtPriority( int i, IModelElement requirement, ResolutionContext ctx )
+        throws ResolutionException
+    {
+        ArrayList<ISigilBundle> providers = new ArrayList<ISigilBundle>();
+
+        for ( IBundleRepository rep : repositoryManager.getRepositories( i ) )
+        {
+            if ( ctx.monitor.isCanceled() )
+            {
+                break;
+            }
+            providers.addAll( findProviders( requirement, ctx.config, rep ) );
+        }
+
+        return providers;
+    }
+
+
+    private Collection<ISigilBundle> findProviders( IModelElement requirement, ResolutionConfig config,
+        IBundleRepository rep ) throws ResolutionException
+    {
+        ArrayList<ISigilBundle> found = new ArrayList<ISigilBundle>();
+
+        if ( requirement instanceof IPackageImport )
+        {
+            IPackageImport pi = ( IPackageImport ) requirement;
+            found.addAll( rep.findAllProviders( pi, config.getOptions() ) );
+        }
+        else if ( requirement instanceof IRequiredBundle )
+        {
+            IRequiredBundle rb = ( IRequiredBundle ) requirement;
+            found.addAll( rep.findAllProviders( rb, config.getOptions() ) );
+        }
+        else if ( requirement instanceof ILibraryImport )
+        {
+            ILibrary lib = repositoryManager.resolveLibrary( ( ILibraryImport ) requirement );
+            if ( lib != null )
+            {
+                found.addAll( rep.findProviders( lib, config.getOptions() ) );
+            }
+        }
+        else
+        {
+            // shouldn't get here - developer error if do
+            // use isRequirement before getting anywhere near this logic...
+            throw new IllegalStateException( "Invalid requirement type " + requirement );
+        }
+
+        return found;
+    }
+
+
+    private boolean isOptional( IModelElement element )
+    {
+        if ( element instanceof IPackageImport )
+        {
+            return ( ( IPackageImport ) element ).isOptional();
+        }
+        else if ( element instanceof IRequiredBundle )
+        {
+            return ( ( IRequiredBundle ) element ).isOptional();
+        }
+        else if ( element instanceof ILibraryImport )
+        {
+            ILibrary lib = repositoryManager.resolveLibrary( ( ILibraryImport ) element );
+            for ( IPackageImport pi : lib.getImports() )
+            {
+                if ( !isOptional( pi ) )
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+        else
+        {
+            // should never get this due to isRequirement test prior to calling this
+            // developer error if found
+            throw new IllegalStateException( "Invalid optional element test for " + element );
+        }
+    }
+
+
+    private boolean isRequirement( IModelElement element )
+    {
+        return element instanceof IPackageImport || element instanceof IRequiredBundle
+            || element instanceof ILibraryImport;
+    }
+
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/repository/DirectoryHelper.java b/sigil/common/core/src/org/apache/felix/sigil/core/repository/DirectoryHelper.java
index 42daf08..d618ea2 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/repository/DirectoryHelper.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/repository/DirectoryHelper.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core.repository;
 
+
 import java.io.File;
 import java.io.IOException;
 import java.util.List;
@@ -34,61 +35,85 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
 
-public class DirectoryHelper {
-	public static void scanBundles(AbstractBundleRepository repository, List<ISigilBundle> bundles, IPath path, IPath source, boolean recursive) {
-		File dir = path.toFile();
-		
-		if ( dir.exists() ) {
-			for ( File f : dir.listFiles() ){
-				if ( f.isDirectory() ) {
-					if ( recursive ) {
-						scanBundles( repository, bundles, new Path( f.getAbsolutePath() ), source, recursive );
-					}
-				}
-				else if ( f.isFile() && f.getName().endsWith( ".jar" )){
-					JarFile jar = null;
-					try {
-						jar = new JarFile(f);
-						ISigilBundle bundle = buildBundle(repository, jar.getManifest(), f );
-						if ( bundle != null ) {
-							bundle.setSourcePathLocation( source );
-							bundle.setSourceRootPath( new Path( "src" ) );
-							bundles.add( bundle );
-						}
-					} catch (IOException e) {
-						BldCore.error( "Failed to read jar file " + f, e );
-					} catch (ModelElementFactoryException e) {
-						BldCore.error( "Failed to build bundle " + f , e );
-					} catch (RuntimeException e) {
-						BldCore.error( "Failed to build bundle " + f , e );
-					}
-					finally {
-						if ( jar != null ) {
-							try {
-								jar.close();
-							} catch (IOException e) {
-								BldCore.error( "Failed to close jar file", e );
-							}
-						}
-					}
-				}
-			}
-		}
-	}
 
-	private static ISigilBundle buildBundle(
-			AbstractBundleRepository repository, Manifest manifest, File f) {
-		IBundleModelElement info = repository.buildBundleModelElement( manifest );
+public class DirectoryHelper
+{
+    public static void scanBundles( AbstractBundleRepository repository, List<ISigilBundle> bundles, IPath path,
+        IPath source, boolean recursive )
+    {
+        File dir = path.toFile();
 
-		ISigilBundle bundle = null;
+        if ( dir.exists() )
+        {
+            for ( File f : dir.listFiles() )
+            {
+                if ( f.isDirectory() )
+                {
+                    if ( recursive )
+                    {
+                        scanBundles( repository, bundles, new Path( f.getAbsolutePath() ), source, recursive );
+                    }
+                }
+                else if ( f.isFile() && f.getName().endsWith( ".jar" ) )
+                {
+                    JarFile jar = null;
+                    try
+                    {
+                        jar = new JarFile( f );
+                        ISigilBundle bundle = buildBundle( repository, jar.getManifest(), f );
+                        if ( bundle != null )
+                        {
+                            bundle.setSourcePathLocation( source );
+                            bundle.setSourceRootPath( new Path( "src" ) );
+                            bundles.add( bundle );
+                        }
+                    }
+                    catch ( IOException e )
+                    {
+                        BldCore.error( "Failed to read jar file " + f, e );
+                    }
+                    catch ( ModelElementFactoryException e )
+                    {
+                        BldCore.error( "Failed to build bundle " + f, e );
+                    }
+                    catch ( RuntimeException e )
+                    {
+                        BldCore.error( "Failed to build bundle " + f, e );
+                    }
+                    finally
+                    {
+                        if ( jar != null )
+                        {
+                            try
+                            {
+                                jar.close();
+                            }
+                            catch ( IOException e )
+                            {
+                                BldCore.error( "Failed to close jar file", e );
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
 
-		if ( info != null ) {
-			bundle = ModelElementFactory.getInstance().newModelElement( ISigilBundle.class );
-			bundle.addChild(info);
-			bundle.setLocation( new Path( f.getAbsolutePath() ) );
-		}
 
-		return bundle;
-	}
+    private static ISigilBundle buildBundle( AbstractBundleRepository repository, Manifest manifest, File f )
+    {
+        IBundleModelElement info = repository.buildBundleModelElement( manifest );
+
+        ISigilBundle bundle = null;
+
+        if ( info != null )
+        {
+            bundle = ModelElementFactory.getInstance().newModelElement( ISigilBundle.class );
+            bundle.addChild( info );
+            bundle.setLocation( new Path( f.getAbsolutePath() ) );
+        }
+
+        return bundle;
+    }
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/repository/FileSystemRepository.java b/sigil/common/core/src/org/apache/felix/sigil/core/repository/FileSystemRepository.java
index d0933ad..dd95eb6 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/repository/FileSystemRepository.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/repository/FileSystemRepository.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core.repository;
 
+
 import java.util.ArrayList;
 
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
@@ -26,40 +27,53 @@
 import org.apache.felix.sigil.repository.IRepositoryVisitor;
 import org.eclipse.core.runtime.IPath;
 
-public class FileSystemRepository extends AbstractBundleRepository {
 
-	private ArrayList<ISigilBundle> bundles;
-	private IPath path;
-	private boolean recurse;
-	
-	public FileSystemRepository(String id, IPath path, boolean recurse) {
-		super(id);
-		this.path = path;
-		this.recurse = recurse;
-	}
+public class FileSystemRepository extends AbstractBundleRepository
+{
 
-	@Override
-	public void accept(IRepositoryVisitor visitor, int options) {
-		synchronized( this ) {
-			if ( bundles == null ) {
-				bundles = new ArrayList<ISigilBundle>();
-				DirectoryHelper.scanBundles(this, bundles, path, null, recurse);
-			}
-		}
-		
-		for ( ISigilBundle b : bundles ) {
-			if ( !visitor.visit(b) ) {
-				break;
-			}
-		}		
-	}
+    private ArrayList<ISigilBundle> bundles;
+    private IPath path;
+    private boolean recurse;
 
-	public void refresh() {
-		synchronized( this ) {
-			bundles = null;
-		}
-		
-		notifyChange();
-	}
+
+    public FileSystemRepository( String id, IPath path, boolean recurse )
+    {
+        super( id );
+        this.path = path;
+        this.recurse = recurse;
+    }
+
+
+    @Override
+    public void accept( IRepositoryVisitor visitor, int options )
+    {
+        synchronized ( this )
+        {
+            if ( bundles == null )
+            {
+                bundles = new ArrayList<ISigilBundle>();
+                DirectoryHelper.scanBundles( this, bundles, path, null, recurse );
+            }
+        }
+
+        for ( ISigilBundle b : bundles )
+        {
+            if ( !visitor.visit( b ) )
+            {
+                break;
+            }
+        }
+    }
+
+
+    public void refresh()
+    {
+        synchronized ( this )
+        {
+            bundles = null;
+        }
+
+        notifyChange();
+    }
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/repository/FileSystemRepositoryProvider.java b/sigil/common/core/src/org/apache/felix/sigil/core/repository/FileSystemRepositoryProvider.java
index c9950e4..58c85aa 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/repository/FileSystemRepositoryProvider.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/repository/FileSystemRepositoryProvider.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core.repository;
 
+
 import java.io.File;
 import java.util.Properties;
 
@@ -27,16 +28,19 @@
 import org.apache.felix.sigil.repository.RepositoryException;
 import org.eclipse.core.runtime.Path;
 
-public class FileSystemRepositoryProvider implements IRepositoryProvider {
 
-	public IBundleRepository createRepository(String id, Properties preferences)
-			throws RepositoryException {
-		String dir = preferences.getProperty("dir");
-		if (!new File(dir).isDirectory()) {
-			throw new RepositoryException("directory '" + dir +"' does not exist.");
-		}
-		boolean recurse = Boolean.valueOf(preferences.getProperty("recurse"));
-		return new FileSystemRepository(id, new Path(dir), recurse);		
-	}
+public class FileSystemRepositoryProvider implements IRepositoryProvider
+{
+
+    public IBundleRepository createRepository( String id, Properties preferences ) throws RepositoryException
+    {
+        String dir = preferences.getProperty( "dir" );
+        if ( !new File( dir ).isDirectory() )
+        {
+            throw new RepositoryException( "directory '" + dir + "' does not exist." );
+        }
+        boolean recurse = Boolean.valueOf( preferences.getProperty( "recurse" ) );
+        return new FileSystemRepository( id, new Path( dir ), recurse );
+    }
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/repository/ProgressWrapper.java b/sigil/common/core/src/org/apache/felix/sigil/core/repository/ProgressWrapper.java
index 18b166f..faea5e1 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/repository/ProgressWrapper.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/repository/ProgressWrapper.java
@@ -19,53 +19,74 @@
 
 package org.apache.felix.sigil.core.repository;
 
+
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.apache.felix.sigil.repository.IResolutionMonitor;
 
-public class ProgressWrapper implements IProgressMonitor {
 
-	private IResolutionMonitor monitor;
-	
-	public ProgressWrapper(IResolutionMonitor monitor) {
-		this.monitor = monitor;
-	}
+public class ProgressWrapper implements IProgressMonitor
+{
 
-	public boolean isCanceled() {
-		return monitor.isCanceled();
-	}
+    private IResolutionMonitor monitor;
 
-	public void beginTask(String name, int totalWork) {
-		// TODO Auto-generated method stub
 
-	}
+    public ProgressWrapper( IResolutionMonitor monitor )
+    {
+        this.monitor = monitor;
+    }
 
-	public void done() {
-		// TODO Auto-generated method stub
 
-	}
+    public boolean isCanceled()
+    {
+        return monitor.isCanceled();
+    }
 
-	public void internalWorked(double work) {
-		// TODO Auto-generated method stub
 
-	}
+    public void beginTask( String name, int totalWork )
+    {
+        // TODO Auto-generated method stub
 
-	public void setCanceled(boolean value) {
-		// TODO Auto-generated method stub
+    }
 
-	}
 
-	public void setTaskName(String name) {
-		// TODO Auto-generated method stub
+    public void done()
+    {
+        // TODO Auto-generated method stub
 
-	}
+    }
 
-	public void subTask(String name) {
-		// TODO Auto-generated method stub
 
-	}
+    public void internalWorked( double work )
+    {
+        // TODO Auto-generated method stub
 
-	public void worked(int work) {
-		// TODO Auto-generated method stub
+    }
 
-	}
+
+    public void setCanceled( boolean value )
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void setTaskName( String name )
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void subTask( String name )
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void worked( int work )
+    {
+        // TODO Auto-generated method stub
+
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/repository/SystemRepository.java b/sigil/common/core/src/org/apache/felix/sigil/core/repository/SystemRepository.java
index 3b471c3..1f1cb0b 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/repository/SystemRepository.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/repository/SystemRepository.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core.repository;
 
+
 import java.io.IOException;
 import java.util.jar.JarFile;
 
@@ -32,79 +33,110 @@
 import org.apache.felix.sigil.repository.IRepositoryVisitor;
 import org.eclipse.core.runtime.IPath;
 
-public class SystemRepository extends AbstractBundleRepository {
 
-	private final String packages;
-	private final IPath frameworkPath;
+public class SystemRepository extends AbstractBundleRepository
+{
 
-	public SystemRepository(String id, IPath frameworkPath, String packages) {
-		super(id);
-		this.frameworkPath = frameworkPath;
-		this.packages = packages;
-	}
+    private final String packages;
+    private final IPath frameworkPath;
 
-	private static ISigilBundle systemBundle;
-	
-	@Override
-	public void accept(IRepositoryVisitor visitor, int options) {
-		ISigilBundle bundle = loadSystemBundle();
-		
-		if ( bundle != null ) {
-			visitor.visit(bundle);
-		}
-	}
 
-	private synchronized ISigilBundle loadSystemBundle() {
-		if (systemBundle == null) {
-			systemBundle = ModelElementFactory.getInstance().newModelElement(ISigilBundle.class);
-			
-			JarFile jar = null;
-			
-			try {
-    			final IBundleModelElement info;
-				if (frameworkPath != null) {
-        			systemBundle.setLocation(frameworkPath);
-    				jar = new JarFile(frameworkPath.toFile());
-    				info = buildBundleModelElement(jar.getManifest());
-				} else {
-				    info = ModelElementFactory.getInstance().newModelElement(IBundleModelElement.class);
-				}
-				
-    			applyProfile(info);
-    			systemBundle.addChild(info);
-			} catch (IOException e) {
-				BldCore.error( "Failed to read jar file " + frameworkPath, e );
-			} catch (ModelElementFactoryException e) {
-				BldCore.error( "Failed to build bundle " + frameworkPath , e );
-			} catch (RuntimeException e) {
-				BldCore.error( "Failed to build bundle " + frameworkPath , e );
-			}
-			finally {
-				if (jar != null) {
-					try {
-						jar.close();
-					} catch (IOException e) {
-						BldCore.error( "Failed to close jar file", e );
-					}
-				}
-			}
-		}
-		
-		return systemBundle;
-	}
+    public SystemRepository( String id, IPath frameworkPath, String packages )
+    {
+        super( id );
+        this.frameworkPath = frameworkPath;
+        this.packages = packages;
+    }
 
-	private void applyProfile(IBundleModelElement info) {
-		if (packages != null) {
-			for (String name : packages.split(",\\s*")) {
-				IPackageExport pe = ModelElementFactory.getInstance().newModelElement(IPackageExport.class);
-				pe.setPackageName(name);
-				info.addExport(pe);
-			}
-		}
-	}
+    private static ISigilBundle systemBundle;
 
-	public synchronized void refresh() {
-		systemBundle = null;
-		notifyChange();
-	}
+
+    @Override
+    public void accept( IRepositoryVisitor visitor, int options )
+    {
+        ISigilBundle bundle = loadSystemBundle();
+
+        if ( bundle != null )
+        {
+            visitor.visit( bundle );
+        }
+    }
+
+
+    private synchronized ISigilBundle loadSystemBundle()
+    {
+        if ( systemBundle == null )
+        {
+            systemBundle = ModelElementFactory.getInstance().newModelElement( ISigilBundle.class );
+
+            JarFile jar = null;
+
+            try
+            {
+                final IBundleModelElement info;
+                if ( frameworkPath != null )
+                {
+                    systemBundle.setLocation( frameworkPath );
+                    jar = new JarFile( frameworkPath.toFile() );
+                    info = buildBundleModelElement( jar.getManifest() );
+                }
+                else
+                {
+                    info = ModelElementFactory.getInstance().newModelElement( IBundleModelElement.class );
+                }
+
+                applyProfile( info );
+                systemBundle.addChild( info );
+            }
+            catch ( IOException e )
+            {
+                BldCore.error( "Failed to read jar file " + frameworkPath, e );
+            }
+            catch ( ModelElementFactoryException e )
+            {
+                BldCore.error( "Failed to build bundle " + frameworkPath, e );
+            }
+            catch ( RuntimeException e )
+            {
+                BldCore.error( "Failed to build bundle " + frameworkPath, e );
+            }
+            finally
+            {
+                if ( jar != null )
+                {
+                    try
+                    {
+                        jar.close();
+                    }
+                    catch ( IOException e )
+                    {
+                        BldCore.error( "Failed to close jar file", e );
+                    }
+                }
+            }
+        }
+
+        return systemBundle;
+    }
+
+
+    private void applyProfile( IBundleModelElement info )
+    {
+        if ( packages != null )
+        {
+            for ( String name : packages.split( ",\\s*" ) )
+            {
+                IPackageExport pe = ModelElementFactory.getInstance().newModelElement( IPackageExport.class );
+                pe.setPackageName( name );
+                info.addExport( pe );
+            }
+        }
+    }
+
+
+    public synchronized void refresh()
+    {
+        systemBundle = null;
+        notifyChange();
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/repository/SystemRepositoryProvider.java b/sigil/common/core/src/org/apache/felix/sigil/core/repository/SystemRepositoryProvider.java
index 8f5c065..d8b045e 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/repository/SystemRepositoryProvider.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/repository/SystemRepositoryProvider.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.core.repository;
 
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Properties;
@@ -28,42 +29,50 @@
 import org.apache.felix.sigil.repository.RepositoryException;
 import org.eclipse.core.runtime.Path;
 
-public class SystemRepositoryProvider implements IRepositoryProvider {
 
-	public IBundleRepository createRepository(String id, Properties properties)
-			throws RepositoryException {
-		String fw = properties.getProperty("framework");
-		Path frameworkPath = fw == null ? null : new Path(fw);
-		String extraPkgs = properties.getProperty("packages");
-		String profile = properties.getProperty("profile");
-		
-		try {
-			Properties p = readProfile(profile);
-    		String pkgs = p.getProperty("org.osgi.framework.system.packages") + "," + extraPkgs;
-			return new SystemRepository(id, frameworkPath, pkgs);
-		} catch (IOException e) {
-			throw new RepositoryException("Failed to load profile", e);
-		}
-	}
-	
-	public static Properties readProfile(String name) throws IOException {
-		if (name == null) {
-			String version = System.getProperty("java.specification.version");
-			String[] split = version.split("\\.");
-			String prefix = ("6".compareTo(split[1]) <= 0) ? "JavaSE-" : "J2SE-";
-			name = prefix + version;
-		}
-		
-		String profilePath = "profiles/" + name + ".profile";
-		InputStream in = SystemRepositoryProvider.class.getClassLoader().getResourceAsStream(profilePath);
-		
-		if (in == null)
-			throw new IOException("No such profile: " + profilePath);
-		
-		Properties p = new Properties();
-		p.load(in);
-		
-		return p;
-	}
-	
+public class SystemRepositoryProvider implements IRepositoryProvider
+{
+
+    public IBundleRepository createRepository( String id, Properties properties ) throws RepositoryException
+    {
+        String fw = properties.getProperty( "framework" );
+        Path frameworkPath = fw == null ? null : new Path( fw );
+        String extraPkgs = properties.getProperty( "packages" );
+        String profile = properties.getProperty( "profile" );
+
+        try
+        {
+            Properties p = readProfile( profile );
+            String pkgs = p.getProperty( "org.osgi.framework.system.packages" ) + "," + extraPkgs;
+            return new SystemRepository( id, frameworkPath, pkgs );
+        }
+        catch ( IOException e )
+        {
+            throw new RepositoryException( "Failed to load profile", e );
+        }
+    }
+
+
+    public static Properties readProfile( String name ) throws IOException
+    {
+        if ( name == null )
+        {
+            String version = System.getProperty( "java.specification.version" );
+            String[] split = version.split( "\\." );
+            String prefix = ( "6".compareTo( split[1] ) <= 0 ) ? "JavaSE-" : "J2SE-";
+            name = prefix + version;
+        }
+
+        String profilePath = "profiles/" + name + ".profile";
+        InputStream in = SystemRepositoryProvider.class.getClassLoader().getResourceAsStream( profilePath );
+
+        if ( in == null )
+            throw new IOException( "No such profile: " + profilePath );
+
+        Properties p = new Properties();
+        p.load( in );
+
+        return p;
+    }
+
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/core/util/QuoteUtil.java b/sigil/common/core/src/org/apache/felix/sigil/core/util/QuoteUtil.java
index 6559d87..fe68920 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/core/util/QuoteUtil.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/core/util/QuoteUtil.java
@@ -19,35 +19,43 @@
 
 package org.apache.felix.sigil.core.util;
 
+
 import java.util.ArrayList;
 
-public class QuoteUtil {
-	public static String[] split(String str) {
-		ArrayList<String> split = new ArrayList<String>();
-		boolean quote = false;
-		StringBuffer buf = new StringBuffer(str.length());
-		
-		for ( int i = 0; i < str.length(); i++ ) {
-			char c = str.charAt(i);
-			switch ( c ) {
-			case '"':
-				quote = !quote;
-				break;
-			case ',':
-				if ( !quote ) {
-					split.add( buf.toString().trim() );
-					buf.setLength(0);
-					break;
-				}
-				// else fall through on purpose
-			default:
-				buf.append( c );
-			}
-		}
-		
-		if ( buf.length() > 0 ) {
-			split.add( buf.toString().trim() );
-		}
-		return split.toArray( new String[split.size()] );
-	}	
+
+public class QuoteUtil
+{
+    public static String[] split( String str )
+    {
+        ArrayList<String> split = new ArrayList<String>();
+        boolean quote = false;
+        StringBuffer buf = new StringBuffer( str.length() );
+
+        for ( int i = 0; i < str.length(); i++ )
+        {
+            char c = str.charAt( i );
+            switch ( c )
+            {
+                case '"':
+                    quote = !quote;
+                    break;
+                case ',':
+                    if ( !quote )
+                    {
+                        split.add( buf.toString().trim() );
+                        buf.setLength( 0 );
+                        break;
+                    }
+                    // else fall through on purpose
+                default:
+                    buf.append( c );
+            }
+        }
+
+        if ( buf.length() > 0 )
+        {
+            split.add( buf.toString().trim() );
+        }
+        return split.toArray( new String[split.size()] );
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/AbstractCompoundModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/model/AbstractCompoundModelElement.java
index 41b8306..3561bb4 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/AbstractCompoundModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/AbstractCompoundModelElement.java
@@ -19,95 +19,125 @@
 
 package org.apache.felix.sigil.model;
 
+
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
 
-public abstract class AbstractCompoundModelElement extends AbstractModelElement implements ICompoundModelElement {
+public abstract class AbstractCompoundModelElement extends AbstractModelElement implements ICompoundModelElement
+{
 
-	private static final long serialVersionUID = 1L;
-	
-	public AbstractCompoundModelElement(String description) {
-		super(description);
-	}
-
-	public boolean addChild(IModelElement child) throws InvalidModelException {
-		return support.addChild(child);
-	}
-
-	public boolean removeChild(IModelElement child) {
-		return support.removeChild(child);
-	}
-
-	public IModelElement[] children() {
-		return support.children();
-	}
-	
-	private static final ThreadLocal<Map<IModelWalker,Set<IModelElement>>> walkedLocal = new ThreadLocal<Map<IModelWalker,Set<IModelElement>>>();
-	
-	public void visit(IModelWalker walker) {
-		if ( walker.visit( this ) ) {
-			Map<IModelWalker,Set<IModelElement>> walked = walkedLocal.get();
-			boolean delete = false;
-			
-			if ( walked == null ) {
-				walked = new HashMap<IModelWalker, Set<IModelElement>>();
-				walkedLocal.set(walked);
-			}
-
-			Set<IModelElement> check = walked.get(walker);
-			
-			if ( check == null ) {
-				delete = true;
-				check = new HashSet<IModelElement>(); 
-			}
-			
-			check.add( this );
-			
-			try {
-				for ( IModelElement e : children() ) {
-					if ( !check.contains( e ) && walker.visit( e ) ) {
-						check.add( e );
-						if ( e instanceof ICompoundModelElement ) {
-							ICompoundModelElement c = (ICompoundModelElement) e;
-							c.visit(walker);
-						}
-					}
-				}
-			}
-			finally {
-				if ( delete ) {
-					walked.remove(walker);
-					
-					if ( walked.isEmpty() ) {
-						walkedLocal.set( null );
-					}
-				}
-			}
-		}
-	}
-
-	public Set<Class<? extends IModelElement>> getOptionalChildren() {
-		return support.getChildrenTypes(false);
-	}
-
-	public Set<Class<? extends IModelElement>> getRequiredChildren() {
-		return support.getChildrenTypes(true);
-	}
-
-	public <T extends IModelElement> T[] childrenOfType(Class<T> type) {
-		return support.childrenOfType( type );
-	}
+    private static final long serialVersionUID = 1L;
 
 
-	@Override
-	public void checkValid() throws InvalidModelException {
-		super.checkValid();
-		
-		for ( IModelElement e : support.children() ) {
-			e.checkValid();
-		}
-	}	
+    public AbstractCompoundModelElement( String description )
+    {
+        super( description );
+    }
+
+
+    public boolean addChild( IModelElement child ) throws InvalidModelException
+    {
+        return support.addChild( child );
+    }
+
+
+    public boolean removeChild( IModelElement child )
+    {
+        return support.removeChild( child );
+    }
+
+
+    public IModelElement[] children()
+    {
+        return support.children();
+    }
+
+    private static final ThreadLocal<Map<IModelWalker, Set<IModelElement>>> walkedLocal = new ThreadLocal<Map<IModelWalker, Set<IModelElement>>>();
+
+
+    public void visit( IModelWalker walker )
+    {
+        if ( walker.visit( this ) )
+        {
+            Map<IModelWalker, Set<IModelElement>> walked = walkedLocal.get();
+            boolean delete = false;
+
+            if ( walked == null )
+            {
+                walked = new HashMap<IModelWalker, Set<IModelElement>>();
+                walkedLocal.set( walked );
+            }
+
+            Set<IModelElement> check = walked.get( walker );
+
+            if ( check == null )
+            {
+                delete = true;
+                check = new HashSet<IModelElement>();
+            }
+
+            check.add( this );
+
+            try
+            {
+                for ( IModelElement e : children() )
+                {
+                    if ( !check.contains( e ) && walker.visit( e ) )
+                    {
+                        check.add( e );
+                        if ( e instanceof ICompoundModelElement )
+                        {
+                            ICompoundModelElement c = ( ICompoundModelElement ) e;
+                            c.visit( walker );
+                        }
+                    }
+                }
+            }
+            finally
+            {
+                if ( delete )
+                {
+                    walked.remove( walker );
+
+                    if ( walked.isEmpty() )
+                    {
+                        walkedLocal.set( null );
+                    }
+                }
+            }
+        }
+    }
+
+
+    public Set<Class<? extends IModelElement>> getOptionalChildren()
+    {
+        return support.getChildrenTypes( false );
+    }
+
+
+    public Set<Class<? extends IModelElement>> getRequiredChildren()
+    {
+        return support.getChildrenTypes( true );
+    }
+
+
+    public <T extends IModelElement> T[] childrenOfType( Class<T> type )
+    {
+        return support.childrenOfType( type );
+    }
+
+
+    @Override
+    public void checkValid() throws InvalidModelException
+    {
+        super.checkValid();
+
+        for ( IModelElement e : support.children() )
+        {
+            e.checkValid();
+        }
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/AbstractModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/model/AbstractModelElement.java
index 628b543..519d1eb 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/AbstractModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/AbstractModelElement.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.model;
 
+
 import java.io.Serializable;
 import java.util.Collections;
 import java.util.HashMap;
@@ -26,129 +27,175 @@
 import java.util.Set;
 
 
-public abstract class AbstractModelElement implements IModelElement {
-	
-	private static final long serialVersionUID = 1L;
+public abstract class AbstractModelElement implements IModelElement
+{
 
-	private IModelElement parent;
-	
+    private static final long serialVersionUID = 1L;
+
+    private IModelElement parent;
+
     private String description;
     private transient Map<Object, Object> meta;
     private Map<Serializable, Serializable> serializedMeta;
     private OverrideOptions override;
-    
+
     protected final ModelElementSupport support;
 
-    public AbstractModelElement(String description) {
-    	support = new ModelElementSupport(this);
-    	this.description = description.intern();
+
+    public AbstractModelElement( String description )
+    {
+        support = new ModelElementSupport( this );
+        this.description = description.intern();
         this.meta = new HashMap<Object, Object>();
         this.serializedMeta = new HashMap<Serializable, Serializable>();
     }
 
-    public String getElementDescription() {
+
+    public String getElementDescription()
+    {
         return description;
     }
 
-    public Map<Object, Object> getMeta() {
+
+    public Map<Object, Object> getMeta()
+    {
         return meta;
     }
 
-    public void setMeta(Map<Object, Object> meta) {
+
+    public void setMeta( Map<Object, Object> meta )
+    {
         this.meta = meta;
     }
 
-    @Override
-    public AbstractModelElement clone() {
-		try {
-	        AbstractModelElement clone = (AbstractModelElement) super.clone();
-	   
-	        clone.meta = new HashMap<Object, Object>(meta);
 
-	        return clone;
-		} catch (CloneNotSupportedException e) {
-			// can't happen but make compiler happy
-			throw new IllegalStateException(e);
-		}
+    @Override
+    public AbstractModelElement clone()
+    {
+        try
+        {
+            AbstractModelElement clone = ( AbstractModelElement ) super.clone();
+
+            clone.meta = new HashMap<Object, Object>( meta );
+
+            return clone;
+        }
+        catch ( CloneNotSupportedException e )
+        {
+            // can't happen but make compiler happy
+            throw new IllegalStateException( e );
+        }
     }
 
+
     @SuppressWarnings("unchecked")
-	public <T extends IModelElement> T getAncestor(Class<T> type) {
-    	IModelElement parent = this.parent;
-    	
-    	while ( parent != null ) {
-    		if ( type.isInstance( parent ) ) {
-    			return (T) parent;
-    		}
-    		parent = parent.getParent();
-    	}
-    	
-		return null;
-	}
+    public <T extends IModelElement> T getAncestor( Class<T> type )
+    {
+        IModelElement parent = this.parent;
 
-	public IModelElement getParent() {
-		return parent;
-	}
-	
-	public void setParent( IModelElement parent ) {
-		if ( parent != null ) {
-			if ( this.parent != null && this.parent != parent ) {
-				throw new IllegalStateException( "Parent already installed");
-			}
-		}
-		
-		this.parent = parent;
-	}
-	
-    public void checkValid() throws InvalidModelException {
-    	for ( String req : getRequiredProperties() ) {
-    		try {
-				if ( getProperty( req ) == null ) {
-					throw new InvalidModelException(this, "Missing property " + req );
-				}
-			} catch (NoSuchMethodException e) {
-				throw new InvalidModelException( this, "No such property " + req );
-			}
-    	}
-	}
+        while ( parent != null )
+        {
+            if ( type.isInstance( parent ) )
+            {
+                return ( T ) parent;
+            }
+            parent = parent.getParent();
+        }
 
-	public Object getProperty(String name) throws NoSuchMethodException {
-		return support.getProperty(name);
-	}
+        return null;
+    }
 
-	public void setProperty(String name, Object value)
-			throws NoSuchMethodException {
-		support.setProperty(name, value);
-	}
 
-	public void addProperty(String name, Object value)
-			throws NoSuchMethodException {
-		support.addProperty(name, value);
-	}
+    public IModelElement getParent()
+    {
+        return parent;
+    }
 
-	public void removeProperty(String name, Object value)
-			throws NoSuchMethodException {
-		support.removeProperty(name, value);
-	}
 
-	public Object getDefaultPropertyValue(String name) {
-		return support.getDefaultPropertyValue( name );
-	}
+    public void setParent( IModelElement parent )
+    {
+        if ( parent != null )
+        {
+            if ( this.parent != null && this.parent != parent )
+            {
+                throw new IllegalStateException( "Parent already installed" );
+            }
+        }
 
-	public Set<String> getPropertyNames() {
-		return support.getPropertyNames();
-	}
+        this.parent = parent;
+    }
 
-	public Set<String> getRequiredProperties() {
-		return Collections.emptySet();
-	}
 
-	protected Object writeReplace() {
+    public void checkValid() throws InvalidModelException
+    {
+        for ( String req : getRequiredProperties() )
+        {
+            try
+            {
+                if ( getProperty( req ) == null )
+                {
+                    throw new InvalidModelException( this, "Missing property " + req );
+                }
+            }
+            catch ( NoSuchMethodException e )
+            {
+                throw new InvalidModelException( this, "No such property " + req );
+            }
+        }
+    }
+
+
+    public Object getProperty( String name ) throws NoSuchMethodException
+    {
+        return support.getProperty( name );
+    }
+
+
+    public void setProperty( String name, Object value ) throws NoSuchMethodException
+    {
+        support.setProperty( name, value );
+    }
+
+
+    public void addProperty( String name, Object value ) throws NoSuchMethodException
+    {
+        support.addProperty( name, value );
+    }
+
+
+    public void removeProperty( String name, Object value ) throws NoSuchMethodException
+    {
+        support.removeProperty( name, value );
+    }
+
+
+    public Object getDefaultPropertyValue( String name )
+    {
+        return support.getDefaultPropertyValue( name );
+    }
+
+
+    public Set<String> getPropertyNames()
+    {
+        return support.getPropertyNames();
+    }
+
+
+    public Set<String> getRequiredProperties()
+    {
+        return Collections.emptySet();
+    }
+
+
+    protected Object writeReplace()
+    {
         AbstractModelElement clone = clone();
 
-        for (Map.Entry<Object, Object> e : clone.meta.entrySet()) {
-            if (e.getKey() instanceof Serializable && e.getValue() instanceof Serializable) {
-                serializedMeta.put((Serializable) e.getKey(), (Serializable) e.getValue());
+        for ( Map.Entry<Object, Object> e : clone.meta.entrySet() )
+        {
+            if ( e.getKey() instanceof Serializable && e.getValue() instanceof Serializable )
+            {
+                serializedMeta.put( ( Serializable ) e.getKey(), ( Serializable ) e.getValue() );
             }
         }
 
@@ -157,21 +204,29 @@
         return clone;
     }
 
-    public Class<?> getPropertyType(String name) throws NoSuchMethodException {
-		return support.getPropertyType(name);
-	}
 
-	protected Object readResolve() {
-        this.meta = new HashMap<Object, Object>(serializedMeta);
+    public Class<?> getPropertyType( String name ) throws NoSuchMethodException
+    {
+        return support.getPropertyType( name );
+    }
+
+
+    protected Object readResolve()
+    {
+        this.meta = new HashMap<Object, Object>( serializedMeta );
         serializedMeta.clear();
         return this;
     }
 
-	public OverrideOptions getOverride() {
-		return override;
-	}
 
-	public void setOverride(OverrideOptions override) {
-		this.override = override;
-	}
+    public OverrideOptions getOverride()
+    {
+        return override;
+    }
+
+
+    public void setOverride( OverrideOptions override )
+    {
+        this.override = override;
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/ICompoundModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/model/ICompoundModelElement.java
index 672224d..374ef2b 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/ICompoundModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/ICompoundModelElement.java
@@ -19,20 +19,29 @@
 
 package org.apache.felix.sigil.model;
 
+
 import java.util.Set;
 
-public interface ICompoundModelElement extends IModelElement {
-    boolean addChild(IModelElement children) throws InvalidModelException;
-    
-    boolean removeChild(IModelElement children);
-    
+
+public interface ICompoundModelElement extends IModelElement
+{
+    boolean addChild( IModelElement children ) throws InvalidModelException;
+
+
+    boolean removeChild( IModelElement children );
+
+
     IModelElement[] children();
-    
-    void visit(IModelWalker walker);
-    
+
+
+    void visit( IModelWalker walker );
+
+
     <T extends IModelElement> T[] childrenOfType( Class<T> type );
-    
+
+
     Set<Class<? extends IModelElement>> getRequiredChildren();
-    
-    Set<Class<? extends IModelElement>> getOptionalChildren();    
+
+
+    Set<Class<? extends IModelElement>> getOptionalChildren();
 }
\ No newline at end of file
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/IDependency.java b/sigil/common/core/src/org/apache/felix/sigil/model/IDependency.java
index ca82523..7ce842c 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/IDependency.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/IDependency.java
@@ -19,6 +19,8 @@
 
 package org.apache.felix.sigil.model;
 
-public interface IDependency extends IModelElement {
-	IDependent getDependent();
+
+public interface IDependency extends IModelElement
+{
+    IDependent getDependent();
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/IDependent.java b/sigil/common/core/src/org/apache/felix/sigil/model/IDependent.java
index 1bd23d3..6adafb9 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/IDependent.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/IDependent.java
@@ -19,6 +19,8 @@
 
 package org.apache.felix.sigil.model;
 
-public interface IDependent extends IModelElement {
-	IDependency getDepender();
+
+public interface IDependent extends IModelElement
+{
+    IDependency getDepender();
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/IDependentModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/model/IDependentModelElement.java
index 941fc9c..50b8f71 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/IDependentModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/IDependentModelElement.java
@@ -19,19 +19,23 @@
 
 package org.apache.felix.sigil.model;
 
-public interface IDependentModelElement extends IModelElement {
+
+public interface IDependentModelElement extends IModelElement
+{
     /**
      * @return
      */
     IDependency[] getDependencies();
-    
+
+
     /**
      * @param dependency
      */
-    void addDependency(IModelElement dependency);
-    
+    void addDependency( IModelElement dependency );
+
+
     /**
      * @param dependency
      */
-    void removeDependency(IModelElement dependency);
+    void removeDependency( IModelElement dependency );
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/IModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/model/IModelElement.java
index 2e355ad..6dc521a 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/IModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/IModelElement.java
@@ -19,9 +19,11 @@
 
 package org.apache.felix.sigil.model;
 
+
 import java.util.Map;
 import java.util.Set;
 
+
 /**
  * Descriptors represent static information about component, composite or system. They allow other services to decide
  * how to deal with the given entity without the need to directly interact with the entity.
@@ -29,14 +31,16 @@
  * @author dave
  * 
  */
-public interface IModelElement extends Cloneable {
+public interface IModelElement extends Cloneable
+{
     /**
      * A brief human readable description of the component, composite or system.
      * 
      * @return
      */
     String getElementDescription();
-    
+
+
     /**
      * A set of key value pairs designed for use by a machine to classify a particular component, composite or system.
      * 
@@ -44,13 +48,15 @@
      */
     Map<Object, Object> getMeta();
 
+
     /**
      * Set meta data on this descriptor. Meta data is designed for use by a machine to classify or further enhance a
      * particular component, composite or system.
      * 
      * @param meta
      */
-    void setMeta(Map<Object, Object> meta);
+    void setMeta( Map<Object, Object> meta );
+
 
     /**
      * Check to see if this descriptor defines a complete set of properties. The definition of what constitutes a
@@ -59,15 +65,18 @@
      * @throws InvalidModelException
      */
     void checkValid() throws InvalidModelException;
-    
+
+
     /**
      * Find the parent element of this model element or null if no parent exists.
      * @return
      */
     IModelElement getParent();
-    
+
+
     void setParent( IModelElement parent );
-        
+
+
     /**
      * Finds the first ancestor up the hierarch of parents which is an instance of the specified
      * type.
@@ -75,24 +84,33 @@
      * @param type
      * @return
      */
-    <T extends IModelElement> T getAncestor(Class<T> type);
-    
+    <T extends IModelElement> T getAncestor( Class<T> type );
+
+
     IModelElement clone();
-    
+
+
     Set<String> getPropertyNames();
-    
-    void setProperty(String name, Object value) throws NoSuchMethodException;
-    
-	void addProperty(String name, Object value) throws NoSuchMethodException;
-	
-	void removeProperty(String name, Object value) throws NoSuchMethodException;
-	
-    Object getProperty(String name) throws NoSuchMethodException;
-    
-    Object getDefaultPropertyValue(String name);
-    
+
+
+    void setProperty( String name, Object value ) throws NoSuchMethodException;
+
+
+    void addProperty( String name, Object value ) throws NoSuchMethodException;
+
+
+    void removeProperty( String name, Object value ) throws NoSuchMethodException;
+
+
+    Object getProperty( String name ) throws NoSuchMethodException;
+
+
+    Object getDefaultPropertyValue( String name );
+
+
     Set<String> getRequiredProperties();
 
-	Class<?> getPropertyType(String name) throws NoSuchMethodException;
+
+    Class<?> getPropertyType( String name ) throws NoSuchMethodException;
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/IModelInfo.java b/sigil/common/core/src/org/apache/felix/sigil/model/IModelInfo.java
index fdc3b6e..c8cb4fa 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/IModelInfo.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/IModelInfo.java
@@ -19,8 +19,14 @@
 
 package org.apache.felix.sigil.model;
 
-public interface IModelInfo {
-	String getGroupName();
-	String getGroupURI();
-	String getName();
+
+public interface IModelInfo
+{
+    String getGroupName();
+
+
+    String getGroupURI();
+
+
+    String getName();
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/IModelWalker.java b/sigil/common/core/src/org/apache/felix/sigil/model/IModelWalker.java
index 345f45f..b058efa 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/IModelWalker.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/IModelWalker.java
@@ -20,6 +20,7 @@
 package org.apache.felix.sigil.model;
 
 
-public interface IModelWalker {
-	boolean visit( IModelElement element );
+public interface IModelWalker
+{
+    boolean visit( IModelElement element );
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/INamedModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/model/INamedModelElement.java
index 1a73baa..7d70630 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/INamedModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/INamedModelElement.java
@@ -19,9 +19,17 @@
 
 package org.apache.felix.sigil.model;
 
-public interface INamedModelElement extends IModelElement {
-	void setName(String name);
-	String getName();
+
+public interface INamedModelElement extends IModelElement
+{
+    void setName( String name );
+
+
+    String getName();
+
+
     OverrideOptions getOverride();
-    void setOverride(OverrideOptions override);	
+
+
+    void setOverride( OverrideOptions override );
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/IRequirementModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/model/IRequirementModelElement.java
index 8877f9b..64419c9 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/IRequirementModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/IRequirementModelElement.java
@@ -19,6 +19,8 @@
 
 package org.apache.felix.sigil.model;
 
-public interface IRequirementModelElement {
-	boolean accepts(IModelElement provider);
+
+public interface IRequirementModelElement
+{
+    boolean accepts( IModelElement provider );
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/InvalidModelException.java b/sigil/common/core/src/org/apache/felix/sigil/model/InvalidModelException.java
index f334f80..eaf3658 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/InvalidModelException.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/InvalidModelException.java
@@ -19,27 +19,35 @@
 
 package org.apache.felix.sigil.model;
 
+
 /**
  * @author dave
  * 
  */
-public class InvalidModelException extends RuntimeException {
-	
-	private static final long serialVersionUID = 1L;
-	
-	private IModelElement target;
-	
-    public InvalidModelException(IModelElement target, String msg) {
-        super(msg);
+public class InvalidModelException extends RuntimeException
+{
+
+    private static final long serialVersionUID = 1L;
+
+    private IModelElement target;
+
+
+    public InvalidModelException( IModelElement target, String msg )
+    {
+        super( msg );
         this.target = target;
     }
 
-    public InvalidModelException(IModelElement target, String msg, Throwable t) {
-        super(msg, t);
+
+    public InvalidModelException( IModelElement target, String msg, Throwable t )
+    {
+        super( msg, t );
         this.target = target;
     }
-    
-    public IModelElement getTarget() {
-    	return target;
+
+
+    public IModelElement getTarget()
+    {
+        return target;
     }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/ModelElementFactory.java b/sigil/common/core/src/org/apache/felix/sigil/model/ModelElementFactory.java
index 4d131c8..552862c 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/ModelElementFactory.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/ModelElementFactory.java
@@ -19,150 +19,213 @@
 
 package org.apache.felix.sigil.model;
 
+
 import java.util.HashMap;
 import java.util.Map;
 
-public abstract class ModelElementFactory {
-	static class ElementInfo {
-		Class<? extends IModelElement> implType;
-		String name;
-		String groupName;
-		String groupURI;
-		
-		public ElementInfo(Class<? extends IModelElement> implType, String name, String groupName, String groupURI) {
-			this.implType = implType;
-			this.name = name;
-			this.groupName = groupName;
-			this.groupURI = groupURI;
-		}
-		
-		public Class<? extends IModelElement> getImplType() {
-			return implType;
-		}
-		public String getName() {
-			return name;
-		}
-		
-		public String getGroupName() {
-			return groupName;
-		}
 
-		public String getGroupURI() {
-			return groupURI;
-		}
-		
-		public String toString() {
-			return "ElementInfo[" + name + ":" + groupName + ":" + groupURI + ":" + implType.getCanonicalName() + "]";
-		}
-	}
+public abstract class ModelElementFactory
+{
+    static class ElementInfo
+    {
+        Class<? extends IModelElement> implType;
+        String name;
+        String groupName;
+        String groupURI;
 
-	static class ModelInfo implements IModelInfo {
 
-		private ElementInfo e;
-		
-		public ModelInfo(ElementInfo e) {
-			this.e = e;
-		}
+        public ElementInfo( Class<? extends IModelElement> implType, String name, String groupName, String groupURI )
+        {
+            this.implType = implType;
+            this.name = name;
+            this.groupName = groupName;
+            this.groupURI = groupURI;
+        }
 
-		public String getGroupName() {
-			return e.getGroupName();
-		}
 
-		public String getGroupURI() {
-			return e.getGroupURI();
-		}
+        public Class<? extends IModelElement> getImplType()
+        {
+            return implType;
+        }
 
-		public String getName() {
-			return e.getName();
-		}
 
-	}
+        public String getName()
+        {
+            return name;
+        }
 
-	static class DefaultModelElementFactory extends ModelElementFactory {
-		private HashMap<Class<? extends IModelElement>, ElementInfo> elementInfo = new HashMap<Class<? extends IModelElement>, ElementInfo>();
-		
-		@SuppressWarnings("unchecked")
-		@Override
-		public <T extends IModelElement> T newModelElement( Class<T> type ) throws ModelElementFactoryException {
-			ElementInfo info = elementInfo.get( type );
-			if ( info == null ) {
-				throw new ModelElementFactoryException( "No implementation registered for " + type );
-			}
-			try {
-				return (T) info.getImplType().newInstance();
-			} catch (InstantiationException e) {
-				throw new ModelElementFactoryException(e);
-			} catch (IllegalAccessException e) {
-				throw new ModelElementFactoryException(e);
-			}
-		}
 
-		@Override
-		public <T extends IModelElement> void register(Class<T> type, Class<? extends T> impl, String name, String groupName, String groupURI ) {
-			elementInfo.put( type, new ElementInfo( impl, name, groupName, groupURI ) );
-		}
+        public String getGroupName()
+        {
+            return groupName;
+        }
 
-		@Override
-		public <T extends IModelElement> void unregister(Class<T> type,
-				Class<? extends T> impl) {
-			ElementInfo info = elementInfo.get( type );
-			if ( info != null && info.getImplType() == impl ) {
-				elementInfo.remove(type);
-			}
-		}
 
-		@Override
-		public IModelInfo getModelInfo(Class<? extends IModelElement> type) {
-			ElementInfo e = findElementInfo( type );
-			
-			if ( e == null ) {
-				return null;
-			}
-			
-			return new ModelInfo( e );
-		}
+        public String getGroupURI()
+        {
+            return groupURI;
+        }
 
-		@Override
-		public IModelElement newModelElement(String namespaceURI, String localPart) throws ModelElementFactoryException {
-			for ( Map.Entry<Class<? extends IModelElement>, ElementInfo> e : elementInfo.entrySet() ) {
-				ElementInfo i = e.getValue();
-				if ( equal( namespaceURI, i.getGroupURI() ) && equal( i.getName(), localPart ) ) {
-					return newModelElement(e.getKey());
-				}
-			}
-			
-			return null;
-		}
 
-		private boolean equal(String val1, String val2) {
-			return val1 == null ? val2 == null : val1.equals( val2 );
-		}
+        public String toString()
+        {
+            return "ElementInfo[" + name + ":" + groupName + ":" + groupURI + ":" + implType.getCanonicalName() + "]";
+        }
+    }
 
-		private ElementInfo findElementInfo( Class<? extends IModelElement> type ) {
-			for ( ElementInfo e : elementInfo.values() ) {
-				if ( e.getImplType() == type ) {
-					return e;
-				}
-			}
-			
-			return null;
-		}
+    static class ModelInfo implements IModelInfo
+    {
 
-	}
+        private ElementInfo e;
 
-	public abstract <T extends IModelElement> T newModelElement( Class<T> type ) throws ModelElementFactoryException;
-	
-	public abstract IModelElement newModelElement(String namespaceURI, String localPart) throws ModelElementFactoryException;	
-	
-	public abstract <T extends IModelElement> void register( Class<T> type, Class<? extends T> impl, String name, String groupName, String groupURI );
-	
-	public abstract <T extends IModelElement> void unregister( Class<T> type, Class<? extends T> impl );
 
-	public abstract IModelInfo getModelInfo( Class<? extends IModelElement> type );
-	
-	private static ModelElementFactory instance = new DefaultModelElementFactory();
+        public ModelInfo( ElementInfo e )
+        {
+            this.e = e;
+        }
 
-	public static ModelElementFactory getInstance() {
-		return instance;
-	}
+
+        public String getGroupName()
+        {
+            return e.getGroupName();
+        }
+
+
+        public String getGroupURI()
+        {
+            return e.getGroupURI();
+        }
+
+
+        public String getName()
+        {
+            return e.getName();
+        }
+
+    }
+
+    static class DefaultModelElementFactory extends ModelElementFactory
+    {
+        private HashMap<Class<? extends IModelElement>, ElementInfo> elementInfo = new HashMap<Class<? extends IModelElement>, ElementInfo>();
+
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public <T extends IModelElement> T newModelElement( Class<T> type ) throws ModelElementFactoryException
+        {
+            ElementInfo info = elementInfo.get( type );
+            if ( info == null )
+            {
+                throw new ModelElementFactoryException( "No implementation registered for " + type );
+            }
+            try
+            {
+                return ( T ) info.getImplType().newInstance();
+            }
+            catch ( InstantiationException e )
+            {
+                throw new ModelElementFactoryException( e );
+            }
+            catch ( IllegalAccessException e )
+            {
+                throw new ModelElementFactoryException( e );
+            }
+        }
+
+
+        @Override
+        public <T extends IModelElement> void register( Class<T> type, Class<? extends T> impl, String name,
+            String groupName, String groupURI )
+        {
+            elementInfo.put( type, new ElementInfo( impl, name, groupName, groupURI ) );
+        }
+
+
+        @Override
+        public <T extends IModelElement> void unregister( Class<T> type, Class<? extends T> impl )
+        {
+            ElementInfo info = elementInfo.get( type );
+            if ( info != null && info.getImplType() == impl )
+            {
+                elementInfo.remove( type );
+            }
+        }
+
+
+        @Override
+        public IModelInfo getModelInfo( Class<? extends IModelElement> type )
+        {
+            ElementInfo e = findElementInfo( type );
+
+            if ( e == null )
+            {
+                return null;
+            }
+
+            return new ModelInfo( e );
+        }
+
+
+        @Override
+        public IModelElement newModelElement( String namespaceURI, String localPart )
+            throws ModelElementFactoryException
+        {
+            for ( Map.Entry<Class<? extends IModelElement>, ElementInfo> e : elementInfo.entrySet() )
+            {
+                ElementInfo i = e.getValue();
+                if ( equal( namespaceURI, i.getGroupURI() ) && equal( i.getName(), localPart ) )
+                {
+                    return newModelElement( e.getKey() );
+                }
+            }
+
+            return null;
+        }
+
+
+        private boolean equal( String val1, String val2 )
+        {
+            return val1 == null ? val2 == null : val1.equals( val2 );
+        }
+
+
+        private ElementInfo findElementInfo( Class<? extends IModelElement> type )
+        {
+            for ( ElementInfo e : elementInfo.values() )
+            {
+                if ( e.getImplType() == type )
+                {
+                    return e;
+                }
+            }
+
+            return null;
+        }
+
+    }
+
+
+    public abstract <T extends IModelElement> T newModelElement( Class<T> type ) throws ModelElementFactoryException;
+
+
+    public abstract IModelElement newModelElement( String namespaceURI, String localPart )
+        throws ModelElementFactoryException;
+
+
+    public abstract <T extends IModelElement> void register( Class<T> type, Class<? extends T> impl, String name,
+        String groupName, String groupURI );
+
+
+    public abstract <T extends IModelElement> void unregister( Class<T> type, Class<? extends T> impl );
+
+
+    public abstract IModelInfo getModelInfo( Class<? extends IModelElement> type );
+
+    private static ModelElementFactory instance = new DefaultModelElementFactory();
+
+
+    public static ModelElementFactory getInstance()
+    {
+        return instance;
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/ModelElementFactoryException.java b/sigil/common/core/src/org/apache/felix/sigil/model/ModelElementFactoryException.java
index 163681c..581f031 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/ModelElementFactoryException.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/ModelElementFactoryException.java
@@ -19,16 +19,22 @@
 
 package org.apache.felix.sigil.model;
 
-public class ModelElementFactoryException extends RuntimeException {
 
-	private static final long serialVersionUID = 1L;
+public class ModelElementFactoryException extends RuntimeException
+{
 
-	public ModelElementFactoryException(Throwable t) {
-		super(t);
-	}
+    private static final long serialVersionUID = 1L;
 
-	public ModelElementFactoryException(String msg) {
-		super(msg);
-	}
+
+    public ModelElementFactoryException( Throwable t )
+    {
+        super( t );
+    }
+
+
+    public ModelElementFactoryException( String msg )
+    {
+        super( msg );
+    }
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/ModelElementSupport.java b/sigil/common/core/src/org/apache/felix/sigil/model/ModelElementSupport.java
index a3347a4..4ea0b0c 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/ModelElementSupport.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/ModelElementSupport.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.model;
 
+
 import java.io.Serializable;
 import java.lang.ref.SoftReference;
 import java.lang.reflect.Array;
@@ -35,694 +36,954 @@
 import java.util.logging.Logger;
 
 
-public class ModelElementSupport implements Serializable {
+public class ModelElementSupport implements Serializable
+{
 
-	private static final Logger log = Logger.getLogger( ModelElementSupport.class.getName() );
-	
-	private static final long serialVersionUID = 1L;
-	
-	private static final PropertyAdapter[] EMPTY_PROPS = new PropertyAdapter[] {};
-	private static final IModelElement[] EMPTY_ELEMENTS = new IModelElement[] {};
-	private static final Object[] ZERO_ARGS = new Object[] {};
-	private static final Class<?>[] ZERO_PARAMS = new Class[] {};
-	
-	private static final WeakHashMap<Class<?>, SoftReference<ChildAdapter[]>> adapterCache = new WeakHashMap<Class<?>, SoftReference<ChildAdapter[]>>();;	
-	private static final WeakHashMap<Class<?>, SoftReference<PropertyAdapter[]>> propertyCache = new WeakHashMap<Class<?>, SoftReference<PropertyAdapter[]>>();;	
-	
-	private IModelElement target;
-	
-	private transient SoftReference<PropertyAdapter[]> propertyReference;
-	private transient SoftReference<ChildAdapter[]> childrenReference;
-	private transient SoftReference<Set<String>> propertyNameReference;
-	
-	public ModelElementSupport(IModelElement target) {
-		this.target = target;
-	}
+    private static final Logger log = Logger.getLogger( ModelElementSupport.class.getName() );
 
-	public void setProperty(String name, Object value) throws NoSuchMethodException {
-		PropertyAdapter p = findProperty( name, value );
-		if ( p == null ) {
-			throw new NoSuchMethodException( "No such property " + name + " for type " + target.getClass() );
-		}
-		invoke( target, p.getWriteMethod(), value );
-	}
-	
-	public void addProperty(String name, Object value) throws NoSuchMethodException {
-		PropertyAdapter p = findProperty( name, value );
-		if ( p == null ) {
-			throw new NoSuchMethodException( "No such property " + name + " for type " + target.getClass() );
-		}
-		invoke( target, p.getAddMethod(), value );
-	}
+    private static final long serialVersionUID = 1L;
 
-	public void removeProperty(String name, Object value) throws NoSuchMethodException {
-		PropertyAdapter p = findProperty( name, value );
-		if ( p == null ) {
-			throw new NoSuchMethodException( "No such property " + name + " for type " + target.getClass() );
-		}
-		invoke( target, p.getRemoveMethod(), value );
-	}
-	
-	public Object getProperty( String name ) throws NoSuchMethodException {
-		PropertyAdapter p = findProperty( name, null );
-		if ( p == null ) {
-			throw new NoSuchMethodException( "No such property " + name + " for type " + target.getClass() );
-		}
-		return invoke( target, p.getReadMethod(), ZERO_ARGS );
-	}
-	
-	public Set<String> getPropertyNames() {
-		Set<String> names = propertyNameReference == null ? null : propertyNameReference.get();
-		
-		if ( names == null ) {
-			names = new HashSet<String>();
-			
-			PropertyAdapter[] props = cachedProps( target.getClass() );
-			for ( PropertyAdapter prop : props ) {
-				names.add( prop.getName() );
-			}
-			
-			propertyNameReference = new SoftReference<Set<String>>(names);
-		}
-		
-		return names;
-	}
-	
-	public Object getDefaultPropertyValue(String name) {
-		try {
-			Method m = target.getClass().getMethod( makeDefaultPropertyValue( name ), ZERO_PARAMS );
-			return invoke( target, m, ZERO_ARGS );
-		} catch (SecurityException e) {
-			throw new UndeclaredThrowableException(e);
-		} catch (NoSuchMethodException e) {
-			// fine no default
-			return null;
-		}
-	}	
-	
-	public Class<?> getPropertyType(String name) throws NoSuchMethodException {
-		PropertyAdapter p = findProperty( name, null );
-		if ( p == null ) {
-			throw new NoSuchMethodException( "No such property " + name + " for type " + target.getClass() );
-		}
-		return p.getPropertyType();
-	}	
-	
-	@SuppressWarnings("unchecked")
-	public <T extends IModelElement> T[] childrenOfType( Class<T> type ) {
-		ChildAdapter[] adapters = cachedAdapters();
-		
-		if ( adapters.length == 0 ) {
-			// return (T[]) EMPTY_ELEMENTS;
-    		return ((T[])Array.newInstance(type, 0));
-		}
-		
-		ArrayList<T> elements = new ArrayList<T>();
-		
-		for ( ChildAdapter adapter : adapters ) {
-			Collection<? extends IModelElement> val = adapter.members(target);
-			
-			for ( IModelElement e : val ) {
-				if ( type.isInstance(e) ) {
-					elements.add( (T) e );
-				}
-			}
-		}
-		
-		//return elements.toArray( (T[]) EMPTY_ELEMENTS );
-		return elements.toArray((T[])Array.newInstance(type, elements.size()));
-	}
-	
-	public IModelElement[] children() {
-		ChildAdapter[] adapters = cachedAdapters();
-		
-		if ( adapters.length == 0 ) {
-			return EMPTY_ELEMENTS;
-		}
-		
-		ArrayList<IModelElement> elements = new ArrayList<IModelElement>();
-		
-		for ( ChildAdapter adapter : adapters ) {
-			elements.addAll( adapter.members(target) );
-		}
-		
-		return elements.toArray( EMPTY_ELEMENTS );
-	}
-	
-	public boolean addChild(IModelElement element) throws InvalidModelException {
-		if ( element.getParent() == null ) {
-			ChildAdapter[] adapters = cachedAdapters();
-			
-			if ( adapters.length > 0 ) {
-				for ( ChildAdapter adapter : adapters ) {
-					if ( adapter.add( target, element ) ) {
-						element.setParent(target);
-						return true;
-					}
-				}
-			}
-		}
-		
-		return false;
-	}
-	
-	public boolean removeChild(IModelElement element) {
-		if ( element.getParent() == target ) {
-			ChildAdapter[] adapters = cachedAdapters();
-			
-			if ( adapters.length > 0 ) {
-				for ( ChildAdapter adapter : adapters ) {
-					if ( adapter.remove( target, element ) ) {
-						element.setParent( null );
-						return true;
-					}
-				}
-			}
-		}
-		
-		return false;
-	}
+    private static final PropertyAdapter[] EMPTY_PROPS = new PropertyAdapter[]
+        {};
+    private static final IModelElement[] EMPTY_ELEMENTS = new IModelElement[]
+        {};
+    private static final Object[] ZERO_ARGS = new Object[]
+        {};
+    private static final Class<?>[] ZERO_PARAMS = new Class[]
+        {};
 
-	public Set<Class<? extends IModelElement>> getChildrenTypes(boolean required) {
-		ChildAdapter[] adapters = cachedAdapters();
-		
-		if ( adapters.length == 0 ) {
-			return Collections.emptySet();
-		}
-		
-		HashSet<Class<? extends IModelElement>> types = new HashSet<Class<? extends IModelElement>>();
-		
-		for ( ChildAdapter adapter : adapters ) {
-			if ( adapter.isRequired() == required ) {
-				Class<? extends IModelElement> type = adapter.getType();
-				
-				if ( type != null ) {
-					types.add( type );
-				}
-			}
-		}
-		
-		return types;
-	}
-	
-	private PropertyAdapter findProperty(String name, Object value) {
-		PropertyAdapter[] props = propertyReference == null ? null : propertyReference.get();
-		
-		if ( props == null ) {
-			props = cachedProps( target.getClass() );
-			propertyReference = new SoftReference<PropertyAdapter[]>( props );
-		}
-		
-		for ( PropertyAdapter prop : props ) {
-			if ( prop.getName().equals( name ) && (value == null || prop.getRawType().isAssignableFrom(value.getClass() ) ) ) {
-				return prop;
-			}
-		}
-		
-		return null;
-	}
+    private static final WeakHashMap<Class<?>, SoftReference<ChildAdapter[]>> adapterCache = new WeakHashMap<Class<?>, SoftReference<ChildAdapter[]>>();;
+    private static final WeakHashMap<Class<?>, SoftReference<PropertyAdapter[]>> propertyCache = new WeakHashMap<Class<?>, SoftReference<PropertyAdapter[]>>();;
 
-	private static PropertyAdapter[] cachedProps(
-			Class<? extends IModelElement> type) {
-		SoftReference<PropertyAdapter[]> ref = propertyCache.get( type );
-		
-		PropertyAdapter[] props = ref == null ? null : ref.get();
-		
-		if ( props == null ) {
-			props = loadProps( type );
-			propertyCache.put( type, new SoftReference<PropertyAdapter[]>( props ) );
-		}
-		
-		return props;
-	}
+    private IModelElement target;
 
-	private static PropertyAdapter[] loadProps(Class<? extends IModelElement> type) {
-		ArrayList<PropertyAdapter> props = new ArrayList<PropertyAdapter>();
-		for ( Method m : type.getMethods() ) {
-			if ( isValidProperty( m )) {
-				try {
-					PropertyAdapter p = new PropertyAdapter( m, type );
-					props.add( p );
-				} catch (NoSuchMethodException e) {
-					// fine not a bean method
-					log.finer( "Invalid bean property method " + m + ": " + e.getMessage() );
-				}
-			}
-		}
-		
-		return props.toArray( EMPTY_PROPS );
-	}
+    private transient SoftReference<PropertyAdapter[]> propertyReference;
+    private transient SoftReference<ChildAdapter[]> childrenReference;
+    private transient SoftReference<Set<String>> propertyNameReference;
 
-	private static boolean isValidProperty(Method m) {
-		return m.getName().startsWith( "get" ) && m.getParameterTypes().length == 0 && !m.getDeclaringClass().equals( Object.class ) && !IModelElement.class.isAssignableFrom(m.getReturnType());
-	}
 
-	private static String makeDefaultPropertyValue(String name) {
-		return "getDefault" + capitalise( name );
-	}
+    public ModelElementSupport( IModelElement target )
+    {
+        this.target = target;
+    }
 
-	private static String capitalise(String name) {
-		return Character.toUpperCase(name.charAt(0))  + name.substring(1);
-	}
 
-	private static String decapitalise(String substring) {
-		return Character.toLowerCase(substring.charAt(0)) + substring.substring(1);
-	}
+    public void setProperty( String name, Object value ) throws NoSuchMethodException
+    {
+        PropertyAdapter p = findProperty( name, value );
+        if ( p == null )
+        {
+            throw new NoSuchMethodException( "No such property " + name + " for type " + target.getClass() );
+        }
+        invoke( target, p.getWriteMethod(), value );
+    }
 
-	private ChildAdapter[] cachedAdapters() {
-		ChildAdapter[] adapters = childrenReference == null ? null : childrenReference.get();
-		
-		if ( adapters == null ) {
-			adapters = loadAdapters( target );
-			childrenReference = new SoftReference<ChildAdapter[]>( adapters );
-		}		
-		
-		return adapters;
-	}
-	
-	private static ChildAdapter[] loadAdapters(IModelElement target) {
-		Class<? extends IModelElement> type = target.getClass();
-		SoftReference<ChildAdapter[]> ref = adapterCache.get( type );
-		
-		ChildAdapter[] adapters = ref == null ? null : ref.get();
-		
-		if ( adapters == null ) {
-			adapters = buildAdapters( type );
-			adapterCache.put( type, new SoftReference<ChildAdapter[]>( adapters ) );
-		}
-		
-		return adapters;
-	}
-	
-	private static ChildAdapter[] buildAdapters(Class<? extends IModelElement> type) {
-		ArrayList<ChildAdapter> adapters = new ArrayList<ChildAdapter>();
-		
-		for ( Method m : type.getMethods() ) {
-			ChildAdapter adapter = null;
-			
-			if ( isValidGetProperty( m ) ) {
-				adapter = buildGetAdapter( m );
-			}
-			else if ( isValidSetProperty( m ) ) {
-				adapter = buildSetAdapter( m );
-			}
-			else if ( isValidAddProperty( m ) ) {
-				adapter = buildAddAdapter( m );
-			}
-			else if ( isValidRemoveProperty( m ) ) {
-				adapter = buildRemoveAdapter( m );
-			}
-			
-			if ( adapter != null ) {
-				adapters.add( adapter );
-			}
-		}
-		
-		return adapters.toArray( new ChildAdapter[adapters.size()] );
-	}
 
-	private static ChildAdapter buildGetAdapter(Method m) {
-		if ( IModelElement.class.isAssignableFrom( m.getReturnType() ) ) {
-			return new GetPropertyAdapter( m );
-		}
-		else if ( Collection.class.isAssignableFrom( m.getReturnType() ) ) {
-			return new GetCollectionAdapter( m );
-		}
-		else if ( isModelArray( m.getReturnType() ) ) {
-			return new GetArrayAdapter( m );
-		}
-		else {
-			return null;
-		}
-	}
-	
-	private static ChildAdapter buildSetAdapter(Method m) {
-		if ( IModelElement.class.isAssignableFrom( m.getParameterTypes()[0] ) ) {
-			return new SetPropertyAdapter( m );
-		}
-		else {
-			return null;
-		}
-	}
+    public void addProperty( String name, Object value ) throws NoSuchMethodException
+    {
+        PropertyAdapter p = findProperty( name, value );
+        if ( p == null )
+        {
+            throw new NoSuchMethodException( "No such property " + name + " for type " + target.getClass() );
+        }
+        invoke( target, p.getAddMethod(), value );
+    }
 
-	private static ChildAdapter buildAddAdapter(Method m) {
-		if ( IModelElement.class.isAssignableFrom( m.getParameterTypes()[0] ) ) {
-			return new AddPropertyAdapter( m );
-		}
-		else {
-			return null;
-		}
-	}
 
-	private static ChildAdapter buildRemoveAdapter(Method m) {
-		if ( IModelElement.class.isAssignableFrom( m.getParameterTypes()[0] ) ) {
-			return new RemovePropertyAdapter( m );
-		}
-		else {
-			return null;
-		}
-	}
+    public void removeProperty( String name, Object value ) throws NoSuchMethodException
+    {
+        PropertyAdapter p = findProperty( name, value );
+        if ( p == null )
+        {
+            throw new NoSuchMethodException( "No such property " + name + " for type " + target.getClass() );
+        }
+        invoke( target, p.getRemoveMethod(), value );
+    }
 
-	private static boolean isValidRemoveProperty(Method m) {
-		return m.getParameterTypes().length == 1 && m.getName().startsWith( "remove" ) && !isDeclared( ICompoundModelElement.class, m );
-	}
 
-	private static boolean isValidAddProperty(Method m) {
-		return m.getParameterTypes().length == 1 && m.getName().startsWith( "add" ) && !isDeclared( ICompoundModelElement.class, m );
-	}
+    public Object getProperty( String name ) throws NoSuchMethodException
+    {
+        PropertyAdapter p = findProperty( name, null );
+        if ( p == null )
+        {
+            throw new NoSuchMethodException( "No such property " + name + " for type " + target.getClass() );
+        }
+        return invoke( target, p.getReadMethod(), ZERO_ARGS );
+    }
 
-	private static boolean isDeclared(Class<? extends IModelElement> element, Method m) {
-		try {
-			element.getMethod( m.getName(), m.getParameterTypes() );
-			return true;
-		} catch (SecurityException e) {
-			throw new UndeclaredThrowableException( e );
-		} catch (NoSuchMethodException e) {
-			return false;
-		}
-	}
 
-	private static boolean isValidSetProperty(Method m) {
-		return m.getParameterTypes().length == 1 && m.getName().startsWith( "set" ) && !isDeclared( IModelElement.class, m );
-	}
+    public Set<String> getPropertyNames()
+    {
+        Set<String> names = propertyNameReference == null ? null : propertyNameReference.get();
 
-	private static boolean isValidGetProperty(Method m) {
-		return m.getParameterTypes().length == 0 && m.getName().startsWith( "get" ) && !isDeclared( IModelElement.class, m ) && !isDeclared(ICompoundModelElement.class, m);
-	}
+        if ( names == null )
+        {
+            names = new HashSet<String>();
 
-	private static Object invoke( Object target, Method m, Object... args ) {
-		try {
-			return m.invoke(target, args);
-		} catch (IllegalArgumentException e) {
-			// this should already have been tested
-			throw new IllegalStateException(e);
-		} catch (IllegalAccessException e) {
-			throw new UndeclaredThrowableException( e );
-		} catch (InvocationTargetException e) {
-			throw new UndeclaredThrowableException( e.getCause() );
-		}
-	}		
+            PropertyAdapter[] props = cachedProps( target.getClass() );
+            for ( PropertyAdapter prop : props )
+            {
+                names.add( prop.getName() );
+            }
 
-	private static class PropertyAdapter {
+            propertyNameReference = new SoftReference<Set<String>>( names );
+        }
 
-		String prop;
-		String name;
-		Method g;
-		Method s;
-		Method a;
-		Method r;
-		Class<?> propertyType;
-		
-		public PropertyAdapter(Method g, Class<?> type) throws SecurityException, NoSuchMethodException {
-			if ( g.getReturnType().isArray() || Iterable.class.isAssignableFrom(g.getReturnType() ) ) {
-				prop = g.getName().substring(3);
-				// remove trailing s - as in addWibble, removeWibble, getWibbles
-				prop = prop.substring(0, prop.length() - 1);
-				name = decapitalise( prop );
-				a = find( "add", prop, g.getReturnType(), type );
-				propertyType = a.getParameterTypes()[0];
-				r = find( "remove", prop, g.getReturnType(), type );
-				if ( r.getParameterTypes()[0] != propertyType ) {
-					throw new NoSuchMethodException( "Add remove property method types do not match" );
-				}
-				propertyType = Array.newInstance(propertyType, 0).getClass();
-			}
-			else {
-				prop = g.getName().substring(3);
-				name = decapitalise( prop );
-				propertyType = g.getReturnType();
-				s = find( "set", prop, propertyType, type );
-			}
-			
-			this.g = g;
-		}
-		
-		public Class<?> getRawType() {
-			return propertyType.isArray() ? propertyType.getComponentType() : propertyType;
-		}
+        return names;
+    }
 
-		public Class<?> getPropertyType() {
-			return propertyType;
-		}
 
-		public Method getReadMethod() {
-			return g;
-		}
+    public Object getDefaultPropertyValue( String name )
+    {
+        try
+        {
+            Method m = target.getClass().getMethod( makeDefaultPropertyValue( name ), ZERO_PARAMS );
+            return invoke( target, m, ZERO_ARGS );
+        }
+        catch ( SecurityException e )
+        {
+            throw new UndeclaredThrowableException( e );
+        }
+        catch ( NoSuchMethodException e )
+        {
+            // fine no default
+            return null;
+        }
+    }
 
-		public Method getAddMethod() throws NoSuchMethodException {
-			if ( a == null ) {
-				throw new NoSuchMethodException( "No such method add" + prop ); 
-			}
-			
-			return a;
-		}
 
-		public Method getRemoveMethod() throws NoSuchMethodException {
-			if ( r == null ) {
-				throw new NoSuchMethodException( "No such method remove" + prop ); 
-			}
-			
-			return r;
-		}
+    public Class<?> getPropertyType( String name ) throws NoSuchMethodException
+    {
+        PropertyAdapter p = findProperty( name, null );
+        if ( p == null )
+        {
+            throw new NoSuchMethodException( "No such property " + name + " for type " + target.getClass() );
+        }
+        return p.getPropertyType();
+    }
 
-		public Method getWriteMethod() throws NoSuchMethodException {
-			if ( s == null ) {
-				throw new NoSuchMethodException( "No such method set" + prop ); 
-			}
-			
-			return s;
-		}
-		
-		@Override
-		public String toString() {
-			return "PropertyAdapter[" + name + "]";
-		}
 
-		private Method find(String prefix, String prop, Class<?> returnType, Class<?> type) throws SecurityException, NoSuchMethodException {
-			String methodName = prefix + prop;
-			
-			if ( returnType.isArray() ) {
-				Class<?> t = returnType.getComponentType();
-				return type.getMethod( methodName, new Class[] { t } );
-			}
-			else if ( Iterable.class.isAssignableFrom( returnType ) ) {
-				Method f = null;
-				for ( Method m : type.getMethods() ) {
-					if ( m.getParameterTypes().length == 1 && m.getName().equals( methodName ) && !IModelElement.class.isAssignableFrom(m.getParameterTypes()[0]) ) {
-						if ( f == null ) {
-							f = m;
-						}
-						else {
-							throw new NoSuchMethodException( "Found duplicate " + methodName );
-						}
-					}
-				}
-				if ( f == null ) {
-					throw new NoSuchMethodException( "No such method " + methodName );
-				}
-				
-				return f;
-			}
-			else {
-				return type.getMethod( methodName, new Class[] { returnType } ); 
-			}
-		}
-		public String getName() {
-			return name;
-		}
-		
-	}
-	
-	private static abstract class ChildAdapter {
-		Method m;
-		
-		ChildAdapter( Method m ) {
-			this.m = m;
-		}
-		
-		public boolean isRequired() {
-			return m.isAnnotationPresent(Required.class);
-		}
+    @SuppressWarnings("unchecked")
+    public <T extends IModelElement> T[] childrenOfType( Class<T> type )
+    {
+        ChildAdapter[] adapters = cachedAdapters();
 
-		boolean add(Object target, IModelElement element) {
-			return false;
-		}
+        if ( adapters.length == 0 )
+        {
+            // return (T[]) EMPTY_ELEMENTS;
+            return ( ( T[] ) Array.newInstance( type, 0 ) );
+        }
 
-		abstract Class<? extends IModelElement> getType();
+        ArrayList<T> elements = new ArrayList<T>();
 
-		boolean remove(Object target, IModelElement element) {
-			return false;
-		}
+        for ( ChildAdapter adapter : adapters )
+        {
+            Collection<? extends IModelElement> val = adapter.members( target );
 
-		Collection<? extends IModelElement> members(Object target) {
-			return Collections.emptyList();
-		}
+            for ( IModelElement e : val )
+            {
+                if ( type.isInstance( e ) )
+                {
+                    elements.add( ( T ) e );
+                }
+            }
+        }
 
-		@Override
-		public String toString() {
-			return "ChildAdapter[ " + m.getName() + "]";
-		}	
-	}
-	
-	private static class GetPropertyAdapter extends ChildAdapter {
-		GetPropertyAdapter(Method m) {
-			super(m);
-		}
+        //return elements.toArray( (T[]) EMPTY_ELEMENTS );
+        return elements.toArray( ( T[] ) Array.newInstance( type, elements.size() ) );
+    }
 
-		@Override
-		Collection<? extends IModelElement> members(Object target) {
-			IModelElement member = (IModelElement) invoke( target, m, ZERO_ARGS );
-			if ( member == null ) {
-				return Collections.emptyList();
-			}
-			else {
-				return Collections.<IModelElement>singleton( member );
-			}
-		}
 
-		@SuppressWarnings("unchecked")
-		@Override
-		Class<? extends IModelElement> getType() {
-			return (Class<? extends IModelElement>) m.getReturnType();
-		}
-	}	
-	
-	private static class GetCollectionAdapter extends ChildAdapter {
-		public GetCollectionAdapter(Method m) {
-			super(m);
-		}
+    public IModelElement[] children()
+    {
+        ChildAdapter[] adapters = cachedAdapters();
 
-		@SuppressWarnings("unchecked")
-		@Override
-		Collection<? extends IModelElement> members(Object target) {
-			Collection members = (Collection) invoke( target, m, ZERO_ARGS );
-			if ( members == null ) {
-				return Collections.emptyList();
-			}
-			else {
-				ArrayList<IModelElement> safe = new ArrayList<IModelElement>(members.size());
-				for ( Object o : members ) {
-					if ( o instanceof IModelElement ) {
-						safe.add( (IModelElement) o );
-					}
-				}
-				return safe;
-			}
-		}
-		
-		@Override
-		Class<? extends IModelElement> getType() {
-			// impossible to get type of a collection as erasure removes generics info
-			return null;
-		}		
-		
-	}
-	
-	private static class GetArrayAdapter extends ChildAdapter {
-		public GetArrayAdapter(Method m) {
-			super(m);
-		}
+        if ( adapters.length == 0 )
+        {
+            return EMPTY_ELEMENTS;
+        }
 
-		@Override
-		Collection<? extends IModelElement> members(Object target) {
-			IModelElement[] array = (IModelElement[]) invoke( target, m, ZERO_ARGS );
-			if ( array == null || array.length == 0) {
-				return Collections.emptyList();
-			}
-			else {
-				return (Collection<? extends IModelElement>) Arrays.asList( array );
-			}
-		}
-		
-		@SuppressWarnings("unchecked")
-		@Override
-		Class<? extends IModelElement> getType() {
-			return (Class<? extends IModelElement>) m.getReturnType().getComponentType();
-		}
-	}
-	
-	private static class SetPropertyAdapter extends ChildAdapter {
-		public SetPropertyAdapter(Method m) {
-			super(m);
-		}
+        ArrayList<IModelElement> elements = new ArrayList<IModelElement>();
 
-		@Override
-		boolean add(Object target, IModelElement element) {
-			if ( m.getParameterTypes()[0].isAssignableFrom( element.getClass() ) ) {
-				invoke(target, m, new Object[] { element } );
-				return true;
-			}
-			else {
-				return false;
-			}
-		}
+        for ( ChildAdapter adapter : adapters )
+        {
+            elements.addAll( adapter.members( target ) );
+        }
 
-		@Override
-		boolean remove(Object target, IModelElement element) {
-			if ( m.getParameterTypes()[0].isAssignableFrom( element.getClass() ) ) {
-				invoke(target, m, new Object[] { null } );
-				return true;
-			}
-			else {
-				return false;
-			}
-		}		
-		
-		@SuppressWarnings("unchecked")
-		@Override
-		Class<? extends IModelElement> getType() {
-			return (Class<? extends IModelElement>) m.getParameterTypes()[0];
-		}		
-	}	
-	
-	private static class AddPropertyAdapter extends ChildAdapter {
-		public AddPropertyAdapter(Method m) {
-			super(m);
-		}
+        return elements.toArray( EMPTY_ELEMENTS );
+    }
 
-		@Override
-		boolean add(Object target, IModelElement element) {
-			if ( m.getParameterTypes()[0].isAssignableFrom( element.getClass() ) ) {
-				invoke(target, m, new Object[] { element } );
-				return true;
-			}
-			else {
-				return false;
-			}
-		}
-		
-		@SuppressWarnings("unchecked")
-		@Override
-		Class<? extends IModelElement> getType() {
-			return (Class<? extends IModelElement>) m.getParameterTypes()[0];
-		}		
-	}
-	
-	private static class RemovePropertyAdapter extends ChildAdapter {
 
-		public RemovePropertyAdapter(Method m) {
-			super(m);
-		}
+    public boolean addChild( IModelElement element ) throws InvalidModelException
+    {
+        if ( element.getParent() == null )
+        {
+            ChildAdapter[] adapters = cachedAdapters();
 
-		@Override
-		boolean remove(Object target, IModelElement element) {
-			if ( m.getParameterTypes()[0].isAssignableFrom( element.getClass() ) ) {
-				invoke(target, m, new Object[] { element } );
-				return true;
-			}
-			else {
-				return false;
-			}
-		}
-		
-		@SuppressWarnings("unchecked")
-		@Override
-		Class<? extends IModelElement> getType() {
-			return (Class<? extends IModelElement>) m.getParameterTypes()[0];
-		}		
-	}
-	
-	private static boolean isModelArray(Class<?> returnType) {
-		return returnType.isArray() && IModelElement.class.isAssignableFrom(returnType.getComponentType() );
-	}
+            if ( adapters.length > 0 )
+            {
+                for ( ChildAdapter adapter : adapters )
+                {
+                    if ( adapter.add( target, element ) )
+                    {
+                        element.setParent( target );
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+
+    public boolean removeChild( IModelElement element )
+    {
+        if ( element.getParent() == target )
+        {
+            ChildAdapter[] adapters = cachedAdapters();
+
+            if ( adapters.length > 0 )
+            {
+                for ( ChildAdapter adapter : adapters )
+                {
+                    if ( adapter.remove( target, element ) )
+                    {
+                        element.setParent( null );
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+
+    public Set<Class<? extends IModelElement>> getChildrenTypes( boolean required )
+    {
+        ChildAdapter[] adapters = cachedAdapters();
+
+        if ( adapters.length == 0 )
+        {
+            return Collections.emptySet();
+        }
+
+        HashSet<Class<? extends IModelElement>> types = new HashSet<Class<? extends IModelElement>>();
+
+        for ( ChildAdapter adapter : adapters )
+        {
+            if ( adapter.isRequired() == required )
+            {
+                Class<? extends IModelElement> type = adapter.getType();
+
+                if ( type != null )
+                {
+                    types.add( type );
+                }
+            }
+        }
+
+        return types;
+    }
+
+
+    private PropertyAdapter findProperty( String name, Object value )
+    {
+        PropertyAdapter[] props = propertyReference == null ? null : propertyReference.get();
+
+        if ( props == null )
+        {
+            props = cachedProps( target.getClass() );
+            propertyReference = new SoftReference<PropertyAdapter[]>( props );
+        }
+
+        for ( PropertyAdapter prop : props )
+        {
+            if ( prop.getName().equals( name )
+                && ( value == null || prop.getRawType().isAssignableFrom( value.getClass() ) ) )
+            {
+                return prop;
+            }
+        }
+
+        return null;
+    }
+
+
+    private static PropertyAdapter[] cachedProps( Class<? extends IModelElement> type )
+    {
+        SoftReference<PropertyAdapter[]> ref = propertyCache.get( type );
+
+        PropertyAdapter[] props = ref == null ? null : ref.get();
+
+        if ( props == null )
+        {
+            props = loadProps( type );
+            propertyCache.put( type, new SoftReference<PropertyAdapter[]>( props ) );
+        }
+
+        return props;
+    }
+
+
+    private static PropertyAdapter[] loadProps( Class<? extends IModelElement> type )
+    {
+        ArrayList<PropertyAdapter> props = new ArrayList<PropertyAdapter>();
+        for ( Method m : type.getMethods() )
+        {
+            if ( isValidProperty( m ) )
+            {
+                try
+                {
+                    PropertyAdapter p = new PropertyAdapter( m, type );
+                    props.add( p );
+                }
+                catch ( NoSuchMethodException e )
+                {
+                    // fine not a bean method
+                    log.finer( "Invalid bean property method " + m + ": " + e.getMessage() );
+                }
+            }
+        }
+
+        return props.toArray( EMPTY_PROPS );
+    }
+
+
+    private static boolean isValidProperty( Method m )
+    {
+        return m.getName().startsWith( "get" ) && m.getParameterTypes().length == 0
+            && !m.getDeclaringClass().equals( Object.class )
+            && !IModelElement.class.isAssignableFrom( m.getReturnType() );
+    }
+
+
+    private static String makeDefaultPropertyValue( String name )
+    {
+        return "getDefault" + capitalise( name );
+    }
+
+
+    private static String capitalise( String name )
+    {
+        return Character.toUpperCase( name.charAt( 0 ) ) + name.substring( 1 );
+    }
+
+
+    private static String decapitalise( String substring )
+    {
+        return Character.toLowerCase( substring.charAt( 0 ) ) + substring.substring( 1 );
+    }
+
+
+    private ChildAdapter[] cachedAdapters()
+    {
+        ChildAdapter[] adapters = childrenReference == null ? null : childrenReference.get();
+
+        if ( adapters == null )
+        {
+            adapters = loadAdapters( target );
+            childrenReference = new SoftReference<ChildAdapter[]>( adapters );
+        }
+
+        return adapters;
+    }
+
+
+    private static ChildAdapter[] loadAdapters( IModelElement target )
+    {
+        Class<? extends IModelElement> type = target.getClass();
+        SoftReference<ChildAdapter[]> ref = adapterCache.get( type );
+
+        ChildAdapter[] adapters = ref == null ? null : ref.get();
+
+        if ( adapters == null )
+        {
+            adapters = buildAdapters( type );
+            adapterCache.put( type, new SoftReference<ChildAdapter[]>( adapters ) );
+        }
+
+        return adapters;
+    }
+
+
+    private static ChildAdapter[] buildAdapters( Class<? extends IModelElement> type )
+    {
+        ArrayList<ChildAdapter> adapters = new ArrayList<ChildAdapter>();
+
+        for ( Method m : type.getMethods() )
+        {
+            ChildAdapter adapter = null;
+
+            if ( isValidGetProperty( m ) )
+            {
+                adapter = buildGetAdapter( m );
+            }
+            else if ( isValidSetProperty( m ) )
+            {
+                adapter = buildSetAdapter( m );
+            }
+            else if ( isValidAddProperty( m ) )
+            {
+                adapter = buildAddAdapter( m );
+            }
+            else if ( isValidRemoveProperty( m ) )
+            {
+                adapter = buildRemoveAdapter( m );
+            }
+
+            if ( adapter != null )
+            {
+                adapters.add( adapter );
+            }
+        }
+
+        return adapters.toArray( new ChildAdapter[adapters.size()] );
+    }
+
+
+    private static ChildAdapter buildGetAdapter( Method m )
+    {
+        if ( IModelElement.class.isAssignableFrom( m.getReturnType() ) )
+        {
+            return new GetPropertyAdapter( m );
+        }
+        else if ( Collection.class.isAssignableFrom( m.getReturnType() ) )
+        {
+            return new GetCollectionAdapter( m );
+        }
+        else if ( isModelArray( m.getReturnType() ) )
+        {
+            return new GetArrayAdapter( m );
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    private static ChildAdapter buildSetAdapter( Method m )
+    {
+        if ( IModelElement.class.isAssignableFrom( m.getParameterTypes()[0] ) )
+        {
+            return new SetPropertyAdapter( m );
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    private static ChildAdapter buildAddAdapter( Method m )
+    {
+        if ( IModelElement.class.isAssignableFrom( m.getParameterTypes()[0] ) )
+        {
+            return new AddPropertyAdapter( m );
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    private static ChildAdapter buildRemoveAdapter( Method m )
+    {
+        if ( IModelElement.class.isAssignableFrom( m.getParameterTypes()[0] ) )
+        {
+            return new RemovePropertyAdapter( m );
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    private static boolean isValidRemoveProperty( Method m )
+    {
+        return m.getParameterTypes().length == 1 && m.getName().startsWith( "remove" )
+            && !isDeclared( ICompoundModelElement.class, m );
+    }
+
+
+    private static boolean isValidAddProperty( Method m )
+    {
+        return m.getParameterTypes().length == 1 && m.getName().startsWith( "add" )
+            && !isDeclared( ICompoundModelElement.class, m );
+    }
+
+
+    private static boolean isDeclared( Class<? extends IModelElement> element, Method m )
+    {
+        try
+        {
+            element.getMethod( m.getName(), m.getParameterTypes() );
+            return true;
+        }
+        catch ( SecurityException e )
+        {
+            throw new UndeclaredThrowableException( e );
+        }
+        catch ( NoSuchMethodException e )
+        {
+            return false;
+        }
+    }
+
+
+    private static boolean isValidSetProperty( Method m )
+    {
+        return m.getParameterTypes().length == 1 && m.getName().startsWith( "set" )
+            && !isDeclared( IModelElement.class, m );
+    }
+
+
+    private static boolean isValidGetProperty( Method m )
+    {
+        return m.getParameterTypes().length == 0 && m.getName().startsWith( "get" )
+            && !isDeclared( IModelElement.class, m ) && !isDeclared( ICompoundModelElement.class, m );
+    }
+
+
+    private static Object invoke( Object target, Method m, Object... args )
+    {
+        try
+        {
+            return m.invoke( target, args );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            // this should already have been tested
+            throw new IllegalStateException( e );
+        }
+        catch ( IllegalAccessException e )
+        {
+            throw new UndeclaredThrowableException( e );
+        }
+        catch ( InvocationTargetException e )
+        {
+            throw new UndeclaredThrowableException( e.getCause() );
+        }
+    }
+
+    private static class PropertyAdapter
+    {
+
+        String prop;
+        String name;
+        Method g;
+        Method s;
+        Method a;
+        Method r;
+        Class<?> propertyType;
+
+
+        public PropertyAdapter( Method g, Class<?> type ) throws SecurityException, NoSuchMethodException
+        {
+            if ( g.getReturnType().isArray() || Iterable.class.isAssignableFrom( g.getReturnType() ) )
+            {
+                prop = g.getName().substring( 3 );
+                // remove trailing s - as in addWibble, removeWibble, getWibbles
+                prop = prop.substring( 0, prop.length() - 1 );
+                name = decapitalise( prop );
+                a = find( "add", prop, g.getReturnType(), type );
+                propertyType = a.getParameterTypes()[0];
+                r = find( "remove", prop, g.getReturnType(), type );
+                if ( r.getParameterTypes()[0] != propertyType )
+                {
+                    throw new NoSuchMethodException( "Add remove property method types do not match" );
+                }
+                propertyType = Array.newInstance( propertyType, 0 ).getClass();
+            }
+            else
+            {
+                prop = g.getName().substring( 3 );
+                name = decapitalise( prop );
+                propertyType = g.getReturnType();
+                s = find( "set", prop, propertyType, type );
+            }
+
+            this.g = g;
+        }
+
+
+        public Class<?> getRawType()
+        {
+            return propertyType.isArray() ? propertyType.getComponentType() : propertyType;
+        }
+
+
+        public Class<?> getPropertyType()
+        {
+            return propertyType;
+        }
+
+
+        public Method getReadMethod()
+        {
+            return g;
+        }
+
+
+        public Method getAddMethod() throws NoSuchMethodException
+        {
+            if ( a == null )
+            {
+                throw new NoSuchMethodException( "No such method add" + prop );
+            }
+
+            return a;
+        }
+
+
+        public Method getRemoveMethod() throws NoSuchMethodException
+        {
+            if ( r == null )
+            {
+                throw new NoSuchMethodException( "No such method remove" + prop );
+            }
+
+            return r;
+        }
+
+
+        public Method getWriteMethod() throws NoSuchMethodException
+        {
+            if ( s == null )
+            {
+                throw new NoSuchMethodException( "No such method set" + prop );
+            }
+
+            return s;
+        }
+
+
+        @Override
+        public String toString()
+        {
+            return "PropertyAdapter[" + name + "]";
+        }
+
+
+        private Method find( String prefix, String prop, Class<?> returnType, Class<?> type ) throws SecurityException,
+            NoSuchMethodException
+        {
+            String methodName = prefix + prop;
+
+            if ( returnType.isArray() )
+            {
+                Class<?> t = returnType.getComponentType();
+                return type.getMethod( methodName, new Class[]
+                    { t } );
+            }
+            else if ( Iterable.class.isAssignableFrom( returnType ) )
+            {
+                Method f = null;
+                for ( Method m : type.getMethods() )
+                {
+                    if ( m.getParameterTypes().length == 1 && m.getName().equals( methodName )
+                        && !IModelElement.class.isAssignableFrom( m.getParameterTypes()[0] ) )
+                    {
+                        if ( f == null )
+                        {
+                            f = m;
+                        }
+                        else
+                        {
+                            throw new NoSuchMethodException( "Found duplicate " + methodName );
+                        }
+                    }
+                }
+                if ( f == null )
+                {
+                    throw new NoSuchMethodException( "No such method " + methodName );
+                }
+
+                return f;
+            }
+            else
+            {
+                return type.getMethod( methodName, new Class[]
+                    { returnType } );
+            }
+        }
+
+
+        public String getName()
+        {
+            return name;
+        }
+
+    }
+
+    private static abstract class ChildAdapter
+    {
+        Method m;
+
+
+        ChildAdapter( Method m )
+        {
+            this.m = m;
+        }
+
+
+        public boolean isRequired()
+        {
+            return m.isAnnotationPresent( Required.class );
+        }
+
+
+        boolean add( Object target, IModelElement element )
+        {
+            return false;
+        }
+
+
+        abstract Class<? extends IModelElement> getType();
+
+
+        boolean remove( Object target, IModelElement element )
+        {
+            return false;
+        }
+
+
+        Collection<? extends IModelElement> members( Object target )
+        {
+            return Collections.emptyList();
+        }
+
+
+        @Override
+        public String toString()
+        {
+            return "ChildAdapter[ " + m.getName() + "]";
+        }
+    }
+
+    private static class GetPropertyAdapter extends ChildAdapter
+    {
+        GetPropertyAdapter( Method m )
+        {
+            super( m );
+        }
+
+
+        @Override
+        Collection<? extends IModelElement> members( Object target )
+        {
+            IModelElement member = ( IModelElement ) invoke( target, m, ZERO_ARGS );
+            if ( member == null )
+            {
+                return Collections.emptyList();
+            }
+            else
+            {
+                return Collections.<IModelElement> singleton( member );
+            }
+        }
+
+
+        @SuppressWarnings("unchecked")
+        @Override
+        Class<? extends IModelElement> getType()
+        {
+            return ( Class<? extends IModelElement> ) m.getReturnType();
+        }
+    }
+
+    private static class GetCollectionAdapter extends ChildAdapter
+    {
+        public GetCollectionAdapter( Method m )
+        {
+            super( m );
+        }
+
+
+        @SuppressWarnings("unchecked")
+        @Override
+        Collection<? extends IModelElement> members( Object target )
+        {
+            Collection members = ( Collection ) invoke( target, m, ZERO_ARGS );
+            if ( members == null )
+            {
+                return Collections.emptyList();
+            }
+            else
+            {
+                ArrayList<IModelElement> safe = new ArrayList<IModelElement>( members.size() );
+                for ( Object o : members )
+                {
+                    if ( o instanceof IModelElement )
+                    {
+                        safe.add( ( IModelElement ) o );
+                    }
+                }
+                return safe;
+            }
+        }
+
+
+        @Override
+        Class<? extends IModelElement> getType()
+        {
+            // impossible to get type of a collection as erasure removes generics info
+            return null;
+        }
+
+    }
+
+    private static class GetArrayAdapter extends ChildAdapter
+    {
+        public GetArrayAdapter( Method m )
+        {
+            super( m );
+        }
+
+
+        @Override
+        Collection<? extends IModelElement> members( Object target )
+        {
+            IModelElement[] array = ( IModelElement[] ) invoke( target, m, ZERO_ARGS );
+            if ( array == null || array.length == 0 )
+            {
+                return Collections.emptyList();
+            }
+            else
+            {
+                return ( Collection<? extends IModelElement> ) Arrays.asList( array );
+            }
+        }
+
+
+        @SuppressWarnings("unchecked")
+        @Override
+        Class<? extends IModelElement> getType()
+        {
+            return ( Class<? extends IModelElement> ) m.getReturnType().getComponentType();
+        }
+    }
+
+    private static class SetPropertyAdapter extends ChildAdapter
+    {
+        public SetPropertyAdapter( Method m )
+        {
+            super( m );
+        }
+
+
+        @Override
+        boolean add( Object target, IModelElement element )
+        {
+            if ( m.getParameterTypes()[0].isAssignableFrom( element.getClass() ) )
+            {
+                invoke( target, m, new Object[]
+                    { element } );
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+
+
+        @Override
+        boolean remove( Object target, IModelElement element )
+        {
+            if ( m.getParameterTypes()[0].isAssignableFrom( element.getClass() ) )
+            {
+                invoke( target, m, new Object[]
+                    { null } );
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+
+
+        @SuppressWarnings("unchecked")
+        @Override
+        Class<? extends IModelElement> getType()
+        {
+            return ( Class<? extends IModelElement> ) m.getParameterTypes()[0];
+        }
+    }
+
+    private static class AddPropertyAdapter extends ChildAdapter
+    {
+        public AddPropertyAdapter( Method m )
+        {
+            super( m );
+        }
+
+
+        @Override
+        boolean add( Object target, IModelElement element )
+        {
+            if ( m.getParameterTypes()[0].isAssignableFrom( element.getClass() ) )
+            {
+                invoke( target, m, new Object[]
+                    { element } );
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+
+
+        @SuppressWarnings("unchecked")
+        @Override
+        Class<? extends IModelElement> getType()
+        {
+            return ( Class<? extends IModelElement> ) m.getParameterTypes()[0];
+        }
+    }
+
+    private static class RemovePropertyAdapter extends ChildAdapter
+    {
+
+        public RemovePropertyAdapter( Method m )
+        {
+            super( m );
+        }
+
+
+        @Override
+        boolean remove( Object target, IModelElement element )
+        {
+            if ( m.getParameterTypes()[0].isAssignableFrom( element.getClass() ) )
+            {
+                invoke( target, m, new Object[]
+                    { element } );
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+
+
+        @SuppressWarnings("unchecked")
+        @Override
+        Class<? extends IModelElement> getType()
+        {
+            return ( Class<? extends IModelElement> ) m.getParameterTypes()[0];
+        }
+    }
+
+
+    private static boolean isModelArray( Class<?> returnType )
+    {
+        return returnType.isArray() && IModelElement.class.isAssignableFrom( returnType.getComponentType() );
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/OverrideOptions.java b/sigil/common/core/src/org/apache/felix/sigil/model/OverrideOptions.java
index 53db850..03661af 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/OverrideOptions.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/OverrideOptions.java
@@ -19,42 +19,54 @@
 
 package org.apache.felix.sigil.model;
 
+
 import java.util.HashMap;
 import java.util.Map;
 
+
 /**
  * @author dave
  * 
  */
-public enum OverrideOptions {
+public enum OverrideOptions
+{
     NO("no"), MAY("may"), MUST("must");
 
     private String str;
 
     private static Map<String, OverrideOptions> map = new HashMap<String, OverrideOptions>();
 
-    static {
-        for (OverrideOptions option : OverrideOptions.values()) {
-            map.put(option.str.toLowerCase(), option);
+    static
+    {
+        for ( OverrideOptions option : OverrideOptions.values() )
+        {
+            map.put( option.str.toLowerCase(), option );
         }
     }
 
-    private OverrideOptions(String str) {
+
+    private OverrideOptions( String str )
+    {
         this.str = str;
     }
 
-    public static OverrideOptions parse(String val) {
-        OverrideOptions option = map.get(val.toLowerCase());
 
-        if (option == null) {
-            throw new IllegalArgumentException("Invalid override value " + val);
+    public static OverrideOptions parse( String val )
+    {
+        OverrideOptions option = map.get( val.toLowerCase() );
+
+        if ( option == null )
+        {
+            throw new IllegalArgumentException( "Invalid override value " + val );
         }
 
         return option;
     }
-    
+
+
     @Override
-    public String toString() {
+    public String toString()
+    {
         return str;
     }
 
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/Required.java b/sigil/common/core/src/org/apache/felix/sigil/model/Required.java
index 9f40c14..24f13f5 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/Required.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/Required.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.model;
 
+
 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Inherited;
@@ -26,10 +27,12 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+
 @Inherited
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
-public @interface Required {
+public @interface Required
+{
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/And.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/And.java
index ca91ee4..9e1bc0a 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/And.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/And.java
@@ -19,81 +19,110 @@
 
 package org.apache.felix.sigil.model.common;
 
+
 import java.util.Map;
 
-public class And implements LDAPExpr {
+
+public class And implements LDAPExpr
+{
 
     /**
      */
     private static final long serialVersionUID = 1L;
     private LDAPExpr[] children;
 
-    public static LDAPExpr apply(LDAPExpr... terms) {
-        if (terms == null) {
-            throw new NullPointerException("terms cannot be null");
+
+    public static LDAPExpr apply( LDAPExpr... terms )
+    {
+        if ( terms == null )
+        {
+            throw new NullPointerException( "terms cannot be null" );
         }
-        else if (terms.length == 0) {
+        else if ( terms.length == 0 )
+        {
             return Expressions.T;
         }
-        else if (terms.length == 1) {
+        else if ( terms.length == 1 )
+        {
             return terms[0];
         }
         LDAPExpr[] filtered = new LDAPExpr[terms.length];
         int ctr = 0;
-        for (int i = 0; i < terms.length; i++) {
-            if (terms[i].equals(Expressions.F))
+        for ( int i = 0; i < terms.length; i++ )
+        {
+            if ( terms[i].equals( Expressions.F ) )
                 return Expressions.F;
-            if (terms[i].equals(Expressions.T))
+            if ( terms[i].equals( Expressions.T ) )
                 continue;
             filtered[ctr] = terms[i];
             ctr++;
         }
-        if (ctr == 0) {
+        if ( ctr == 0 )
+        {
             return Expressions.T;
         }
-        else if (ctr == 1) {
+        else if ( ctr == 1 )
+        {
             return filtered[0];
         }
         LDAPExpr[] andTerms = new LDAPExpr[ctr];
-        System.arraycopy(filtered, 0, andTerms, 0, ctr);
+        System.arraycopy( filtered, 0, andTerms, 0, ctr );
 
-        return new And(andTerms);
+        return new And( andTerms );
     }
 
-    private And(LDAPExpr... children) {
+
+    private And( LDAPExpr... children )
+    {
         this.children = children;
     }
 
-    public boolean eval(Map<String, ?> map) {
-        for (int i = 0; i < children.length; i++) {
-            if (!children[i].eval(map)) {
+
+    public boolean eval( Map<String, ?> map )
+    {
+        for ( int i = 0; i < children.length; i++ )
+        {
+            if ( !children[i].eval( map ) )
+            {
                 return false;
             }
         }
         return true;
     }
 
-    public void visit(ExprVisitor v) {
-        v.visitAnd(this);
+
+    public void visit( ExprVisitor v )
+    {
+        v.visitAnd( this );
     }
 
-    public LDAPExpr[] getChildren() {
+
+    public LDAPExpr[] getChildren()
+    {
         return children;
     }
 
-    public void setChildren(LDAPExpr[] children) {
+
+    public void setChildren( LDAPExpr[] children )
+    {
         this.children = children;
     }
 
+
     @Override
-    public boolean equals(Object other) {
-        if (other instanceof And) {
-            And that = (And) other;
-            if (children.length != that.children.length) {
+    public boolean equals( Object other )
+    {
+        if ( other instanceof And )
+        {
+            And that = ( And ) other;
+            if ( children.length != that.children.length )
+            {
                 return false;
             }
-            for (int i = 0; i < children.length; i++) {
-                if (!children[i].equals(that.children[i])) {
+            for ( int i = 0; i < children.length; i++ )
+            {
+                if ( !children[i].equals( that.children[i] ) )
+                {
                     return false;
                 }
             }
@@ -102,14 +131,17 @@
         return false;
     }
 
+
     @Override
-    public String toString() {
-        StringBuffer buf = new StringBuffer(256);
-        buf.append("(&");
-        for (int i = 0; i < children.length; i++) {
-            buf.append(" ").append(children[i]).append(" ");
+    public String toString()
+    {
+        StringBuffer buf = new StringBuffer( 256 );
+        buf.append( "(&" );
+        for ( int i = 0; i < children.length; i++ )
+        {
+            buf.append( " " ).append( children[i] ).append( " " );
         }
-        buf.append(")");
+        buf.append( ")" );
         return buf.toString();
     }
 
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/Cardinality.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/Cardinality.java
index f190de8..07220cc 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/Cardinality.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/Cardinality.java
@@ -19,135 +19,173 @@
 
 package org.apache.felix.sigil.model.common;
 
+
 import java.io.Serializable;
 
+
 /**
  * Immutable class representing cardinality constraints between two entities.
  * 
  */
-public class Cardinality implements Serializable {
+public class Cardinality implements Serializable
+{
 
     /**
      * 
      */
     private static final long serialVersionUID = 1L;
-    public static final Cardinality ZERO_TO_MANY = new Cardinality(0, -1);
-    public static final Cardinality ONE_TO_MANY = new Cardinality(1, -1);
-    public static final Cardinality ZERO_TO_ONE = new Cardinality(0, 1);
-    public static final Cardinality ONE_TO_ONE = new Cardinality(1, 1);
+    public static final Cardinality ZERO_TO_MANY = new Cardinality( 0, -1 );
+    public static final Cardinality ONE_TO_MANY = new Cardinality( 1, -1 );
+    public static final Cardinality ZERO_TO_ONE = new Cardinality( 0, 1 );
+    public static final Cardinality ONE_TO_ONE = new Cardinality( 1, 1 );
 
     private int min;
     private int max;
 
+
     /**
      * @param min
      *            >=0 (usually 0 or 1)
      * @param max
      *            >=min or -1 to indicate an unbounded maximum
      */
-    public Cardinality(int min, int max) {
-        if (min < 0) {
-            throw new IllegalArgumentException("Min cannot be less than 0");
+    public Cardinality( int min, int max )
+    {
+        if ( min < 0 )
+        {
+            throw new IllegalArgumentException( "Min cannot be less than 0" );
         }
 
-        if ((max < min) && (max != -1)) {
-            throw new IllegalArgumentException("Max cannot be less than min");
+        if ( ( max < min ) && ( max != -1 ) )
+        {
+            throw new IllegalArgumentException( "Max cannot be less than min" );
         }
 
         this.min = min;
         this.max = max;
     }
 
-    public int getMin() {
+
+    public int getMin()
+    {
         return min;
     }
 
-    public int getMax() {
+
+    public int getMax()
+    {
         return max;
     }
 
-    public String toString() {
-        return min + ".." + ((max == -1) ? ("n") : (Integer.toString(max)));
+
+    public String toString()
+    {
+        return min + ".." + ( ( max == -1 ) ? ( "n" ) : ( Integer.toString( max ) ) );
     }
 
-    public boolean isDefined(Cardinality cardinality) {
-        return (min <= cardinality.min) && ((max == -1) || (max >= cardinality.max));
+
+    public boolean isDefined( Cardinality cardinality )
+    {
+        return ( min <= cardinality.min ) && ( ( max == -1 ) || ( max >= cardinality.max ) );
     }
 
-    public boolean isSingleton() {
-        return (min == 1) && (max == 1);
+
+    public boolean isSingleton()
+    {
+        return ( min == 1 ) && ( max == 1 );
     }
 
-    public static Cardinality parse(String stringRep) throws IllegalArgumentException {
+
+    public static Cardinality parse( String stringRep ) throws IllegalArgumentException
+    {
         stringRep = stringRep.trim();
 
-        int dotdot = stringRep.indexOf("..");
+        int dotdot = stringRep.indexOf( ".." );
 
-        if (dotdot == -1) {
-            throw new IllegalArgumentException("Invalid cardinality string representation, expected ..");
+        if ( dotdot == -1 )
+        {
+            throw new IllegalArgumentException( "Invalid cardinality string representation, expected .." );
         }
 
-        String minStr = stringRep.substring(0, dotdot);
-        String maxStr = stringRep.substring(dotdot + 2);
+        String minStr = stringRep.substring( 0, dotdot );
+        String maxStr = stringRep.substring( dotdot + 2 );
 
-        int min = Integer.parseInt(minStr);
+        int min = Integer.parseInt( minStr );
         int max = min;
 
-        if ("n".equals(maxStr)) {
+        if ( "n".equals( maxStr ) )
+        {
             max = -1;
         }
-        else {
-            max = Integer.parseInt(maxStr);
+        else
+        {
+            max = Integer.parseInt( maxStr );
         }
 
-        return cardinality(min, max);
+        return cardinality( min, max );
     }
 
-    public static Cardinality cardinality(int min, int max) {
+
+    public static Cardinality cardinality( int min, int max )
+    {
         Cardinality c = null;
 
-        if (min == 0) {
-            if (max == 1) {
+        if ( min == 0 )
+        {
+            if ( max == 1 )
+            {
                 c = ZERO_TO_ONE;
             }
-            else if (max == -1) {
+            else if ( max == -1 )
+            {
                 c = ZERO_TO_MANY;
             }
         }
-        else if (min == 1) {
-            if (max == 1) {
+        else if ( min == 1 )
+        {
+            if ( max == 1 )
+            {
                 c = ONE_TO_ONE;
             }
-            else if (max == -1) {
+            else if ( max == -1 )
+            {
                 c = ONE_TO_MANY;
             }
         }
 
-        if (c == null)
-            c = new Cardinality(min, max);
+        if ( c == null )
+            c = new Cardinality( min, max );
 
         return c;
     }
 
-    public int hashCode() {
+
+    public int hashCode()
+    {
         return max ^ min;
     }
 
-    public boolean equals(Object o) {
-        if (o == this) {
+
+    public boolean equals( Object o )
+    {
+        if ( o == this )
+        {
             return true;
         }
 
-        if (o == null) {
+        if ( o == null )
+        {
             return false;
         }
 
-        try {
-            Cardinality c = (Cardinality) o;
+        try
+        {
+            Cardinality c = ( Cardinality ) o;
 
-            return (min == c.min) && (max == c.max);
+            return ( min == c.min ) && ( max == c.max );
         }
-        catch (ClassCastException cce) {
+        catch ( ClassCastException cce )
+        {
             return false;
         }
     }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/ExprVisitor.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/ExprVisitor.java
index bc7ced6..4a1b95c 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/ExprVisitor.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/ExprVisitor.java
@@ -19,12 +19,22 @@
 
 package org.apache.felix.sigil.model.common;
 
-public interface ExprVisitor {
 
-    void visitAnd(And a);
-    void visitOr(Or o);
-    void visitNot(Not n);
-    void visitSimple(SimpleTerm st);
+public interface ExprVisitor
+{
+
+    void visitAnd( And a );
+
+
+    void visitOr( Or o );
+
+
+    void visitNot( Not n );
+
+
+    void visitSimple( SimpleTerm st );
+
+
     // if none of the above matches use this
-    void visitAny(LDAPExpr ex);
+    void visitAny( LDAPExpr ex );
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/Expressions.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/Expressions.java
index 6bc0987..976d4b5 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/Expressions.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/Expressions.java
@@ -19,61 +19,82 @@
 
 package org.apache.felix.sigil.model.common;
 
+
 import java.util.Map;
 
-public class Expressions {
 
-    public static LDAPExpr and(LDAPExpr... terms) {
-        return And.apply(terms);
+public class Expressions
+{
+
+    public static LDAPExpr and( LDAPExpr... terms )
+    {
+        return And.apply( terms );
     }
 
-    public static LDAPExpr or(LDAPExpr... terms) {
-        return Or.apply(terms);
+
+    public static LDAPExpr or( LDAPExpr... terms )
+    {
+        return Or.apply( terms );
     }
 
-    public static LDAPExpr not(LDAPExpr e) {
-        return Not.apply(e);
+
+    public static LDAPExpr not( LDAPExpr e )
+    {
+        return Not.apply( e );
     }
 
     public static LDAPExpr T = Bool.TRUE;
     public static LDAPExpr F = Bool.FALSE;
 
-    // supports direct use of wildcards for ease of testing, but not literal *s
-    public static SimpleTerm ex(String name, Ops op, String rhs) {
 
-        rhs = rhs.replace('*', SimpleTerm.WILDCARD);
-        return new SimpleTerm(name, op, rhs);
+    // supports direct use of wildcards for ease of testing, but not literal *s
+    public static SimpleTerm ex( String name, Ops op, String rhs )
+    {
+
+        rhs = rhs.replace( '*', SimpleTerm.WILDCARD );
+        return new SimpleTerm( name, op, rhs );
     }
 
 }
 
-class Bool implements LDAPExpr {
+class Bool implements LDAPExpr
+{
 
     /**
      * 
      */
     private static final long serialVersionUID = 1L;
-    public static final Bool TRUE = new Bool(true);
-    public static final Bool FALSE = new Bool(false);
+    public static final Bool TRUE = new Bool( true );
+    public static final Bool FALSE = new Bool( false );
 
     private boolean bool;
 
-    public Bool(boolean bool) {
+
+    public Bool( boolean bool )
+    {
         this.bool = bool;
     }
 
-    public boolean eval(Map<String, ?> map) {
+
+    public boolean eval( Map<String, ?> map )
+    {
         return bool;
     }
 
-    public void visit(ExprVisitor v) {
+
+    public void visit( ExprVisitor v )
+    {
     }
 
-    public LDAPExpr[] getChildren() {
+
+    public LDAPExpr[] getChildren()
+    {
         return CHILDLESS;
     }
 
-    public String toString() {
+
+    public String toString()
+    {
         return "(" + bool + ")";
     }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/FilterValidator.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/FilterValidator.java
index b6c6863..a5bbb1d 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/FilterValidator.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/FilterValidator.java
@@ -19,15 +19,20 @@
 
 package org.apache.felix.sigil.model.common;
 
-public interface FilterValidator {
+
+public interface FilterValidator
+{
 
     public static FilterValidator ACCEPT_ALL = new AcceptEverythingValidator();
 
-    boolean validate(LDAPExpr filter);
 
-    static class AcceptEverythingValidator implements FilterValidator {
+    boolean validate( LDAPExpr filter );
 
-        public boolean validate(LDAPExpr filter) {
+    static class AcceptEverythingValidator implements FilterValidator
+    {
+
+        public boolean validate( LDAPExpr filter )
+        {
             return true;
         }
 
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/LDAPExpr.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/LDAPExpr.java
index 13bced3..8e9214c 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/LDAPExpr.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/LDAPExpr.java
@@ -19,21 +19,30 @@
 
 package org.apache.felix.sigil.model.common;
 
+
 import java.io.Serializable;
 import java.util.Map;
 
-public interface LDAPExpr extends Serializable {
 
-    public static final LDAPExpr[] CHILDLESS = new LDAPExpr[] {};
+public interface LDAPExpr extends Serializable
+{
+
+    public static final LDAPExpr[] CHILDLESS = new LDAPExpr[]
+        {};
     public static LDAPExpr ACCEPT_ALL = Expressions.T;
 
+
     LDAPExpr[] getChildren();
 
-    void visit(ExprVisitor v);
 
-    boolean equals(Object other);
+    void visit( ExprVisitor v );
+
+
+    boolean equals( Object other );
+
 
     int hashCode();
 
-    boolean eval(Map<String, ?> map);
+
+    boolean eval( Map<String, ?> map );
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/LDAPParseException.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/LDAPParseException.java
index 85ea519..b72aa2f 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/LDAPParseException.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/LDAPParseException.java
@@ -19,7 +19,9 @@
 
 package org.apache.felix.sigil.model.common;
 
-public class LDAPParseException extends Exception {
+
+public class LDAPParseException extends Exception
+{
 
     /**
      * 
@@ -27,31 +29,39 @@
     private static final long serialVersionUID = 1L;
 
     private ParseState ps;
-    private static final String LINE_SEPARATOR = System.getProperty("line.separator", "\\r\\n");
+    private static final String LINE_SEPARATOR = System.getProperty( "line.separator", "\\r\\n" );
 
-    public LDAPParseException(String message, ParseState ps) {
-        super(message);
+
+    public LDAPParseException( String message, ParseState ps )
+    {
+        super( message );
         this.ps = ps;
     }
 
-    public LDAPParseException(String message) {
-        super(message);
+
+    public LDAPParseException( String message )
+    {
+        super( message );
     }
 
+
     @Override
-    public String getMessage() {
-        if (ps == null) {
+    public String getMessage()
+    {
+        if ( ps == null )
+        {
             return super.getMessage();
         }
 
         String basicMessage = super.getMessage();
-        StringBuffer buf = new StringBuffer(basicMessage.length() + ps.str.length() * 2);
-        buf.append(basicMessage).append(LINE_SEPARATOR);
-        buf.append(ps.str).append(LINE_SEPARATOR);
-        for (int i = 0; i < ps.pos; i++) {
-            buf.append(" ");
+        StringBuffer buf = new StringBuffer( basicMessage.length() + ps.str.length() * 2 );
+        buf.append( basicMessage ).append( LINE_SEPARATOR );
+        buf.append( ps.str ).append( LINE_SEPARATOR );
+        for ( int i = 0; i < ps.pos; i++ )
+        {
+            buf.append( " " );
         }
-        buf.append("^");
+        buf.append( "^" );
         return buf.toString();
     }
 
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/LDAPParser.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/LDAPParser.java
index 8c4a9df..98b4bda 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/LDAPParser.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/LDAPParser.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.model.common;
 
+
 import static org.apache.felix.sigil.model.common.Expressions.and;
 import static org.apache.felix.sigil.model.common.Expressions.not;
 import static org.apache.felix.sigil.model.common.Expressions.or;
@@ -32,193 +33,244 @@
 import java.util.ArrayList;
 import java.util.List;
 
-public class LDAPParser {
+
+public class LDAPParser
+{
 
     private static final LDAPParser parser = new LDAPParser();
 
-    public static LDAPExpr parseExpression(String strExpr) throws LDAPParseException {
-        return parser.parse(strExpr);
+
+    public static LDAPExpr parseExpression( String strExpr ) throws LDAPParseException
+    {
+        return parser.parse( strExpr );
     }
 
-    public static void main(String[] args) {
-        for (String arg : args) {
-            try {
-                System.out.println(parseExpression(arg));
+
+    public static void main( String[] args )
+    {
+        for ( String arg : args )
+        {
+            try
+            {
+                System.out.println( parseExpression( arg ) );
             }
-            catch (LDAPParseException e) {
-                System.out.println("Failed to parse " + arg);
+            catch ( LDAPParseException e )
+            {
+                System.out.println( "Failed to parse " + arg );
                 e.printStackTrace();
             }
         }
     }
 
-    public LDAPExpr parse(String strExpr) throws LDAPParseException {
 
-        if (strExpr == null || strExpr.trim().length() == 0) {
+    public LDAPExpr parse( String strExpr ) throws LDAPParseException
+    {
+
+        if ( strExpr == null || strExpr.trim().length() == 0 )
+        {
             return LDAPExpr.ACCEPT_ALL;
         }
 
-        ParseState ps = new ParseState(strExpr);
-        LDAPExpr expr = parseExpr(ps);
+        ParseState ps = new ParseState( strExpr );
+        LDAPExpr expr = parseExpr( ps );
         ps.skipWhitespace();
-        if (!ps.isEndOfString()) {
-            error("expected end of expression ", ps);
+        if ( !ps.isEndOfString() )
+        {
+            error( "expected end of expression ", ps );
         }
         return expr;
     }
 
-    public LDAPExpr parseExpr(ParseState ps) throws LDAPParseException {
+
+    public LDAPExpr parseExpr( ParseState ps ) throws LDAPParseException
+    {
         ps.skipWhitespace();
-        if (!(ps.peek() == '(')) {
-            error("expected (", ps);
+        if ( !( ps.peek() == '(' ) )
+        {
+            error( "expected (", ps );
         }
         ps.read();
         LDAPExpr expr = null;
         ps.skipWhitespace();
         char ch = ps.peek();
-        switch (ch) {
-        case '&':
-            ps.readAndSkipWhiteSpace();
-            List<LDAPExpr> andList = new ArrayList<LDAPExpr>();
-            while (ps.peek() == '(') {
-                andList.add(parseExpr(ps));
-                ps.skipWhitespace();
-            }
-            LDAPExpr[] andArr = andList.toArray(new LDAPExpr[andList.size()]);
-            expr = and(andArr);
-            break;
-        case '|':
-            ps.readAndSkipWhiteSpace();
-            List<LDAPExpr> orList = new ArrayList<LDAPExpr>();
-            while (ps.peek() == '(') {
-                orList.add(parseExpr(ps));
-                ps.skipWhitespace();
-            }
-            LDAPExpr[] orArray = orList.toArray(new LDAPExpr[orList.size()]);
-            expr = or(orArray);
-            break;
-        case '!':
-            ps.readAndSkipWhiteSpace();
-            expr = not(parseExpr(ps));
-            break;
-        default:
-            if (isNameChar(ch)) {
-                expr = parseSimple(ps);
-            }
-            else {
-                error("unexpected character: '" + ch + "'", ps);
-            }
+        switch ( ch )
+        {
+            case '&':
+                ps.readAndSkipWhiteSpace();
+                List<LDAPExpr> andList = new ArrayList<LDAPExpr>();
+                while ( ps.peek() == '(' )
+                {
+                    andList.add( parseExpr( ps ) );
+                    ps.skipWhitespace();
+                }
+                LDAPExpr[] andArr = andList.toArray( new LDAPExpr[andList.size()] );
+                expr = and( andArr );
+                break;
+            case '|':
+                ps.readAndSkipWhiteSpace();
+                List<LDAPExpr> orList = new ArrayList<LDAPExpr>();
+                while ( ps.peek() == '(' )
+                {
+                    orList.add( parseExpr( ps ) );
+                    ps.skipWhitespace();
+                }
+                LDAPExpr[] orArray = orList.toArray( new LDAPExpr[orList.size()] );
+                expr = or( orArray );
+                break;
+            case '!':
+                ps.readAndSkipWhiteSpace();
+                expr = not( parseExpr( ps ) );
+                break;
+            default:
+                if ( isNameChar( ch ) )
+                {
+                    expr = parseSimple( ps );
+                }
+                else
+                {
+                    error( "unexpected character: '" + ch + "'", ps );
+                }
         }
         ps.skipWhitespace();
-        if (ps.peek() != ')') {
-            error("expected )", ps);
+        if ( ps.peek() != ')' )
+        {
+            error( "expected )", ps );
         }
         ps.read();
         return expr;
 
     }
 
-    void error(String message, ParseState ps) throws LDAPParseException {
-        throw new LDAPParseException(message, ps);
+
+    void error( String message, ParseState ps ) throws LDAPParseException
+    {
+        throw new LDAPParseException( message, ps );
     }
 
-    private SimpleTerm parseSimple(ParseState ps) throws LDAPParseException {
+
+    private SimpleTerm parseSimple( ParseState ps ) throws LDAPParseException
+    {
         // read name
-        StringBuffer name = new StringBuffer(16);
-        for (char c = ps.peek(); !ps.isEndOfString() && isNameChar(c); c = ps.peek()) {
+        StringBuffer name = new StringBuffer( 16 );
+        for ( char c = ps.peek(); !ps.isEndOfString() && isNameChar( c ); c = ps.peek() )
+        {
             ps.read();
-            name.append(c);
+            name.append( c );
         }
         ps.skipWhitespace();
         Ops op = null;
         // read op
-        if (ps.lookingAt("=")) {
+        if ( ps.lookingAt( "=" ) )
+        {
             op = EQ;
-            ps.skip(1);
+            ps.skip( 1 );
         }
-        else if (ps.lookingAt(">=")) {
+        else if ( ps.lookingAt( ">=" ) )
+        {
             op = GE;
-            ps.skip(2);
+            ps.skip( 2 );
         }
-        else if (ps.lookingAt("<=")) {
+        else if ( ps.lookingAt( "<=" ) )
+        {
             op = LE;
-            ps.skip(2);
+            ps.skip( 2 );
         }
-        else if (ps.lookingAt(">")) {
+        else if ( ps.lookingAt( ">" ) )
+        {
             op = GT;
-            ps.skip(1);
+            ps.skip( 1 );
         }
-        else if (ps.lookingAt("<")) {
+        else if ( ps.lookingAt( "<" ) )
+        {
             op = LT;
-            ps.skip(1);
+            ps.skip( 1 );
         }
-        else if (ps.lookingAt("-=")) {
+        else if ( ps.lookingAt( "-=" ) )
+        {
             op = APPROX;
-            ps.skip(2);
+            ps.skip( 2 );
         }
-        else if (ps.isEndOfString()) {
-            error("unexpected end of expression", ps);
+        else if ( ps.isEndOfString() )
+        {
+            error( "unexpected end of expression", ps );
         }
-        else {
-            error("unexpected character: '" + ps.peek() + "'", ps);
+        else
+        {
+            error( "unexpected character: '" + ps.peek() + "'", ps );
         }
         ps.skipWhitespace();
 
         boolean escaped = false;
-        StringBuffer value = new StringBuffer(16);
+        StringBuffer value = new StringBuffer( 16 );
 
-        while (!ps.isEndOfString() && !Character.isWhitespace(ps.peek()) && !(ps.peek() == ')' && !escaped)) {
+        while ( !ps.isEndOfString() && !Character.isWhitespace( ps.peek() ) && !( ps.peek() == ')' && !escaped ) )
+        {
 
             char ch = ps.peek();
 
-            if (ch == '\\') {
+            if ( ch == '\\' )
+            {
                 escaped = true;
                 ps.read();
             }
-            else if (ch == '*') {
-                if (escaped) {
-                    value.append(ch);
+            else if ( ch == '*' )
+            {
+                if ( escaped )
+                {
+                    value.append( ch );
                     escaped = false;
                 }
-                else {
-                    value.append(SimpleTerm.WILDCARD);
+                else
+                {
+                    value.append( SimpleTerm.WILDCARD );
                 }
                 ps.read();
             }
-            else if (isLiteralValue(ch)) {
-                if (escaped) {
-                    error("incorrectly applied escape of '" + ch + "'", ps);
+            else if ( isLiteralValue( ch ) )
+            {
+                if ( escaped )
+                {
+                    error( "incorrectly applied escape of '" + ch + "'", ps );
                 }
-                value.append(ps.read());
+                value.append( ps.read() );
             }
-            else if (isEscapedValue(ch)) {
-                if (!escaped) {
-                    error("missing escape for '" + ch + "'", ps);
+            else if ( isEscapedValue( ch ) )
+            {
+                if ( !escaped )
+                {
+                    error( "missing escape for '" + ch + "'", ps );
                 }
-                value.append(ps.read());
+                value.append( ps.read() );
                 escaped = false;
             }
-            else {
-                error("unexpected character: '" + ps.peek() + "'", ps);
+            else
+            {
+                error( "unexpected character: '" + ps.peek() + "'", ps );
             }
         }
         ps.skipWhitespace();
 
-        SimpleTerm expr = new SimpleTerm(name.toString(), op, value.toString());
+        SimpleTerm expr = new SimpleTerm( name.toString(), op, value.toString() );
 
         return expr;
     }
 
-    private boolean isNameChar(int ch) {
-        return !(Character.isWhitespace(ch) || (ch == '(') || (ch == ')') || (ch == '<') || (ch == '>') || (ch == '=')
-                || (ch == '~') || (ch == '*') || (ch == '\\'));
+
+    private boolean isNameChar( int ch )
+    {
+        return !( Character.isWhitespace( ch ) || ( ch == '(' ) || ( ch == ')' ) || ( ch == '<' ) || ( ch == '>' )
+            || ( ch == '=' ) || ( ch == '~' ) || ( ch == '*' ) || ( ch == '\\' ) );
     }
 
-    private boolean isLiteralValue(int ch) {
-        return !(Character.isWhitespace(ch) || (ch == '(') || (ch == ')') || (ch == '*'));
+
+    private boolean isLiteralValue( int ch )
+    {
+        return !( Character.isWhitespace( ch ) || ( ch == '(' ) || ( ch == ')' ) || ( ch == '*' ) );
     }
 
-    private boolean isEscapedValue(int ch) {
-        return (ch == '(') || (ch == ')') || (ch == '*');
+
+    private boolean isEscapedValue( int ch )
+    {
+        return ( ch == '(' ) || ( ch == ')' ) || ( ch == '*' );
     }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/Not.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/Not.java
index 2ef43c5..f8cd608 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/Not.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/Not.java
@@ -19,9 +19,12 @@
 
 package org.apache.felix.sigil.model.common;
 
+
 import java.util.Map;
 
-public class Not implements LDAPExpr {
+
+public class Not implements LDAPExpr
+{
 
     /**
      * 
@@ -29,58 +32,82 @@
     private static final long serialVersionUID = 1L;
     private LDAPExpr[] children;
 
-    public static LDAPExpr apply(LDAPExpr e) {
-        if (e == null) {
-            throw new NullPointerException("cannot apply Not to a null expression");
+
+    public static LDAPExpr apply( LDAPExpr e )
+    {
+        if ( e == null )
+        {
+            throw new NullPointerException( "cannot apply Not to a null expression" );
         }
-        if (e.equals(Expressions.T)) {
+        if ( e.equals( Expressions.T ) )
+        {
             return Expressions.F;
         }
-        if (e.equals(Expressions.F)) {
+        if ( e.equals( Expressions.F ) )
+        {
             return Expressions.T;
         }
-        return new Not(e);
+        return new Not( e );
     }
 
-    private Not(LDAPExpr child) {
-        this.children = new LDAPExpr[] { child };
+
+    private Not( LDAPExpr child )
+    {
+        this.children = new LDAPExpr[]
+            { child };
     }
 
-    public boolean eval(Map<String, ?> map) {
-        return !children[0].eval(map);
+
+    public boolean eval( Map<String, ?> map )
+    {
+        return !children[0].eval( map );
     }
 
-    public LDAPExpr getEx() {
+
+    public LDAPExpr getEx()
+    {
         return children[0];
     }
 
-    public void visit(ExprVisitor v) {
-        v.visitNot(this);
+
+    public void visit( ExprVisitor v )
+    {
+        v.visitNot( this );
     }
 
-    public LDAPExpr[] getChildren() {
+
+    public LDAPExpr[] getChildren()
+    {
         return children;
     }
 
-    public void setChild(LDAPExpr child) {
-        this.children = new LDAPExpr[] { child };
+
+    public void setChild( LDAPExpr child )
+    {
+        this.children = new LDAPExpr[]
+            { child };
     }
 
+
     @Override
-    public boolean equals(Object other) {
-        if (other instanceof Not) {
-            Not that = (Not) other;
-            return children[0].equals(that.children[0]);
+    public boolean equals( Object other )
+    {
+        if ( other instanceof Not )
+        {
+            Not that = ( Not ) other;
+            return children[0].equals( that.children[0] );
         }
         return false;
     }
 
+
     @Override
-    public String toString() {
-        StringBuffer buf = new StringBuffer(256);
-        buf.append("(!");
-        buf.append(" ").append(children[0]).append(" ");
-        buf.append(")");
+    public String toString()
+    {
+        StringBuffer buf = new StringBuffer( 256 );
+        buf.append( "(!" );
+        buf.append( " " ).append( children[0] ).append( " " );
+        buf.append( ")" );
         return buf.toString();
     }
 
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/Ops.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/Ops.java
index ed913bc..29a0a8c 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/Ops.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/Ops.java
@@ -19,26 +19,30 @@
 
 package org.apache.felix.sigil.model.common;
 
-public enum Ops {
+
+public enum Ops
+{
     EQ, GE, LE, GT, LT, APPROX;
 
     @Override
-    public String toString() {
-        switch (this) {
-        case EQ:
-            return "=";
-        case GE:
-            return ">=";
-        case LE:
-            return "<=";
-        case GT:
-            return ">";
-        case LT:
-            return "<";
-        case APPROX:
-            return "~=";
-        default:
-            return super.toString();
+    public String toString()
+    {
+        switch ( this )
+        {
+            case EQ:
+                return "=";
+            case GE:
+                return ">=";
+            case LE:
+                return "<=";
+            case GT:
+                return ">";
+            case LT:
+                return "<";
+            case APPROX:
+                return "~=";
+            default:
+                return super.toString();
         }
     }
 
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/Or.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/Or.java
index a50a5b9..dc4af04 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/Or.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/Or.java
@@ -19,9 +19,12 @@
 
 package org.apache.felix.sigil.model.common;
 
+
 import java.util.Map;
 
-public class Or implements LDAPExpr {
+
+public class Or implements LDAPExpr
+{
 
     /**
      * 
@@ -29,72 +32,98 @@
     private static final long serialVersionUID = 1L;
     private LDAPExpr[] children;
 
-    public static LDAPExpr apply(LDAPExpr... terms) {
-        if (terms == null) {
-            throw new NullPointerException("terms cannot be null");
+
+    public static LDAPExpr apply( LDAPExpr... terms )
+    {
+        if ( terms == null )
+        {
+            throw new NullPointerException( "terms cannot be null" );
         }
-        else if (terms.length == 0) {
+        else if ( terms.length == 0 )
+        {
             return Expressions.T;
         }
-        else if (terms.length == 1) {
+        else if ( terms.length == 1 )
+        {
             return terms[0];
         }
         LDAPExpr[] filtered = new LDAPExpr[terms.length];
         int ctr = 0;
-        for (int i = 0; i < terms.length; i++) {
-            if (terms[i].equals(Expressions.T))
+        for ( int i = 0; i < terms.length; i++ )
+        {
+            if ( terms[i].equals( Expressions.T ) )
                 return Expressions.T;
-            if (terms[i].equals(Expressions.F))
+            if ( terms[i].equals( Expressions.F ) )
                 continue;
             filtered[ctr] = terms[i];
             ctr++;
         }
-        if (ctr == 0) {
+        if ( ctr == 0 )
+        {
             return Expressions.F;
         }
-        else if (ctr == 1) {
+        else if ( ctr == 1 )
+        {
             return filtered[0];
         }
         LDAPExpr[] orTerms = new LDAPExpr[ctr];
-        System.arraycopy(filtered, 0, orTerms, 0, ctr);
+        System.arraycopy( filtered, 0, orTerms, 0, ctr );
 
-        return new Or(orTerms);
+        return new Or( orTerms );
     }
 
-    private Or(LDAPExpr... children) {
+
+    private Or( LDAPExpr... children )
+    {
         this.children = children;
     }
 
-    public boolean eval(Map<String, ?> map) {
-        for (int i = 0; i < children.length; i++) {
-            if (children[i].eval(map)) {
+
+    public boolean eval( Map<String, ?> map )
+    {
+        for ( int i = 0; i < children.length; i++ )
+        {
+            if ( children[i].eval( map ) )
+            {
                 return true;
             }
         }
         return false;
     }
 
-    public void visit(ExprVisitor v) {
-        v.visitOr(this);
+
+    public void visit( ExprVisitor v )
+    {
+        v.visitOr( this );
     }
 
-    public LDAPExpr[] getChildren() {
+
+    public LDAPExpr[] getChildren()
+    {
         return children;
     }
 
-    public void setChildren(LDAPExpr[] children) {
+
+    public void setChildren( LDAPExpr[] children )
+    {
         this.children = children;
     }
 
+
     @Override
-    public boolean equals(Object other) {
-        if (other instanceof Or) {
-            Or that = (Or) other;
-            if (children.length != that.children.length) {
+    public boolean equals( Object other )
+    {
+        if ( other instanceof Or )
+        {
+            Or that = ( Or ) other;
+            if ( children.length != that.children.length )
+            {
                 return false;
             }
-            for (int i = 0; i < children.length; i++) {
-                if (children[i].equals(that.children[i])) {
+            for ( int i = 0; i < children.length; i++ )
+            {
+                if ( children[i].equals( that.children[i] ) )
+                {
                     return true;
                 }
             }
@@ -103,14 +132,17 @@
         return false;
     }
 
+
     @Override
-    public String toString() {
-        StringBuffer buf = new StringBuffer(256);
-        buf.append("(|");
-        for (int i = 0; i < children.length; i++) {
-            buf.append(" ").append(children[i]).append(" ");
+    public String toString()
+    {
+        StringBuffer buf = new StringBuffer( 256 );
+        buf.append( "(|" );
+        for ( int i = 0; i < children.length; i++ )
+        {
+            buf.append( " " ).append( children[i] ).append( " " );
         }
-        buf.append(")");
+        buf.append( ")" );
         return buf.toString();
     }
 
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/ParseState.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/ParseState.java
index 2a839cd..298cd7f 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/ParseState.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/ParseState.java
@@ -19,13 +19,16 @@
 
 package org.apache.felix.sigil.model.common;
 
+
 import java.io.Serializable;
 
+
 /**
  * @author dave
  * 
  */
-class ParseState implements Serializable {
+class ParseState implements Serializable
+{
     /**
      * 
      */
@@ -35,48 +38,67 @@
 
     String str;
 
-    ParseState(String str) {
+
+    ParseState( String str )
+    {
         this.str = str;
     }
 
-    public boolean lookingAt(String start) {
-        return str.substring(pos).startsWith(start);
+
+    public boolean lookingAt( String start )
+    {
+        return str.substring( pos ).startsWith( start );
     }
 
-    public CharSequence skip(int n) {
+
+    public CharSequence skip( int n )
+    {
         int end = pos + n < str.length() ? pos + n : str.length();
         int start = pos;
         pos = end;
-        return str.subSequence(start, end);
+        return str.subSequence( start, end );
     }
 
-    public char read() {
-        char ch = str.charAt(pos);
-        if (pos < str.length()) {
+
+    public char read()
+    {
+        char ch = str.charAt( pos );
+        if ( pos < str.length() )
+        {
             pos++;
         }
         return ch;
     }
 
-    public char readAndSkipWhiteSpace() {
+
+    public char readAndSkipWhiteSpace()
+    {
         char ch = read();
         skipWhitespace();
         return ch;
     }
 
-    char peek() {
-        if (isEndOfString()) {
-            return (char) -1;
+
+    char peek()
+    {
+        if ( isEndOfString() )
+        {
+            return ( char ) -1;
         }
-        return str.charAt(pos);
+        return str.charAt( pos );
     }
 
-    boolean isEndOfString() {
+
+    boolean isEndOfString()
+    {
         return pos == str.length();
     }
 
-    void skipWhitespace() {
-        while (pos < str.length() && Character.isWhitespace(str.charAt(pos))) {
+
+    void skipWhitespace()
+    {
+        while ( pos < str.length() && Character.isWhitespace( str.charAt( pos ) ) )
+        {
             pos++;
         }
     }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/SimpleTerm.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/SimpleTerm.java
index 038676e..a347539 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/SimpleTerm.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/SimpleTerm.java
@@ -19,261 +19,333 @@
 
 package org.apache.felix.sigil.model.common;
 
+
 import java.lang.reflect.Constructor;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Vector;
 
-public class SimpleTerm implements LDAPExpr {
+
+public class SimpleTerm implements LDAPExpr
+{
 
     /**
      * 
      */
     private static final long serialVersionUID = 1L;
     public static final char WILDCARD = 2 ^ 16 - 1;
-    private static final String WILDCARD_STRING = new String(new char[] { SimpleTerm.WILDCARD });
+    private static final String WILDCARD_STRING = new String( new char[]
+        { SimpleTerm.WILDCARD } );
 
     private Ops op;
     private String name;
     private String rval;
 
-    public SimpleTerm(String name, Ops op, String value) {
+
+    public SimpleTerm( String name, Ops op, String value )
+    {
         this.op = op;
         this.name = name.intern();
         this.rval = value.intern();
     }
 
-    public String getName() {
+
+    public String getName()
+    {
         return name;
     }
 
-    public Ops getOp() {
+
+    public Ops getOp()
+    {
         return op;
     }
 
-    public String getRval() {
+
+    public String getRval()
+    {
         return rval;
     }
 
-    public boolean eval(Map<String, ?> map) {
 
-        Object lval = map.get(name);
-        if (lval == null) {
+    public boolean eval( Map<String, ?> map )
+    {
+
+        Object lval = map.get( name );
+        if ( lval == null )
+        {
             return false;
         }
-        else if (Ops.EQ == op && WILDCARD_STRING.equals(lval)) {
+        else if ( Ops.EQ == op && WILDCARD_STRING.equals( lval ) )
+        {
             return true;
         }
         // any match in the vector will do
-        else if (lval instanceof Vector<?>) {
-            Vector<?> vec = (Vector<?>) lval;
-            for (Iterator<?> i = vec.iterator(); i.hasNext();) {
-                if (check(i.next())) {
+        else if ( lval instanceof Vector<?> )
+        {
+            Vector<?> vec = ( Vector<?> ) lval;
+            for ( Iterator<?> i = vec.iterator(); i.hasNext(); )
+            {
+                if ( check( i.next() ) )
+                {
                     return true;
                 }
             }
             return false;
         }
         // any match in the array will do
-        else if (lval instanceof Object[]) {
-            Object[] arr = (Object[]) lval;
-            for (int i = 0; i < arr.length; i++) {
-                if (check(arr[i])) {
+        else if ( lval instanceof Object[] )
+        {
+            Object[] arr = ( Object[] ) lval;
+            for ( int i = 0; i < arr.length; i++ )
+            {
+                if ( check( arr[i] ) )
+                {
                     return true;
                 }
             }
             return false;
         }
-        return check(lval);
+        return check( lval );
     }
 
+
     @SuppressWarnings("unchecked")
-    private boolean check(Object lval) {
-        if (lval == null) {
+    private boolean check( Object lval )
+    {
+        if ( lval == null )
+        {
             return false;
         }
-        else if (Ops.EQ == op && WILDCARD_STRING.equals(lval)) {
+        else if ( Ops.EQ == op && WILDCARD_STRING.equals( lval ) )
+        {
             return true;
         }
 
         Object rhs = null;
 
-        if (lval instanceof String) {
+        if ( lval instanceof String )
+        {
 
-            if (Ops.APPROX == op) {
-                rhs = collapseWhiteSpace(rval);
-                lval = collapseWhiteSpace((String) lval);
+            if ( Ops.APPROX == op )
+            {
+                rhs = collapseWhiteSpace( rval );
+                lval = collapseWhiteSpace( ( String ) lval );
             }
 
-            if (Ops.EQ == op || Ops.APPROX == op) {
-                return stringCheck((String) lval);
+            if ( Ops.EQ == op || Ops.APPROX == op )
+            {
+                return stringCheck( ( String ) lval );
             }
             // rhs already a string
 
         }
-        else if (lval.getClass() == Byte.class) {
-            rhs = Byte.valueOf(rval);
+        else if ( lval.getClass() == Byte.class )
+        {
+            rhs = Byte.valueOf( rval );
         }
-        else if (lval.getClass() == Short.class) {
-            rhs = Short.valueOf(rval);
+        else if ( lval.getClass() == Short.class )
+        {
+            rhs = Short.valueOf( rval );
         }
-        else if (lval.getClass() == Integer.class) {
-            rhs = Integer.valueOf(rval);
+        else if ( lval.getClass() == Integer.class )
+        {
+            rhs = Integer.valueOf( rval );
         }
-        else if (lval.getClass() == Long.class) {
-            rhs = Long.valueOf(rval);
+        else if ( lval.getClass() == Long.class )
+        {
+            rhs = Long.valueOf( rval );
         }
-        else if (lval.getClass() == Float.class) {
-            rhs = Float.valueOf(rval);
+        else if ( lval.getClass() == Float.class )
+        {
+            rhs = Float.valueOf( rval );
         }
-        else if (lval.getClass() == Double.class) {
-            rhs = Double.valueOf(rval);
+        else if ( lval.getClass() == Double.class )
+        {
+            rhs = Double.valueOf( rval );
         }
-        else {
-            try {
-                Constructor<?> stringCtor = lval.getClass().getConstructor(new Class[] { String.class });
-                rhs = stringCtor.newInstance(rval);
+        else
+        {
+            try
+            {
+                Constructor<?> stringCtor = lval.getClass().getConstructor( new Class[]
+                    { String.class } );
+                rhs = stringCtor.newInstance( rval );
             }
-            catch (Exception e) {
+            catch ( Exception e )
+            {
                 // log it
                 e.printStackTrace();
                 return false;
             }
         }
 
-        if (!(lval instanceof Comparable)) {
-            return Ops.EQ == op && lval.equals(rval);
+        if ( !( lval instanceof Comparable ) )
+        {
+            return Ops.EQ == op && lval.equals( rval );
         }
-        else {
+        else
+        {
 
-            Comparable<? super Object> lhs = (Comparable<? super Object>) lval;
+            Comparable<? super Object> lhs = ( Comparable<? super Object> ) lval;
 
-            int compare = lhs.compareTo(rhs);
+            int compare = lhs.compareTo( rhs );
 
-            switch (op) {
-            case EQ:
-                return compare == 0;
-            case APPROX:
-                return compare == 0;
-            case GE:
-                return compare >= 0;
-            case LE:
-                return compare <= 0;
-            case GT:
-                return compare > 0;
-            case LT:
-                return compare < 0;
+            switch ( op )
+            {
+                case EQ:
+                    return compare == 0;
+                case APPROX:
+                    return compare == 0;
+                case GE:
+                    return compare >= 0;
+                case LE:
+                    return compare <= 0;
+                case GT:
+                    return compare > 0;
+                case LT:
+                    return compare < 0;
             }
         }
 
         return false;
     }
 
-    private boolean stringCheck(String lhs) {
+
+    private boolean stringCheck( String lhs )
+    {
 
         String rhs;
-        switch (op) {
-        case EQ:
-        case APPROX:
-            rhs = rval;
-            break;
-        default:
-            return false;
+        switch ( op )
+        {
+            case EQ:
+            case APPROX:
+                rhs = rval;
+                break;
+            default:
+                return false;
         }
 
         int valLength = lhs.length();
         int patLength = rval.length();
 
-        if (valLength == 0 && patLength == 0) {
+        if ( valLength == 0 && patLength == 0 )
+        {
             return true;
         }
 
         boolean wc = false;
         int j = 0;
-        for (int i = 0; i < patLength; i++) {
+        for ( int i = 0; i < patLength; i++ )
+        {
             // trailing wildcards
-            char pc = rhs.charAt(i);
-            if (j == valLength) {
-                if (pc != SimpleTerm.WILDCARD) {
+            char pc = rhs.charAt( i );
+            if ( j == valLength )
+            {
+                if ( pc != SimpleTerm.WILDCARD )
+                {
                     return false;
                 }
                 continue;
             }
-            if (pc == SimpleTerm.WILDCARD) {
+            if ( pc == SimpleTerm.WILDCARD )
+            {
                 wc = true;
                 continue;
             }
-            while (wc && j < valLength - 1 && lhs.charAt(j) != pc) {
+            while ( wc && j < valLength - 1 && lhs.charAt( j ) != pc )
+            {
                 j++;
             }
-            if (lhs.charAt(j) != pc) {
+            if ( lhs.charAt( j ) != pc )
+            {
                 return false;
             }
-            else {
+            else
+            {
                 wc = false;
                 j++;
             }
         }
-        return (wc || j == valLength);
+        return ( wc || j == valLength );
 
     }
 
-    private String collapseWhiteSpace(String in) {
-        StringBuffer out = new StringBuffer(in.trim().length());
+
+    private String collapseWhiteSpace( String in )
+    {
+        StringBuffer out = new StringBuffer( in.trim().length() );
         boolean white = false;
-        for (int i = 0; i < in.length(); i++) {
-            char ch = in.charAt(i);
-            if (Character.isWhitespace(ch)) {
+        for ( int i = 0; i < in.length(); i++ )
+        {
+            char ch = in.charAt( i );
+            if ( Character.isWhitespace( ch ) )
+            {
                 white = true;
             }
-            else {
-                if (white) {
-                    out.append(" ");
+            else
+            {
+                if ( white )
+                {
+                    out.append( " " );
                     white = false;
                 }
-                out.append(ch);
+                out.append( ch );
             }
         }
         return out.toString();
     }
 
-    public void visit(ExprVisitor v) {
-        v.visitSimple(this);
+
+    public void visit( ExprVisitor v )
+    {
+        v.visitSimple( this );
     }
 
-    public LDAPExpr[] getChildren() {
+
+    public LDAPExpr[] getChildren()
+    {
         return CHILDLESS;
     }
 
+
     @Override
-    public boolean equals(Object other) {
-        if (other instanceof SimpleTerm) {
-            SimpleTerm that = (SimpleTerm) other;
-            return name.equals(that.name) && op.equals(that.op) && rval.equals(that.rval);
+    public boolean equals( Object other )
+    {
+        if ( other instanceof SimpleTerm )
+        {
+            SimpleTerm that = ( SimpleTerm ) other;
+            return name.equals( that.name ) && op.equals( that.op ) && rval.equals( that.rval );
         }
         return false;
     }
 
+
     @Override
-    public String toString() {
-        return "(" + name + " " + op.toString() + " " + escape(rval) + ")";
+    public String toString()
+    {
+        return "(" + name + " " + op.toString() + " " + escape( rval ) + ")";
     }
 
-    private String escape(String raw) {
-        StringBuffer buf = new StringBuffer(raw.length() + 10);
-        for (int i = 0; i < raw.length(); i++) {
-            char ch = raw.charAt(i);
-            switch (ch) {
-            case SimpleTerm.WILDCARD:
-                buf.append("*");
-                break;
-            case '(':
-            case ')':
-            case '*':
-                buf.append("\\").append(ch);
-                break;
-            default:
-                buf.append(ch);
+
+    private String escape( String raw )
+    {
+        StringBuffer buf = new StringBuffer( raw.length() + 10 );
+        for ( int i = 0; i < raw.length(); i++ )
+        {
+            char ch = raw.charAt( i );
+            switch ( ch )
+            {
+                case SimpleTerm.WILDCARD:
+                    buf.append( "*" );
+                    break;
+                case '(':
+                case ')':
+                case '*':
+                    buf.append( "\\" ).append( ch );
+                    break;
+                default:
+                    buf.append( ch );
             }
         }
         return buf.toString();
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/Utils.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/Utils.java
index dd308d5..14a4d04 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/Utils.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/Utils.java
@@ -19,52 +19,66 @@
 
 package org.apache.felix.sigil.model.common;
 
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-public class Utils {
-    public static MapBuilder map(String name, Object value) {
-        return new MapBuilder().put(name, value);
+
+public class Utils
+{
+    public static MapBuilder map( String name, Object value )
+    {
+        return new MapBuilder().put( name, value );
     }
 
-    public static String toString(Map<String, Object> attrs) {
-        if (attrs == null) {
+
+    public static String toString( Map<String, Object> attrs )
+    {
+        if ( attrs == null )
+        {
             return "NULL";
         }
 
-        StringBuffer buf = new StringBuffer(128);
-        List<String> keys = new ArrayList<String>(attrs.keySet());
-        Collections.sort(keys);
-        buf.append("{");
+        StringBuffer buf = new StringBuffer( 128 );
+        List<String> keys = new ArrayList<String>( attrs.keySet() );
+        Collections.sort( keys );
+        buf.append( "{" );
 
-        for (int i = 0; i < keys.size(); i++) {
-            Object name = keys.get(i);
-            Object value = attrs.get(name);
-            buf.append(name).append("=").append(value).append(",");
+        for ( int i = 0; i < keys.size(); i++ )
+        {
+            Object name = keys.get( i );
+            Object value = attrs.get( name );
+            buf.append( name ).append( "=" ).append( value ).append( "," );
         }
 
-        if (buf.length() > 1) {
-            buf.delete(buf.length() - 1, buf.length());
+        if ( buf.length() > 1 )
+        {
+            buf.delete( buf.length() - 1, buf.length() );
         }
 
-        buf.append("}");
+        buf.append( "}" );
 
         return buf.toString();
     }
 
-    public static class MapBuilder {
+    public static class MapBuilder
+    {
         private Map<String, Object> map = new HashMap<String, Object>();
 
-        public MapBuilder put(String name, Object value) {
-            map.put(name, value);
+
+        public MapBuilder put( String name, Object value )
+        {
+            map.put( name, value );
 
             return this;
         }
 
-        public Map<String, Object> toMap() {
+
+        public Map<String, Object> toMap()
+        {
             return map;
         }
     }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/VersionRange.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/VersionRange.java
index 3839a88..9448088 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/VersionRange.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/VersionRange.java
@@ -19,25 +19,30 @@
 
 package org.apache.felix.sigil.model.common;
 
+
 import java.io.Serializable;
 
 import org.osgi.framework.Version;
 
-public class VersionRange implements Serializable {
+
+public class VersionRange implements Serializable
+{
 
     /**
      * 
      */
     private static final long serialVersionUID = 1L;
-    public static final Version INFINITE_VERSION = new Version(Integer.MAX_VALUE, Integer.MAX_VALUE,
-            Integer.MAX_VALUE, "");
-    public static final VersionRange ANY_VERSION = new VersionRange(false, Version.emptyVersion, INFINITE_VERSION, true);
+    public static final Version INFINITE_VERSION = new Version( Integer.MAX_VALUE, Integer.MAX_VALUE,
+        Integer.MAX_VALUE, "" );
+    public static final VersionRange ANY_VERSION = new VersionRange( false, Version.emptyVersion, INFINITE_VERSION,
+        true );
 
     private boolean openFloor;
     private Version floor;
     private Version ceiling;
     private boolean openCeiling;
 
+
     /**
      * Interval constructor
      * 
@@ -46,207 +51,253 @@
      * @param ceiling The upper bound version of the range.
      * @param openCeiling Whether the upper bound of the range is inclusive (false) or exclusive (true).
      */
-    public VersionRange(boolean openFloor, Version floor, Version ceiling, boolean openCeiling) {
+    public VersionRange( boolean openFloor, Version floor, Version ceiling, boolean openCeiling )
+    {
         this.openFloor = openFloor;
         this.floor = floor;
         this.ceiling = ceiling;
         this.openCeiling = openCeiling;
     }
 
+
     /**
      * atLeast constructor
      * 
      * @param openFloor
      * @param floor
      */
-    public VersionRange(Version atLeast) {
+    public VersionRange( Version atLeast )
+    {
         this.openFloor = false;
         this.floor = atLeast;
         this.ceiling = INFINITE_VERSION;
         this.openCeiling = true;
     }
-	
-    public static VersionRange parseVersionRange(String val) throws IllegalArgumentException, NumberFormatException {
-    	if ( val == null || val.trim().length() == 0 ) {
-    		return ANY_VERSION;
-    	}
-    	
+
+
+    public static VersionRange parseVersionRange( String val ) throws IllegalArgumentException, NumberFormatException
+    {
+        if ( val == null || val.trim().length() == 0 )
+        {
+            return ANY_VERSION;
+        }
+
         boolean openFloor;
         boolean openCeiling;
-        val = val.replaceAll("\\s", "");
-        val = val.replaceAll("\"", "");
-        int fst = val.charAt(0);
-        if (fst == '[') {
+        val = val.replaceAll( "\\s", "" );
+        val = val.replaceAll( "\"", "" );
+        int fst = val.charAt( 0 );
+        if ( fst == '[' )
+        {
             openFloor = false;
         }
-        else if (fst == '(') {
+        else if ( fst == '(' )
+        {
             openFloor = true;
         }
-        else {
-            Version atLeast = Version.parseVersion(val);
-            return new VersionRange(atLeast);
+        else
+        {
+            Version atLeast = Version.parseVersion( val );
+            return new VersionRange( atLeast );
         }
 
-        int lst = val.charAt(val.length() - 1);
-        if (lst == ']') {
+        int lst = val.charAt( val.length() - 1 );
+        if ( lst == ']' )
+        {
             openCeiling = false;
         }
-        else if (lst == ')') {
+        else if ( lst == ')' )
+        {
             openCeiling = true;
         }
-        else {
-            throw new IllegalArgumentException("illegal version range syntax " + val + ": range must end in ')' or ']'");
+        else
+        {
+            throw new IllegalArgumentException( "illegal version range syntax " + val
+                + ": range must end in ')' or ']'" );
         }
 
-        String inner = val.substring(1, val.length() - 1);
-        String[] floorCeiling = inner.split(",");
-        if (floorCeiling.length != 2) {
-            throw new IllegalArgumentException("illegal version range syntax " + "too many commas");
+        String inner = val.substring( 1, val.length() - 1 );
+        String[] floorCeiling = inner.split( "," );
+        if ( floorCeiling.length != 2 )
+        {
+            throw new IllegalArgumentException( "illegal version range syntax " + "too many commas" );
         }
-        Version floor = Version.parseVersion(floorCeiling[0]);
-        Version ceiling = "*".equals( floorCeiling[1] ) ? INFINITE_VERSION : Version.parseVersion(floorCeiling[1]);
-        return new VersionRange(openFloor, floor, ceiling, openCeiling);
-    }    
-    public Version getCeiling() {
+        Version floor = Version.parseVersion( floorCeiling[0] );
+        Version ceiling = "*".equals( floorCeiling[1] ) ? INFINITE_VERSION : Version.parseVersion( floorCeiling[1] );
+        return new VersionRange( openFloor, floor, ceiling, openCeiling );
+    }
+
+
+    public Version getCeiling()
+    {
         return ceiling;
     }
 
-    public Version getFloor() {
+
+    public Version getFloor()
+    {
         return floor;
     }
 
-    public boolean isOpenCeiling() {
+
+    public boolean isOpenCeiling()
+    {
         return openCeiling;
     }
 
-    public boolean isOpenFloor() {
+
+    public boolean isOpenFloor()
+    {
         return openFloor;
     }
 
-    public boolean isPointVersion() {
-        return !openFloor && !openCeiling && floor.equals(ceiling);
+
+    public boolean isPointVersion()
+    {
+        return !openFloor && !openCeiling && floor.equals( ceiling );
     }
 
+
     /**
      * test a version to see if it falls in the range
      * 
      * @param version
      * @return
      */
-    public boolean contains(Version version) {
-        if (version.equals(INFINITE_VERSION)) {
-            return ceiling.equals(INFINITE_VERSION);
+    public boolean contains( Version version )
+    {
+        if ( version.equals( INFINITE_VERSION ) )
+        {
+            return ceiling.equals( INFINITE_VERSION );
         }
-        else {
-            return (version.compareTo(floor) > 0 && version.compareTo(ceiling) < 0)
-                    || (!openFloor && version.equals(floor)) || (!openCeiling && version.equals(ceiling));
+        else
+        {
+            return ( version.compareTo( floor ) > 0 && version.compareTo( ceiling ) < 0 )
+                || ( !openFloor && version.equals( floor ) ) || ( !openCeiling && version.equals( ceiling ) );
         }
     }
 
+
     @Override
-    public int hashCode() {
+    public int hashCode()
+    {
         final int prime = 31;
         int result = 1;
-        result = prime * result + ((ceiling == null) ? 0 : ceiling.hashCode());
-        result = prime * result + ((floor == null) ? 0 : floor.hashCode());
-        result = prime * result + (openCeiling ? 1231 : 1237);
-        result = prime * result + (openFloor ? 1231 : 1237);
+        result = prime * result + ( ( ceiling == null ) ? 0 : ceiling.hashCode() );
+        result = prime * result + ( ( floor == null ) ? 0 : floor.hashCode() );
+        result = prime * result + ( openCeiling ? 1231 : 1237 );
+        result = prime * result + ( openFloor ? 1231 : 1237 );
         return result;
     }
 
+
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
             return true;
-        if (obj == null)
+        if ( obj == null )
             return false;
-        if (getClass() != obj.getClass())
+        if ( getClass() != obj.getClass() )
             return false;
-        final VersionRange other = (VersionRange) obj;
-        if (ceiling == null) {
-            if (other.ceiling != null)
+        final VersionRange other = ( VersionRange ) obj;
+        if ( ceiling == null )
+        {
+            if ( other.ceiling != null )
                 return false;
         }
-        else if (!ceiling.equals(other.ceiling))
+        else if ( !ceiling.equals( other.ceiling ) )
             return false;
-        if (floor == null) {
-            if (other.floor != null)
+        if ( floor == null )
+        {
+            if ( other.floor != null )
                 return false;
         }
-        else if (!floor.equals(other.floor))
+        else if ( !floor.equals( other.floor ) )
             return false;
-        if (openCeiling != other.openCeiling)
+        if ( openCeiling != other.openCeiling )
             return false;
-        if (openFloor != other.openFloor)
+        if ( openFloor != other.openFloor )
             return false;
         return true;
     }
 
+
     @Override
-    public String toString() {
-        if (ANY_VERSION.equals(this)) {
-            return makeString(openFloor, Version.emptyVersion, INFINITE_VERSION, openCeiling);
+    public String toString()
+    {
+        if ( ANY_VERSION.equals( this ) )
+        {
+            return makeString( openFloor, Version.emptyVersion, INFINITE_VERSION, openCeiling );
         }
-        return makeString(openFloor, floor, ceiling, openCeiling);
+        return makeString( openFloor, floor, ceiling, openCeiling );
     }
 
-    private String makeString(boolean openFloor, Version floor, Version ceiling, boolean openCeiling) {
-        StringBuffer vr = new StringBuffer(32);
-        if ( INFINITE_VERSION.equals(ceiling) ) {
-        	vr.append( Version.emptyVersion.equals(floor) ? "0" : floor.toString() );
+
+    private String makeString( boolean openFloor, Version floor, Version ceiling, boolean openCeiling )
+    {
+        StringBuffer vr = new StringBuffer( 32 );
+        if ( INFINITE_VERSION.equals( ceiling ) )
+        {
+            vr.append( Version.emptyVersion.equals( floor ) ? "0" : floor.toString() );
         }
-        else {
-            vr.append(openFloor ? "(" : "[");
-            String floorStr = Version.emptyVersion.equals(floor) ? "0" : floor.toString();
+        else
+        {
+            vr.append( openFloor ? "(" : "[" );
+            String floorStr = Version.emptyVersion.equals( floor ) ? "0" : floor.toString();
             String ceilingStr = ceiling.toString();
-            vr.append(floorStr).append(",").append(ceilingStr);
-            vr.append(openCeiling ? ")" : "]");
+            vr.append( floorStr ).append( "," ).append( ceilingStr );
+            vr.append( openCeiling ? ")" : "]" );
         }
         return vr.toString();
     }
 
-    
-    public static VersionRange newInstance(Version pointVersion, VersionRangeBoundingRule lowerBoundRule, VersionRangeBoundingRule upperBoundRule) {
-    	Version floor = null;
-    	switch (lowerBoundRule) {
-		case Any:
-			floor = new Version(0, 0, 0);
-			break;
-		case Major:
-			floor = new Version(pointVersion.getMajor(), 0, 0);
-			break;
-		case Minor:
-			floor = new Version(pointVersion.getMajor(), pointVersion.getMinor(), 0);
-			break;
-		case Micro:
-			floor = new Version(pointVersion.getMajor(), pointVersion.getMinor(), pointVersion.getMicro());
-			break;
-		case Exact:
-			floor = pointVersion;
-			break;
-		}
-    	
-    	Version ceiling = null;
-    	boolean openCeiling = true;
-    	switch (upperBoundRule) {
-		case Any:
-			ceiling = INFINITE_VERSION;
-			break;
-		case Major:
-			ceiling = new Version(pointVersion.getMajor() + 1, 0, 0);
-			break;
-		case Minor:
-			ceiling = new Version(pointVersion.getMajor(), pointVersion.getMinor() + 1, 0);
-			break;
-		case Micro:
-			ceiling = new Version(pointVersion.getMajor(), pointVersion.getMinor(), pointVersion.getMicro() + 1);
-			break;
-		case Exact:
-			ceiling = pointVersion;
-			openCeiling = false;
-			break;
-		}
-    	
-    	return new VersionRange(false, floor, ceiling, openCeiling);
+
+    public static VersionRange newInstance( Version pointVersion, VersionRangeBoundingRule lowerBoundRule,
+        VersionRangeBoundingRule upperBoundRule )
+    {
+        Version floor = null;
+        switch ( lowerBoundRule )
+        {
+            case Any:
+                floor = new Version( 0, 0, 0 );
+                break;
+            case Major:
+                floor = new Version( pointVersion.getMajor(), 0, 0 );
+                break;
+            case Minor:
+                floor = new Version( pointVersion.getMajor(), pointVersion.getMinor(), 0 );
+                break;
+            case Micro:
+                floor = new Version( pointVersion.getMajor(), pointVersion.getMinor(), pointVersion.getMicro() );
+                break;
+            case Exact:
+                floor = pointVersion;
+                break;
+        }
+
+        Version ceiling = null;
+        boolean openCeiling = true;
+        switch ( upperBoundRule )
+        {
+            case Any:
+                ceiling = INFINITE_VERSION;
+                break;
+            case Major:
+                ceiling = new Version( pointVersion.getMajor() + 1, 0, 0 );
+                break;
+            case Minor:
+                ceiling = new Version( pointVersion.getMajor(), pointVersion.getMinor() + 1, 0 );
+                break;
+            case Micro:
+                ceiling = new Version( pointVersion.getMajor(), pointVersion.getMinor(), pointVersion.getMicro() + 1 );
+                break;
+            case Exact:
+                ceiling = pointVersion;
+                openCeiling = false;
+                break;
+        }
+
+        return new VersionRange( false, floor, ceiling, openCeiling );
     }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/common/VersionRangeBoundingRule.java b/sigil/common/core/src/org/apache/felix/sigil/model/common/VersionRangeBoundingRule.java
index 145e791..c1f6f14 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/common/VersionRangeBoundingRule.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/common/VersionRangeBoundingRule.java
@@ -19,6 +19,8 @@
 
 package org.apache.felix.sigil.model.common;
 
-public enum VersionRangeBoundingRule {
-	Exact, Micro, Minor, Major, Any
+
+public enum VersionRangeBoundingRule
+{
+    Exact, Micro, Minor, Major, Any
 }
\ No newline at end of file
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/IDownloadJar.java b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/IDownloadJar.java
index b4565b8..a500c34 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/IDownloadJar.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/IDownloadJar.java
@@ -19,17 +19,25 @@
 
 package org.apache.felix.sigil.model.eclipse;
 
+
 import java.util.Set;
 
 import org.apache.felix.sigil.model.IModelElement;
 import org.eclipse.core.runtime.IPath;
 
-public interface IDownloadJar extends IModelElement {
-	void addEntry(IPath entry);
-	void removeEntry(IPath entry);
-	// XXX bad spelling on purpose so that ModelElementSupport picks up method
-	// TODO fix in ModelElementSupport
-	Set<IPath> getEntrys();
-	
-	void clearEntries();
+
+public interface IDownloadJar extends IModelElement
+{
+    void addEntry( IPath entry );
+
+
+    void removeEntry( IPath entry );
+
+
+    // XXX bad spelling on purpose so that ModelElementSupport picks up method
+    // TODO fix in ModelElementSupport
+    Set<IPath> getEntrys();
+
+
+    void clearEntries();
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ILibrary.java b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ILibrary.java
index e98a4a7..c0b5f7d 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ILibrary.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ILibrary.java
@@ -19,18 +19,33 @@
 
 package org.apache.felix.sigil.model.eclipse;
 
+
 import java.util.Collection;
 
 import org.apache.felix.sigil.model.IModelElement;
 import org.apache.felix.sigil.model.osgi.IPackageImport;
 import org.osgi.framework.Version;
 
-public interface ILibrary extends IModelElement {
-	String getName();
-	void setName(String name);
-	Version getVersion();
-	void setVersion(Version version);
-	void addImport(IPackageImport pi);
-	void removeImport(IPackageImport pi);
-	Collection<IPackageImport> getImports();
+
+public interface ILibrary extends IModelElement
+{
+    String getName();
+
+
+    void setName( String name );
+
+
+    Version getVersion();
+
+
+    void setVersion( Version version );
+
+
+    void addImport( IPackageImport pi );
+
+
+    void removeImport( IPackageImport pi );
+
+
+    Collection<IPackageImport> getImports();
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ILibraryImport.java b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ILibraryImport.java
index 9ebc7f6..664e32f 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ILibraryImport.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ILibraryImport.java
@@ -19,12 +19,21 @@
 
 package org.apache.felix.sigil.model.eclipse;
 
+
 import org.apache.felix.sigil.model.IModelElement;
 import org.apache.felix.sigil.model.common.VersionRange;
 
-public interface ILibraryImport extends IModelElement {
-	String getLibraryName();
-	void setLibraryName(String name);
-	VersionRange getVersions();
-	void setVersions(VersionRange range);
+
+public interface ILibraryImport extends IModelElement
+{
+    String getLibraryName();
+
+
+    void setLibraryName( String name );
+
+
+    VersionRange getVersions();
+
+
+    void setVersions( VersionRange range );
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/INewtonSystem.java b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/INewtonSystem.java
index 61eed82..d19966b 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/INewtonSystem.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/INewtonSystem.java
@@ -19,15 +19,19 @@
 
 package org.apache.felix.sigil.model.eclipse;
 
+
 import org.apache.felix.sigil.model.IModelElement;
 import org.eclipse.core.runtime.IPath;
 
+
 /**
  * @author dave
  *
  */
-public interface INewtonSystem extends IModelElement {
+public interface INewtonSystem extends IModelElement
+{
     IPath getLocation();
-    
-    void setLocation(IPath location);
+
+
+    void setLocation( IPath location );
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISCAComposite.java b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISCAComposite.java
index d9cc88d..cf0c603 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISCAComposite.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISCAComposite.java
@@ -19,15 +19,19 @@
 
 package org.apache.felix.sigil.model.eclipse;
 
+
 import org.apache.felix.sigil.model.IModelElement;
 import org.eclipse.core.runtime.IPath;
 
+
 /**
  * @author dave
  *
  */
-public interface ISCAComposite extends IModelElement {
+public interface ISCAComposite extends IModelElement
+{
     IPath getLocation();
-    
-    void setLocation(IPath location);
+
+
+    void setLocation( IPath location );
 }
\ No newline at end of file
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISigilBundle.java b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISigilBundle.java
index 5419cbb..d75c162 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISigilBundle.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/eclipse/ISigilBundle.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.model.eclipse;
 
+
 import java.io.IOException;
 import java.util.Set;
 
@@ -30,112 +31,148 @@
 import org.apache.felix.sigil.model.osgi.IPackageImport;
 import org.apache.felix.sigil.model.osgi.IVersionedModelElement;
 
+
 /**
  * @author dave
  *
  */
-public interface ISigilBundle extends ICompoundModelElement, IVersionedModelElement {
-	void synchronize(IProgressMonitor monitor) throws IOException;
-	
-	boolean isSynchronized();	
-	
+public interface ISigilBundle extends ICompoundModelElement, IVersionedModelElement
+{
+    void synchronize( IProgressMonitor monitor ) throws IOException;
+
+
+    boolean isSynchronized();
+
+
     IBundleModelElement getBundleInfo();
-    
-	String getSymbolicName();
-    
-    void setBundleInfo(IBundleModelElement bundle);
-    
+
+
+    String getSymbolicName();
+
+
+    void setBundleInfo( IBundleModelElement bundle );
+
+
     IDownloadJar getDownloadJar();
-    
-    void setDownloadJar(IDownloadJar download);
-    
-    void addComposite(ISCAComposite composite);
-    
-    void removeComposite(ISCAComposite composite);
-    
+
+
+    void setDownloadJar( IDownloadJar download );
+
+
+    void addComposite( ISCAComposite composite );
+
+
+    void removeComposite( ISCAComposite composite );
+
+
     Set<ISCAComposite> getComposites();
 
-    void addLibraryPath(IPath path);
 
-    void removeLibraryPath(IPath path);
+    void addLibraryPath( IPath path );
+
+
+    void removeLibraryPath( IPath path );
+
 
     Set<IPath> getLibraryPaths();
 
-    void addSourcePath(IPath path);
 
-    void removeSourcePath(IPath path);
+    void addSourcePath( IPath path );
+
+
+    void removeSourcePath( IPath path );
+
 
     Set<IPath> getSourcePaths();
 
-	void clearSourcePaths();
 
-	Set<String> getClasspathEntrys();
-	
-	void addClasspathEntry(String encodedClasspath);
-	
-	void removeClasspathEntry(String encodedClasspath);
+    void clearSourcePaths();
 
-	IPath getLocation();
-	
-	void setLocation(IPath location);
 
-	IPath getSourcePathLocation();
-	
-	void setSourcePathLocation( IPath location );
+    Set<String> getClasspathEntrys();
 
-	IPath getSourceRootPath();
-	
-	void setSourceRootPath( IPath location );
 
-	void setLicencePathLocation(IPath cacheSourceLocation);
-	
-	IPath getLicencePathLocation();
-	
-	/**
-	 * get package names included in bundle.
-	 * Can contain wildcards e.g. org.foo.*
-	 */
-	Set<String> getPackages();
-	
-	/**
-	 * remove package name from those included in bundle.
-	 */
-	boolean removePackage(String pkg);
-	
-	/**
-	 * add package name to be included in bundle.
-	 */
-	void addPackage(String pkg);
-	
-	
-	/**
-	 * get package names included in download jar.
-	 * Can contain wildcards e.g. org.foo.*
-	 */
-	Set<String> getDownloadPackages();
-	
-	/**
-	 * remove package name from those included in download jar.
-	 */
-	boolean removeDownloadPackage(String pkg);
-	
-	/**
-	 * add package name to be included in download jar.
-	 */
-	void addDownloadPackage(String pkg);
+    void addClasspathEntry( String encodedClasspath );
 
-	/**
-	 * Attempt to find a package export that matches the given name or return null if none specified
-	 * 
-	 * @param elementName
-	 * @return
-	 */
-	IPackageExport findExport(String elementName);
 
-	/**
-	 * Attempt to find a package import that matches the given name or return null if none specified
-	 * @param packageName
-	 * @return
-	 */
-	IPackageImport findImport(String packageName);
+    void removeClasspathEntry( String encodedClasspath );
+
+
+    IPath getLocation();
+
+
+    void setLocation( IPath location );
+
+
+    IPath getSourcePathLocation();
+
+
+    void setSourcePathLocation( IPath location );
+
+
+    IPath getSourceRootPath();
+
+
+    void setSourceRootPath( IPath location );
+
+
+    void setLicencePathLocation( IPath cacheSourceLocation );
+
+
+    IPath getLicencePathLocation();
+
+
+    /**
+     * get package names included in bundle.
+     * Can contain wildcards e.g. org.foo.*
+     */
+    Set<String> getPackages();
+
+
+    /**
+     * remove package name from those included in bundle.
+     */
+    boolean removePackage( String pkg );
+
+
+    /**
+     * add package name to be included in bundle.
+     */
+    void addPackage( String pkg );
+
+
+    /**
+     * get package names included in download jar.
+     * Can contain wildcards e.g. org.foo.*
+     */
+    Set<String> getDownloadPackages();
+
+
+    /**
+     * remove package name from those included in download jar.
+     */
+    boolean removeDownloadPackage( String pkg );
+
+
+    /**
+     * add package name to be included in download jar.
+     */
+    void addDownloadPackage( String pkg );
+
+
+    /**
+     * Attempt to find a package export that matches the given name or return null if none specified
+     * 
+     * @param elementName
+     * @return
+     */
+    IPackageExport findExport( String elementName );
+
+
+    /**
+     * Attempt to find a package import that matches the given name or return null if none specified
+     * @param packageName
+     * @return
+     */
+    IPackageImport findImport( String packageName );
 }
\ No newline at end of file
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IBundleModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IBundleModelElement.java
index 7edb8c3..1ebf287 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IBundleModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IBundleModelElement.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.model.osgi;
 
+
 import java.net.URI;
 import java.util.Collection;
 import java.util.Set;
@@ -28,87 +29,129 @@
 import org.apache.felix.sigil.model.eclipse.ILibraryImport;
 import org.osgi.framework.Version;
 
-public interface IBundleModelElement extends INamedModelElement, ICompoundModelElement, IVersionedModelElement {
 
-	 String getActivator();
-	 
-	 void setActivator(String activator);
-	 
-	 String getCategory();
+public interface IBundleModelElement extends INamedModelElement, ICompoundModelElement, IVersionedModelElement
+{
 
-	 void setCategory(String category);
+    String getActivator();
 
-	 String getContactAddress();
 
-	 void setContactAddress(String contactAddress);
+    void setActivator( String activator );
 
-	 String getCopyright();
 
-	 void setCopyright(String copyright);
+    String getCategory();
 
-	 URI getDocURI();
 
-	 void setDocURI(URI docURI);
+    void setCategory( String category );
 
-	 Set<IPackageExport> getExports();
 
-	 void addExport(IPackageExport packageExport);
+    String getContactAddress();
 
-	 void removeExport(IPackageExport packageExport);
 
-	 Set<IPackageImport> getImports();
+    void setContactAddress( String contactAddress );
 
-	 void addImport(IPackageImport packageImport);
 
-	 void removeImport(IPackageImport packageImport);
+    String getCopyright();
 
-	 Set<IRequiredBundle> getRequiredBundles();
 
-	 void addRequiredBundle(IRequiredBundle bundle);
+    void setCopyright( String copyright );
 
-	 void removeRequiredBundle(IRequiredBundle bundle);
-	 
-	 void addLibraryImport(ILibraryImport library);
-	 
-	 void removeLibraryImport(ILibraryImport library);
-	 
-	 Set<ILibraryImport> getLibraryImports();
 
-	 URI getLicenseURI();
+    URI getDocURI();
 
-	 void setLicenseURI(URI licenseURI);
 
-	 URI getSourceLocation();
+    void setDocURI( URI docURI );
 
-	 void setSourceLocation(URI sourceLocation);
 
-	 String getSymbolicName();
+    Set<IPackageExport> getExports();
 
-	 void setSymbolicName(String symbolicName);
 
-	 URI getUpdateLocation();
+    void addExport( IPackageExport packageExport );
 
-	 void setUpdateLocation(URI updateLocation);
 
-	 String getVendor();
+    void removeExport( IPackageExport packageExport );
 
-	 void setVendor(String vendor);
 
-	 Version getVersion();
+    Set<IPackageImport> getImports();
 
-	 void setVersion(Version version);
 
-	 void setDescription(String elementText);
-	 
-	 String getDescription();
+    void addImport( IPackageImport packageImport );
 
-	Collection<String> getClasspaths();
-	
-	void addClasspath(String path);
-	
-	void removeClasspath(String path);
 
-	void setFragmentHost(IRequiredBundle fragmentHost);
-	
-	IRequiredBundle getFragmentHost();
+    void removeImport( IPackageImport packageImport );
+
+
+    Set<IRequiredBundle> getRequiredBundles();
+
+
+    void addRequiredBundle( IRequiredBundle bundle );
+
+
+    void removeRequiredBundle( IRequiredBundle bundle );
+
+
+    void addLibraryImport( ILibraryImport library );
+
+
+    void removeLibraryImport( ILibraryImport library );
+
+
+    Set<ILibraryImport> getLibraryImports();
+
+
+    URI getLicenseURI();
+
+
+    void setLicenseURI( URI licenseURI );
+
+
+    URI getSourceLocation();
+
+
+    void setSourceLocation( URI sourceLocation );
+
+
+    String getSymbolicName();
+
+
+    void setSymbolicName( String symbolicName );
+
+
+    URI getUpdateLocation();
+
+
+    void setUpdateLocation( URI updateLocation );
+
+
+    String getVendor();
+
+
+    void setVendor( String vendor );
+
+
+    Version getVersion();
+
+
+    void setVersion( Version version );
+
+
+    void setDescription( String elementText );
+
+
+    String getDescription();
+
+
+    Collection<String> getClasspaths();
+
+
+    void addClasspath( String path );
+
+
+    void removeClasspath( String path );
+
+
+    void setFragmentHost( IRequiredBundle fragmentHost );
+
+
+    IRequiredBundle getFragmentHost();
 }
\ No newline at end of file
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageExport.java b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageExport.java
index 463201f..271774c 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageExport.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageExport.java
@@ -19,18 +19,25 @@
 
 package org.apache.felix.sigil.model.osgi;
 
+
 import java.util.Collection;
 
 import org.osgi.framework.Version;
 
-public interface IPackageExport extends IPackageModelElement, IVersionedModelElement, Comparable<IPackageExport> {
-	void addUse(String uses);
-	
-	void removeUse(String uses);
-	
-	Collection<String> getUses();
 
-	void setUses(Collection<String> asList);
-	
-	Version getRawVersion();
+public interface IPackageExport extends IPackageModelElement, IVersionedModelElement, Comparable<IPackageExport>
+{
+    void addUse( String uses );
+
+
+    void removeUse( String uses );
+
+
+    Collection<String> getUses();
+
+
+    void setUses( Collection<String> asList );
+
+
+    Version getRawVersion();
 }
\ No newline at end of file
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageImport.java b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageImport.java
index 2355b08..1cec175 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageImport.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageImport.java
@@ -19,47 +19,57 @@
 
 package org.apache.felix.sigil.model.osgi;
 
+
 import org.apache.felix.sigil.model.IRequirementModelElement;
 
-public interface IPackageImport extends IPackageModelElement, IVersionRangeModelElement, IRequirementModelElement, Comparable<IPackageImport> {
-	/**
-	 * indicates whether the OSGi attribute "resolution=optional" is specified.
-	 */
-	boolean isOptional();
-	
-	void setOptional(boolean optional);
 
-	/**
-	 * indicates whether import is needed at compile-time.
-	 * Default true. Used in conjunction with OSGiHeader.ALWAYS,
-	 * to add an OSGI import, without creating a dependency.
-	 */
-	boolean isDependency();
-	
-	void setDependency(boolean dependency);
-	
-	/**
-	 * indicates whether import should be added to OSGi Package-Import header.
-	 * Default: AUTO.
-	 */
-	OSGiImport getOSGiImport();
-	
-	void setOSGiImport(OSGiImport osgiImport);
-	
-	enum OSGiImport {
-		/**
-		 * only add to OSGi header, if it appears to be needed.
-		 */
-		AUTO,
-		
-		/**
-		 * always add to OSGi header, even if it appears unnecessary.
-		 */
-		ALWAYS,
-		
-		/**
-		 * never add to OSGi header.
-		 */
-		NEVER
-	}
+public interface IPackageImport extends IPackageModelElement, IVersionRangeModelElement, IRequirementModelElement,
+    Comparable<IPackageImport>
+{
+    /**
+     * indicates whether the OSGi attribute "resolution=optional" is specified.
+     */
+    boolean isOptional();
+
+
+    void setOptional( boolean optional );
+
+
+    /**
+     * indicates whether import is needed at compile-time.
+     * Default true. Used in conjunction with OSGiHeader.ALWAYS,
+     * to add an OSGI import, without creating a dependency.
+     */
+    boolean isDependency();
+
+
+    void setDependency( boolean dependency );
+
+
+    /**
+     * indicates whether import should be added to OSGi Package-Import header.
+     * Default: AUTO.
+     */
+    OSGiImport getOSGiImport();
+
+
+    void setOSGiImport( OSGiImport osgiImport );
+
+    enum OSGiImport
+    {
+        /**
+         * only add to OSGi header, if it appears to be needed.
+         */
+        AUTO,
+
+        /**
+         * always add to OSGi header, even if it appears unnecessary.
+         */
+        ALWAYS,
+
+        /**
+         * never add to OSGi header.
+         */
+        NEVER
+    }
 }
\ No newline at end of file
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageModelElement.java
index aab0b14..79d618b 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IPackageModelElement.java
@@ -19,12 +19,16 @@
 
 package org.apache.felix.sigil.model.osgi;
 
+
 import org.apache.felix.sigil.model.IModelElement;
 
-public interface IPackageModelElement extends IModelElement {
 
-	String getPackageName();
+public interface IPackageModelElement extends IModelElement
+{
 
-	void setPackageName(String packageName);
+    String getPackageName();
+
+
+    void setPackageName( String packageName );
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IRequiredBundle.java b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IRequiredBundle.java
index 226abee..d039c84 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IRequiredBundle.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IRequiredBundle.java
@@ -19,20 +19,28 @@
 
 package org.apache.felix.sigil.model.osgi;
 
+
 import org.apache.felix.sigil.model.IModelElement;
 import org.apache.felix.sigil.model.IRequirementModelElement;
 import org.apache.felix.sigil.model.common.VersionRange;
 
-public interface IRequiredBundle extends IModelElement, IRequirementModelElement, Comparable<IRequiredBundle> {
-	String getSymbolicName();
 
-	void setSymbolicName(String symbolicName);
+public interface IRequiredBundle extends IModelElement, IRequirementModelElement, Comparable<IRequiredBundle>
+{
+    String getSymbolicName();
 
-	VersionRange getVersions();
 
-	void setVersions(VersionRange versions);
+    void setSymbolicName( String symbolicName );
 
-	boolean isOptional();
-	
-	void setOptional(boolean optional);
+
+    VersionRange getVersions();
+
+
+    void setVersions( VersionRange versions );
+
+
+    boolean isOptional();
+
+
+    void setOptional( boolean optional );
 }
\ No newline at end of file
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IVersionRangeModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IVersionRangeModelElement.java
index d65e451..83d8bf4 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IVersionRangeModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IVersionRangeModelElement.java
@@ -19,12 +19,16 @@
 
 package org.apache.felix.sigil.model.osgi;
 
+
 import org.apache.felix.sigil.model.common.VersionRange;
 
-public interface IVersionRangeModelElement {
 
-	VersionRange getVersions();
+public interface IVersionRangeModelElement
+{
 
-	void setVersions(VersionRange version);
+    VersionRange getVersions();
+
+
+    void setVersions( VersionRange version );
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IVersionedModelElement.java b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IVersionedModelElement.java
index 6d8421b..8f03acd 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IVersionedModelElement.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/model/osgi/IVersionedModelElement.java
@@ -19,12 +19,16 @@
 
 package org.apache.felix.sigil.model.osgi;
 
+
 import org.osgi.framework.Version;
 
-public interface IVersionedModelElement {
 
-	Version getVersion();
+public interface IVersionedModelElement
+{
 
-	void setVersion(Version version);
+    Version getVersion();
+
+
+    void setVersion( Version version );
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/AbstractBundleRepository.java b/sigil/common/core/src/org/apache/felix/sigil/repository/AbstractBundleRepository.java
index f34a4ec..2d459a7 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/AbstractBundleRepository.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/AbstractBundleRepository.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.repository;
 
+
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
@@ -44,361 +45,474 @@
 import org.apache.felix.sigil.model.osgi.IRequiredBundle;
 import org.osgi.framework.Version;
 
-public abstract class AbstractBundleRepository implements IBundleRepository {
-	
-	private final String id;
-	private final HashSet<IBundleRepositoryListener> listeners = new HashSet<IBundleRepositoryListener>();
 
-	public AbstractBundleRepository(String id) {
-		this.id = id;
-	}
-	
-	public abstract void accept(IRepositoryVisitor visitor, int options);
-	
-	public void addBundleRepositoryListener(IBundleRepositoryListener listener) {
-		synchronized(listeners) {
-			listeners.add(listener);
-		}
-	}
+public abstract class AbstractBundleRepository implements IBundleRepository
+{
 
-	public void removeBundleRepositoryListener(IBundleRepositoryListener listener) {
-		synchronized(listeners) {
-			listeners.remove(listener);
-		}
-	}
-	
-	protected void notifyChange() {
-		for ( IBundleRepositoryListener l : listeners ) {
-			l.notifyChange(this);
-		}
-	}
-	
-	public String getId() {
-		return id;
-	}
-		
-	public void accept(IRepositoryVisitor visitor) {
-		accept( visitor, 0 );
-	}
-	
-	public void writeOBR(OutputStream out) throws IOException {
-		throw new UnsupportedOperationException();
-	}
+    private final String id;
+    private final HashSet<IBundleRepositoryListener> listeners = new HashSet<IBundleRepositoryListener>();
 
-	public Collection<ISigilBundle> findProviders(final ILibrary library, int options) {
-		final ArrayList<ISigilBundle> found = new ArrayList<ISigilBundle>();
-		
-		final ILicensePolicy policy = findPolicy(library);
-		
-		IRepositoryVisitor visitor = new IRepositoryVisitor() {
-			public boolean visit(ISigilBundle bundle) {
-				if (policy.accept(bundle)) {
-					IBundleModelElement info = bundle.getBundleInfo();
-					for ( IPackageImport pi : library.getImports() ) {
-						for ( IPackageExport e : info.getExports() ) {
-							if ( pi.getPackageName().equals( e.getPackageName() ) && pi.getVersions().contains( e.getVersion() ) ) {
-								found.add(bundle);
-								break;
-							}
-						}
-					}					
-				}
-				return true;
-			}
-		};
-		
-		accept( visitor, options );
-		
-		return found;
-	}
 
-	public Collection<ISigilBundle> findAllProviders(final IRequiredBundle req, int options) {
-		final ArrayList<ISigilBundle> found = new ArrayList<ISigilBundle>();
-		
-		final ILicensePolicy policy = findPolicy(req);
-		
-		IRepositoryVisitor visitor = new IRepositoryVisitor() {
-			public boolean visit(ISigilBundle bundle) {
-				if (policy.accept(bundle)) {
-					IBundleModelElement info = bundle.getBundleInfo();
-					if ( req.getSymbolicName().equals( info.getSymbolicName() ) && req.getVersions().contains( info.getVersion() ) ) {
-						found.add(bundle);
-					}
-				}
-				return true;
-			}
-		};
-		
-		accept( visitor, options );
-		
-		return found;
-	}
+    public AbstractBundleRepository( String id )
+    {
+        this.id = id;
+    }
 
-	public Collection<ISigilBundle> findAllProviders(final IPackageImport pi, int options) {
-		final ArrayList<ISigilBundle> found = new ArrayList<ISigilBundle>();
-		
-		final ILicensePolicy policy = findPolicy(pi);
-		
-		IRepositoryVisitor visitor = new IRepositoryVisitor() {
 
-			public boolean visit(ISigilBundle bundle) {
-				if (policy.accept(bundle)) {
-					IBundleModelElement info = bundle.getBundleInfo();
-					if ( info != null ) {
-						for ( IPackageExport e : info.getExports() ) {
-							if ( pi.getPackageName().equals( e.getPackageName() ) ) {
-								if ( pi.getVersions().contains( e.getVersion() ) ) {
-									found.add(bundle);
-									break;
-								}
-							}
-						}
-					}
-				}
-				return true;
-			}
-			
-		};
-		
-		accept( visitor, options );
-		
-		return found;
-	}
+    public abstract void accept( IRepositoryVisitor visitor, int options );
 
-	public ISigilBundle findProvider(final IPackageImport pi, int options) {
-		final ArrayList<ISigilBundle> found = new ArrayList<ISigilBundle>();
-		
-		final ILicensePolicy policy = findPolicy(pi);
-		
-		IRepositoryVisitor visitor = new IRepositoryVisitor() {
-			public boolean visit(ISigilBundle bundle) {
-				if (policy.accept(bundle)) {
-					IBundleModelElement info = bundle.getBundleInfo();
-					for ( IPackageExport e : info.getExports() ) {
-						if ( pi.getPackageName().equals( e.getPackageName() ) && pi.getVersions().contains( e.getVersion() ) ) {
-							found.add( bundle );
-							return false;
-						}
-					}
-				}
-				return true;
-			}
-			
-		};
-		
-		accept( visitor, options );
-		
-		return found.isEmpty() ? null : found.iterator().next();
-	}
 
-	public ISigilBundle findProvider(final IRequiredBundle req, int options) {
-		final ArrayList<ISigilBundle> found = new ArrayList<ISigilBundle>();
-		
-		final ILicensePolicy policy = findPolicy(req);
-		
-		IRepositoryVisitor visitor = new IRepositoryVisitor() {
+    public void addBundleRepositoryListener( IBundleRepositoryListener listener )
+    {
+        synchronized ( listeners )
+        {
+            listeners.add( listener );
+        }
+    }
 
-			public boolean visit(ISigilBundle bundle) {
-				if (policy.accept(bundle)) {
-					IBundleModelElement info = bundle.getBundleInfo();
-					if ( req.getSymbolicName().equals( info.getSymbolicName() ) && req.getVersions().contains( info.getVersion() ) ) {
-						found.add( bundle );
-						return false;
-					}
-				}
-				return true;
-			}
-			
-		};
-		
-		accept( visitor, options );
-		
-		return found.isEmpty() ? null : found.iterator().next();
-	}
-	
-	public IBundleModelElement buildBundleModelElement(Manifest mf) {
-		IBundleModelElement info = null;
-		
-		if ( mf != null ) {
-			Attributes attrs = mf.getMainAttributes();
-			String name = attrs.getValue("Bundle-SymbolicName");
-			if (name == null) {
-    			// framework.jar doesn't have Bundle-SymbolicName!
-    			name = attrs.getValue("Bundle-Name");
-			}
-			
-			if (name != null) {
-				try {
-					info = ModelElementFactory.getInstance().newModelElement( IBundleModelElement.class );
-					info.setSymbolicName( name.split(";")[0] );
-					info.setVersion( Version.parseVersion( attrs.getValue( "Bundle-Version" ) ) );
-					info.setName( attrs.getValue( "Bundle-Name" ) );
-					info.setDescription( attrs.getValue( "Bundle-Description" ) );
-					info.setVendor( attrs.getValue( "Bundle-Vendor" ) );
 
-					String str = attrs.getValue( "Import-Package" );
-					if ( str != null ) {
-						addImports( info, str );
-					}
-					
-					str = attrs.getValue( "Export-Package" );
-					if ( str != null ) {
-						addExports( info, str );
-					}
+    public void removeBundleRepositoryListener( IBundleRepositoryListener listener )
+    {
+        synchronized ( listeners )
+        {
+            listeners.remove( listener );
+        }
+    }
 
-					str = attrs.getValue( "Require-Bundle" );
-					if ( str != null ) {
-						addRequires( info, str );
-					}
 
-					str = attrs.getValue( "Bundle-Classpath" );
+    protected void notifyChange()
+    {
+        for ( IBundleRepositoryListener l : listeners )
+        {
+            l.notifyChange( this );
+        }
+    }
 
-					if ( str != null ) {
-						addClasspath( info, str );
-					}
-					
-					str = attrs.getValue( "Fragment-Host" );
-					if ( str != null ) {
-						addHost(info, str);
-					}
-				}
-				catch (RuntimeException e) {
-					BldCore.error( "Failed to read info from bundle " + name, e );
-					// clear elements as clearly got garbage
-					info = null;
-				}
-			}
-		}
-		
-		return info;
-	}
 
-	protected ILicensePolicy findPolicy(IModelElement elem) {
-		ILicenseManager man = BldCore.getLicenseManager();
-		
-/*		ISigilProjectModel p = elem.getAncestor(ISigilProjectModel.class);
-		
-		ILicensePolicy policy = null;
-		
-		if ( p != null ) {
-			policy = man.getPolicy(p);
-		}
-		else {
-			policy = man.getDefaultPolicy();
-		}
-		
-		return policy; */
-		
-		return man.getDefaultPolicy();
-	}
-	
-	private void addClasspath(IBundleModelElement info, String cpStr) {
-		for ( String cp : cpStr.split( "\\s*,\\s*" ) ) {
-			info.addClasspath( cp );
-		}
-	}
+    public String getId()
+    {
+        return id;
+    }
 
-	private void addExports(IBundleModelElement info, String exportStr) throws ModelElementFactoryException {
-		for ( String exp : QuoteUtil.split( exportStr ) ) {
-			try { 
-				String[] parts = exp.split( ";" );
-				IPackageExport pe = ModelElementFactory.getInstance().newModelElement(IPackageExport.class);
-				pe.setPackageName( parts[0].trim() );
-				
-				if ( parts.length > 1 ) {
-					for (int i = 1; i < parts.length; i++ ) {
-						String check = parts[i];
-						if ( check.toLowerCase().startsWith( "version=" ) ) {
-							pe.setVersion( parseVersion(check.substring("version=".length())));
-						}
-						else if ( check.toLowerCase().startsWith( "specification-version=" ) ) {
-							pe.setVersion( parseVersion( check.substring("specification-version=".length()) ) );
-						}
-						else if ( check.toLowerCase().startsWith( "uses:=" ) ) {
-							for (String use : parseUses( check.substring( "uses:=".length() ) ) ) {
-								pe.addUse(use);
-							}
-						}
-					}
-				}
-				info.addExport(pe);
-			}
-			catch (RuntimeException e) {
-				e.printStackTrace();
-			}
-		}
-	}
 
-	private Collection<String> parseUses(String uses) {
-		if ( uses.startsWith( "\"") ) {
-			uses = uses.substring(1, uses.length() - 2 );
-		}
-		
-		return Arrays.asList( uses.split(",") );
-	}
+    public void accept( IRepositoryVisitor visitor )
+    {
+        accept( visitor, 0 );
+    }
 
-	private Version parseVersion(String val) {
-        val = val.replaceAll("\"", "");
-        return new Version(val);
-	}
 
-	private void addImports(IBundleModelElement info, String importStr) throws ModelElementFactoryException {
-		for ( String imp : QuoteUtil.split( importStr ) ) {
-			String[] parts = imp.split( ";" );
-			IPackageImport pi = ModelElementFactory.getInstance().newModelElement(IPackageImport.class);
-			pi.setPackageName( parts[0].trim() );
-			
-			if ( parts.length > 1 ) {
-				for ( int i = 1; i < parts.length; i++ ) {
-					String p = parts[i];
-					if ( p.toLowerCase().startsWith( "version=" ) ) {
-						pi.setVersions( VersionRange.parseVersionRange(p.substring("version=".length())));
-					}
-					else if ( p.toLowerCase().startsWith( "specification-version=" ) ) {
-						pi.setVersions( VersionRange.parseVersionRange( p.substring("specification-version=".length()) ));
-					}
-					else if ( p.toLowerCase().startsWith( "resolution:=" ) ) {
-						pi.setOptional( p.toLowerCase().substring("resolution:=".length()).equals( "optional") );
-					}
-				}
-			}
-			info.addImport(pi);
-		}
-	}
+    public void writeOBR( OutputStream out ) throws IOException
+    {
+        throw new UnsupportedOperationException();
+    }
 
-	private void addRequires(IBundleModelElement info, String reqStr) throws ModelElementFactoryException {
-		for ( String imp : QuoteUtil.split( reqStr ) ) {
-			String[] parts = imp.split( ";" );
-			IRequiredBundle req = ModelElementFactory.getInstance().newModelElement(IRequiredBundle.class);
-			req.setSymbolicName( parts[0] );
-			
-			if ( parts.length > 1 ) {
-				if ( parts[1].toLowerCase().startsWith( "version=" ) ) {
-					req.setVersions( VersionRange.parseVersionRange(parts[1].substring("version=".length())));
-				}
-				else if ( parts[1].toLowerCase().startsWith( "specification-version=" ) ) {
-					req.setVersions( VersionRange.parseVersionRange( parts[1].substring("specification-version=".length()) ));
-				}
-			}
-			info.addRequiredBundle(req);
-		}
-	}
-	
-	/**
-	 * @param info
-	 * @param str
-	 */
-	private void addHost(IBundleModelElement info, String str) {
-		String[] parts = str.split( ";" );
-		IRequiredBundle req = ModelElementFactory.getInstance().newModelElement(IRequiredBundle.class);
-		req.setSymbolicName( parts[0].trim() );
-		
-		if ( parts.length > 1 ) {
-			String part = parts[1].toLowerCase().trim();
-			if ( part.startsWith( "bundle-version=" ) ) {
-				req.setVersions( VersionRange.parseVersionRange(part.substring("bundle-version=".length())));
-			}
-		}
-		info.setFragmentHost(req);
-	}
+
+    public Collection<ISigilBundle> findProviders( final ILibrary library, int options )
+    {
+        final ArrayList<ISigilBundle> found = new ArrayList<ISigilBundle>();
+
+        final ILicensePolicy policy = findPolicy( library );
+
+        IRepositoryVisitor visitor = new IRepositoryVisitor()
+        {
+            public boolean visit( ISigilBundle bundle )
+            {
+                if ( policy.accept( bundle ) )
+                {
+                    IBundleModelElement info = bundle.getBundleInfo();
+                    for ( IPackageImport pi : library.getImports() )
+                    {
+                        for ( IPackageExport e : info.getExports() )
+                        {
+                            if ( pi.getPackageName().equals( e.getPackageName() )
+                                && pi.getVersions().contains( e.getVersion() ) )
+                            {
+                                found.add( bundle );
+                                break;
+                            }
+                        }
+                    }
+                }
+                return true;
+            }
+        };
+
+        accept( visitor, options );
+
+        return found;
+    }
+
+
+    public Collection<ISigilBundle> findAllProviders( final IRequiredBundle req, int options )
+    {
+        final ArrayList<ISigilBundle> found = new ArrayList<ISigilBundle>();
+
+        final ILicensePolicy policy = findPolicy( req );
+
+        IRepositoryVisitor visitor = new IRepositoryVisitor()
+        {
+            public boolean visit( ISigilBundle bundle )
+            {
+                if ( policy.accept( bundle ) )
+                {
+                    IBundleModelElement info = bundle.getBundleInfo();
+                    if ( req.getSymbolicName().equals( info.getSymbolicName() )
+                        && req.getVersions().contains( info.getVersion() ) )
+                    {
+                        found.add( bundle );
+                    }
+                }
+                return true;
+            }
+        };
+
+        accept( visitor, options );
+
+        return found;
+    }
+
+
+    public Collection<ISigilBundle> findAllProviders( final IPackageImport pi, int options )
+    {
+        final ArrayList<ISigilBundle> found = new ArrayList<ISigilBundle>();
+
+        final ILicensePolicy policy = findPolicy( pi );
+
+        IRepositoryVisitor visitor = new IRepositoryVisitor()
+        {
+
+            public boolean visit( ISigilBundle bundle )
+            {
+                if ( policy.accept( bundle ) )
+                {
+                    IBundleModelElement info = bundle.getBundleInfo();
+                    if ( info != null )
+                    {
+                        for ( IPackageExport e : info.getExports() )
+                        {
+                            if ( pi.getPackageName().equals( e.getPackageName() ) )
+                            {
+                                if ( pi.getVersions().contains( e.getVersion() ) )
+                                {
+                                    found.add( bundle );
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+                return true;
+            }
+
+        };
+
+        accept( visitor, options );
+
+        return found;
+    }
+
+
+    public ISigilBundle findProvider( final IPackageImport pi, int options )
+    {
+        final ArrayList<ISigilBundle> found = new ArrayList<ISigilBundle>();
+
+        final ILicensePolicy policy = findPolicy( pi );
+
+        IRepositoryVisitor visitor = new IRepositoryVisitor()
+        {
+            public boolean visit( ISigilBundle bundle )
+            {
+                if ( policy.accept( bundle ) )
+                {
+                    IBundleModelElement info = bundle.getBundleInfo();
+                    for ( IPackageExport e : info.getExports() )
+                    {
+                        if ( pi.getPackageName().equals( e.getPackageName() )
+                            && pi.getVersions().contains( e.getVersion() ) )
+                        {
+                            found.add( bundle );
+                            return false;
+                        }
+                    }
+                }
+                return true;
+            }
+
+        };
+
+        accept( visitor, options );
+
+        return found.isEmpty() ? null : found.iterator().next();
+    }
+
+
+    public ISigilBundle findProvider( final IRequiredBundle req, int options )
+    {
+        final ArrayList<ISigilBundle> found = new ArrayList<ISigilBundle>();
+
+        final ILicensePolicy policy = findPolicy( req );
+
+        IRepositoryVisitor visitor = new IRepositoryVisitor()
+        {
+
+            public boolean visit( ISigilBundle bundle )
+            {
+                if ( policy.accept( bundle ) )
+                {
+                    IBundleModelElement info = bundle.getBundleInfo();
+                    if ( req.getSymbolicName().equals( info.getSymbolicName() )
+                        && req.getVersions().contains( info.getVersion() ) )
+                    {
+                        found.add( bundle );
+                        return false;
+                    }
+                }
+                return true;
+            }
+
+        };
+
+        accept( visitor, options );
+
+        return found.isEmpty() ? null : found.iterator().next();
+    }
+
+
+    public IBundleModelElement buildBundleModelElement( Manifest mf )
+    {
+        IBundleModelElement info = null;
+
+        if ( mf != null )
+        {
+            Attributes attrs = mf.getMainAttributes();
+            String name = attrs.getValue( "Bundle-SymbolicName" );
+            if ( name == null )
+            {
+                // framework.jar doesn't have Bundle-SymbolicName!
+                name = attrs.getValue( "Bundle-Name" );
+            }
+
+            if ( name != null )
+            {
+                try
+                {
+                    info = ModelElementFactory.getInstance().newModelElement( IBundleModelElement.class );
+                    info.setSymbolicName( name.split( ";" )[0] );
+                    info.setVersion( Version.parseVersion( attrs.getValue( "Bundle-Version" ) ) );
+                    info.setName( attrs.getValue( "Bundle-Name" ) );
+                    info.setDescription( attrs.getValue( "Bundle-Description" ) );
+                    info.setVendor( attrs.getValue( "Bundle-Vendor" ) );
+
+                    String str = attrs.getValue( "Import-Package" );
+                    if ( str != null )
+                    {
+                        addImports( info, str );
+                    }
+
+                    str = attrs.getValue( "Export-Package" );
+                    if ( str != null )
+                    {
+                        addExports( info, str );
+                    }
+
+                    str = attrs.getValue( "Require-Bundle" );
+                    if ( str != null )
+                    {
+                        addRequires( info, str );
+                    }
+
+                    str = attrs.getValue( "Bundle-Classpath" );
+
+                    if ( str != null )
+                    {
+                        addClasspath( info, str );
+                    }
+
+                    str = attrs.getValue( "Fragment-Host" );
+                    if ( str != null )
+                    {
+                        addHost( info, str );
+                    }
+                }
+                catch ( RuntimeException e )
+                {
+                    BldCore.error( "Failed to read info from bundle " + name, e );
+                    // clear elements as clearly got garbage
+                    info = null;
+                }
+            }
+        }
+
+        return info;
+    }
+
+
+    protected ILicensePolicy findPolicy( IModelElement elem )
+    {
+        ILicenseManager man = BldCore.getLicenseManager();
+
+        /*		ISigilProjectModel p = elem.getAncestor(ISigilProjectModel.class);
+        		
+        		ILicensePolicy policy = null;
+        		
+        		if ( p != null ) {
+        			policy = man.getPolicy(p);
+        		}
+        		else {
+        			policy = man.getDefaultPolicy();
+        		}
+        		
+        		return policy; */
+
+        return man.getDefaultPolicy();
+    }
+
+
+    private void addClasspath( IBundleModelElement info, String cpStr )
+    {
+        for ( String cp : cpStr.split( "\\s*,\\s*" ) )
+        {
+            info.addClasspath( cp );
+        }
+    }
+
+
+    private void addExports( IBundleModelElement info, String exportStr ) throws ModelElementFactoryException
+    {
+        for ( String exp : QuoteUtil.split( exportStr ) )
+        {
+            try
+            {
+                String[] parts = exp.split( ";" );
+                IPackageExport pe = ModelElementFactory.getInstance().newModelElement( IPackageExport.class );
+                pe.setPackageName( parts[0].trim() );
+
+                if ( parts.length > 1 )
+                {
+                    for ( int i = 1; i < parts.length; i++ )
+                    {
+                        String check = parts[i];
+                        if ( check.toLowerCase().startsWith( "version=" ) )
+                        {
+                            pe.setVersion( parseVersion( check.substring( "version=".length() ) ) );
+                        }
+                        else if ( check.toLowerCase().startsWith( "specification-version=" ) )
+                        {
+                            pe.setVersion( parseVersion( check.substring( "specification-version=".length() ) ) );
+                        }
+                        else if ( check.toLowerCase().startsWith( "uses:=" ) )
+                        {
+                            for ( String use : parseUses( check.substring( "uses:=".length() ) ) )
+                            {
+                                pe.addUse( use );
+                            }
+                        }
+                    }
+                }
+                info.addExport( pe );
+            }
+            catch ( RuntimeException e )
+            {
+                e.printStackTrace();
+            }
+        }
+    }
+
+
+    private Collection<String> parseUses( String uses )
+    {
+        if ( uses.startsWith( "\"" ) )
+        {
+            uses = uses.substring( 1, uses.length() - 2 );
+        }
+
+        return Arrays.asList( uses.split( "," ) );
+    }
+
+
+    private Version parseVersion( String val )
+    {
+        val = val.replaceAll( "\"", "" );
+        return new Version( val );
+    }
+
+
+    private void addImports( IBundleModelElement info, String importStr ) throws ModelElementFactoryException
+    {
+        for ( String imp : QuoteUtil.split( importStr ) )
+        {
+            String[] parts = imp.split( ";" );
+            IPackageImport pi = ModelElementFactory.getInstance().newModelElement( IPackageImport.class );
+            pi.setPackageName( parts[0].trim() );
+
+            if ( parts.length > 1 )
+            {
+                for ( int i = 1; i < parts.length; i++ )
+                {
+                    String p = parts[i];
+                    if ( p.toLowerCase().startsWith( "version=" ) )
+                    {
+                        pi.setVersions( VersionRange.parseVersionRange( p.substring( "version=".length() ) ) );
+                    }
+                    else if ( p.toLowerCase().startsWith( "specification-version=" ) )
+                    {
+                        pi.setVersions( VersionRange
+                            .parseVersionRange( p.substring( "specification-version=".length() ) ) );
+                    }
+                    else if ( p.toLowerCase().startsWith( "resolution:=" ) )
+                    {
+                        pi.setOptional( p.toLowerCase().substring( "resolution:=".length() ).equals( "optional" ) );
+                    }
+                }
+            }
+            info.addImport( pi );
+        }
+    }
+
+
+    private void addRequires( IBundleModelElement info, String reqStr ) throws ModelElementFactoryException
+    {
+        for ( String imp : QuoteUtil.split( reqStr ) )
+        {
+            String[] parts = imp.split( ";" );
+            IRequiredBundle req = ModelElementFactory.getInstance().newModelElement( IRequiredBundle.class );
+            req.setSymbolicName( parts[0] );
+
+            if ( parts.length > 1 )
+            {
+                if ( parts[1].toLowerCase().startsWith( "version=" ) )
+                {
+                    req.setVersions( VersionRange.parseVersionRange( parts[1].substring( "version=".length() ) ) );
+                }
+                else if ( parts[1].toLowerCase().startsWith( "specification-version=" ) )
+                {
+                    req.setVersions( VersionRange.parseVersionRange( parts[1].substring( "specification-version="
+                        .length() ) ) );
+                }
+            }
+            info.addRequiredBundle( req );
+        }
+    }
+
+
+    /**
+     * @param info
+     * @param str
+     */
+    private void addHost( IBundleModelElement info, String str )
+    {
+        String[] parts = str.split( ";" );
+        IRequiredBundle req = ModelElementFactory.getInstance().newModelElement( IRequiredBundle.class );
+        req.setSymbolicName( parts[0].trim() );
+
+        if ( parts.length > 1 )
+        {
+            String part = parts[1].toLowerCase().trim();
+            if ( part.startsWith( "bundle-version=" ) )
+            {
+                req.setVersions( VersionRange.parseVersionRange( part.substring( "bundle-version=".length() ) ) );
+            }
+        }
+        info.setFragmentHost( req );
+    }
 }
\ No newline at end of file
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/AbstractRepositoryManager.java b/sigil/common/core/src/org/apache/felix/sigil/repository/AbstractRepositoryManager.java
index fd61b9b..247bce4 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/AbstractRepositoryManager.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/AbstractRepositoryManager.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.repository;
 
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -37,279 +38,369 @@
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
 import org.apache.felix.sigil.repository.RepositoryChangeEvent.Type;
 
-public abstract class AbstractRepositoryManager implements IRepositoryManager, IBundleRepositoryListener {
 
-	private HashSet<IRepositoryChangeListener> listeners = new HashSet<IRepositoryChangeListener>();
-	
-	private boolean initialised;
-	
-	private HashMap<String, IBundleRepository> repositories = new HashMap<String, IBundleRepository>();
-	private ArrayList<IBundleRepository> order = new ArrayList<IBundleRepository>();
-	private TreeMap<Integer, HashSet<IBundleRepository>> levelMap = new TreeMap<Integer, HashSet<IBundleRepository>>();
-	private int[] levels;
-	
-	private BundleResolver resolver = new BundleResolver(this);
-	
-	private ArrayList<ILibrary> libraries = new ArrayList<ILibrary>();
-	
-	public void initialise() {
-		synchronized( repositories ) {
-			if ( !initialised ) {
-				initialised = true;
-				loadRepositories();
-			}
-		}
-	}
-	
-	protected abstract void loadRepositories();
+public abstract class AbstractRepositoryManager implements IRepositoryManager, IBundleRepositoryListener
+{
 
-	public void addRepositoryChangeListener(IRepositoryChangeListener listener) {
-		synchronized(listeners) {
-			listeners.add(listener);			
-		}
-	}
+    private HashSet<IRepositoryChangeListener> listeners = new HashSet<IRepositoryChangeListener>();
 
-	public void removeRepositoryChangeListener(IRepositoryChangeListener listener) {
-		synchronized(listeners) {
-			listeners.remove(listener);
-		}
-	}
-	
-	public void notifyChange(IBundleRepository repository) {
-		notifyListeners( new RepositoryChangeEvent(repository, Type.CHANGED ) );
-	}
+    private boolean initialised;
 
-	private void notifyListeners(RepositoryChangeEvent event) {
-		ArrayList<IRepositoryChangeListener> safe = null;
-		synchronized(listeners) {
-			safe = new ArrayList<IRepositoryChangeListener>(listeners);
-		}
-		for ( IRepositoryChangeListener l : safe ) {
-			l.repositoryChanged(event);
-		}
-	}
-	
-	protected void setRepositories(IBundleRepository[] repos) {
-		synchronized( repositories ) {
-			repositories.clear();
-			order.clear();
-			levelMap.clear();
-			resetLevels();
-			if ( repos != null ) {
-				for ( int i = 0; i < repos.length; i++ ) {
-					addRepository(repos[i], i);
-				}
-			}
-		}
-	}
+    private HashMap<String, IBundleRepository> repositories = new HashMap<String, IBundleRepository>();
+    private ArrayList<IBundleRepository> order = new ArrayList<IBundleRepository>();
+    private TreeMap<Integer, HashSet<IBundleRepository>> levelMap = new TreeMap<Integer, HashSet<IBundleRepository>>();
+    private int[] levels;
 
-	protected void addRepository(IBundleRepository rep, int level) {
-		Type type = null;
-		
-		synchronized( repositories ) {
-			IBundleRepository old = repositories.put(rep.getId(), rep); 
-			if ( old == null ) {
-				type = Type.ADDED;
-				rep.addBundleRepositoryListener(this);
-			}
-			else {
-				old.removeBundleRepositoryListener(this);
-				type = Type.CHANGED;
-				order.remove(old);
-				clearLevel(rep);
-			}
-			
-			order.add(rep);
-			
-			HashSet<IBundleRepository> set = levelMap.get(level);
-			
-			if ( set == null ) {
-				set = new HashSet<IBundleRepository>();
-				levelMap.put( level, set );
-			}
-			
-			set.add( rep );
-			resetLevels();
-		}
-		
-		notifyListeners( new RepositoryChangeEvent(rep, type ) );
-	}
-	
-	protected void removeRepository(IBundleRepository rep) {
-		Type type = null;
-		
-		synchronized( repositories ) {
-			if ( repositories.remove(rep.getId()) != null ) {
-				order.remove(rep);
-				type = Type.REMOVED;
-				clearLevel(rep);
-				resetLevels();
-			}
-		}
-		
-		if ( type != null ) {
-			notifyListeners( new RepositoryChangeEvent(rep, type ) );
-		}
-	}
-	
-	private void clearLevel(IBundleRepository rep) {
-		for ( Iterator<Map.Entry<Integer, HashSet<IBundleRepository>>> iter = levelMap.entrySet().iterator(); iter.hasNext(); ) {
-			Map.Entry<Integer, HashSet<IBundleRepository>> e = iter.next();
-			if ( e.getValue().remove(rep) ) {
-				if ( e.getValue().isEmpty() ) {
-					iter.remove();
-				}					
-				break;
-			}				
-		}
-	}
+    private BundleResolver resolver = new BundleResolver( this );
 
-	public Collection<IBundleRepository> getRepositories() {
-		initialise();
-		ArrayList<IBundleRepository> safe = null;
-		
-		synchronized( repositories ) {
-			safe = new ArrayList<IBundleRepository>( order );
-		}
-		
-		return safe;
-	}
+    private ArrayList<ILibrary> libraries = new ArrayList<ILibrary>();
 
-	private void resetLevels() {
-		Collections.sort(order, new Comparator<IBundleRepository>() {
-			public int compare(IBundleRepository o1, IBundleRepository o2) {
-				int l1 = findLevel(o1);
-				int l2 = findLevel(o2);
-				
-				if ( l1 < l2 ) {
-					return -1;
-				}
-				else if ( l1 > l2 ) {
-					return 1;
-				}
-				else {
-					return 0;
-				}
-			}
 
-			private int findLevel(IBundleRepository rep) {
-				for ( Map.Entry<Integer, HashSet<IBundleRepository>> e : levelMap.entrySet() ) {
-					if ( e.getValue().contains( rep ) ) {
-						return e.getKey();
-					}
-				}
-				throw new IllegalStateException();
-			}
-		});
-		levels = new int[levelMap.size()];
-		int i = 0;
-		for ( Integer v : levelMap.keySet() ) {
-			levels[i++] = v;
-		}			
-	}
-	
+    public void initialise()
+    {
+        synchronized ( repositories )
+        {
+            if ( !initialised )
+            {
+                initialised = true;
+                loadRepositories();
+            }
+        }
+    }
 
-	public int[] getPriorityLevels() {
-		initialise();
-		synchronized( repositories ) {
-			return levels;
-		}
-	}
 
-	public Collection<IBundleRepository> getRepositories(int priorityLevel) {
-		initialise();
-		List<IBundleRepository> found = null;
-		
-		synchronized (repositories) {
-			HashSet<IBundleRepository> b = levelMap.get(priorityLevel);
-			if ( b == null ) {
-				found = Collections.emptyList();
-			}
-			else {
-				found = new ArrayList<IBundleRepository>(b);
-			}
-		}
-		
-		return found;
-	}
+    protected abstract void loadRepositories();
 
-	public void addLibrary(ILibrary library) {
-		synchronized( libraries ) {
-			libraries.add(library);
-		}
-	}
-	
-	public void removeLibrary(ILibrary library) {
-		synchronized( libraries ) {
-			libraries.remove(library);
-		}
-	}
-	
-	public Collection<ILibrary> getLibraries() {
-		synchronized( libraries ) {
-			return libraries;
-		}
-	}
 
-	public ILibrary resolveLibrary(final ILibraryImport l) {
-		final ArrayList<ILibrary> found = new ArrayList<ILibrary>(1);
-		//ISigilProjectModel p = l.getAncestor(ISigilProjectModel.class);
-		//
-		//IModelWalker w = new IModelWalker() {
-		//	public boolean visit(IModelElement element) {
-		//		if ( element instanceof ILibrary ) {
-		//			updateLibrary(l, (ILibrary) element, found);
-		//			return false;
-		//		}
-		//		
-		//		return true;
-		//	}
-		//};
-		
-		//p.visit( w );
-		
-		//if ( found.isEmpty() ) { // no project specific libraries - check workspace definitions
-			synchronized( libraries ) {
-				for ( ILibrary lib : libraries ) {
-					if ( l.getLibraryName().equals( lib.getName() ) && l.getVersions().contains(lib.getVersion()) ) {
-						updateLibrary(l, lib, found);
-					}
-				}
-			}
-		//}
-		
-		return found.isEmpty() ? null : found.get(0);		
-	}
+    public void addRepositoryChangeListener( IRepositoryChangeListener listener )
+    {
+        synchronized ( listeners )
+        {
+            listeners.add( listener );
+        }
+    }
 
-	protected void updateLibrary(ILibraryImport li, ILibrary l, ArrayList<ILibrary> found) {
-		if ( li.getLibraryName().equals( l.getName() ) && li.getVersions().contains(l.getVersion()) ) {
-			if ( found.isEmpty() ) {
-				found.add( l );
-			}
-			else {
-				ILibrary c = found.get(0);
-				if ( l.getVersion().compareTo(c.getVersion()) > 0 ) {
-					found.remove(0);
-					found.add(l);
-				}
-			}
-		}
-	}
 
-	public IBundleResolver getBundleResolver() {
-		return resolver;
-	}
+    public void removeRepositoryChangeListener( IRepositoryChangeListener listener )
+    {
+        synchronized ( listeners )
+        {
+            listeners.remove( listener );
+        }
+    }
 
-	public void visit(final IModelWalker walker) {
-		for (IBundleRepository rep : getRepositories()) {
-			IRepositoryVisitor wrapper = new IRepositoryVisitor() {
-				public boolean visit(ISigilBundle bundle) {
-					bundle.visit(walker);
-					// return true as still want to visit other bundles
-					return true;
-				}
-			};
-			rep.accept(wrapper);
-		}
-	}
+
+    public void notifyChange( IBundleRepository repository )
+    {
+        notifyListeners( new RepositoryChangeEvent( repository, Type.CHANGED ) );
+    }
+
+
+    private void notifyListeners( RepositoryChangeEvent event )
+    {
+        ArrayList<IRepositoryChangeListener> safe = null;
+        synchronized ( listeners )
+        {
+            safe = new ArrayList<IRepositoryChangeListener>( listeners );
+        }
+        for ( IRepositoryChangeListener l : safe )
+        {
+            l.repositoryChanged( event );
+        }
+    }
+
+
+    protected void setRepositories( IBundleRepository[] repos )
+    {
+        synchronized ( repositories )
+        {
+            repositories.clear();
+            order.clear();
+            levelMap.clear();
+            resetLevels();
+            if ( repos != null )
+            {
+                for ( int i = 0; i < repos.length; i++ )
+                {
+                    addRepository( repos[i], i );
+                }
+            }
+        }
+    }
+
+
+    protected void addRepository( IBundleRepository rep, int level )
+    {
+        Type type = null;
+
+        synchronized ( repositories )
+        {
+            IBundleRepository old = repositories.put( rep.getId(), rep );
+            if ( old == null )
+            {
+                type = Type.ADDED;
+                rep.addBundleRepositoryListener( this );
+            }
+            else
+            {
+                old.removeBundleRepositoryListener( this );
+                type = Type.CHANGED;
+                order.remove( old );
+                clearLevel( rep );
+            }
+
+            order.add( rep );
+
+            HashSet<IBundleRepository> set = levelMap.get( level );
+
+            if ( set == null )
+            {
+                set = new HashSet<IBundleRepository>();
+                levelMap.put( level, set );
+            }
+
+            set.add( rep );
+            resetLevels();
+        }
+
+        notifyListeners( new RepositoryChangeEvent( rep, type ) );
+    }
+
+
+    protected void removeRepository( IBundleRepository rep )
+    {
+        Type type = null;
+
+        synchronized ( repositories )
+        {
+            if ( repositories.remove( rep.getId() ) != null )
+            {
+                order.remove( rep );
+                type = Type.REMOVED;
+                clearLevel( rep );
+                resetLevels();
+            }
+        }
+
+        if ( type != null )
+        {
+            notifyListeners( new RepositoryChangeEvent( rep, type ) );
+        }
+    }
+
+
+    private void clearLevel( IBundleRepository rep )
+    {
+        for ( Iterator<Map.Entry<Integer, HashSet<IBundleRepository>>> iter = levelMap.entrySet().iterator(); iter
+            .hasNext(); )
+        {
+            Map.Entry<Integer, HashSet<IBundleRepository>> e = iter.next();
+            if ( e.getValue().remove( rep ) )
+            {
+                if ( e.getValue().isEmpty() )
+                {
+                    iter.remove();
+                }
+                break;
+            }
+        }
+    }
+
+
+    public Collection<IBundleRepository> getRepositories()
+    {
+        initialise();
+        ArrayList<IBundleRepository> safe = null;
+
+        synchronized ( repositories )
+        {
+            safe = new ArrayList<IBundleRepository>( order );
+        }
+
+        return safe;
+    }
+
+
+    private void resetLevels()
+    {
+        Collections.sort( order, new Comparator<IBundleRepository>()
+        {
+            public int compare( IBundleRepository o1, IBundleRepository o2 )
+            {
+                int l1 = findLevel( o1 );
+                int l2 = findLevel( o2 );
+
+                if ( l1 < l2 )
+                {
+                    return -1;
+                }
+                else if ( l1 > l2 )
+                {
+                    return 1;
+                }
+                else
+                {
+                    return 0;
+                }
+            }
+
+
+            private int findLevel( IBundleRepository rep )
+            {
+                for ( Map.Entry<Integer, HashSet<IBundleRepository>> e : levelMap.entrySet() )
+                {
+                    if ( e.getValue().contains( rep ) )
+                    {
+                        return e.getKey();
+                    }
+                }
+                throw new IllegalStateException();
+            }
+        } );
+        levels = new int[levelMap.size()];
+        int i = 0;
+        for ( Integer v : levelMap.keySet() )
+        {
+            levels[i++] = v;
+        }
+    }
+
+
+    public int[] getPriorityLevels()
+    {
+        initialise();
+        synchronized ( repositories )
+        {
+            return levels;
+        }
+    }
+
+
+    public Collection<IBundleRepository> getRepositories( int priorityLevel )
+    {
+        initialise();
+        List<IBundleRepository> found = null;
+
+        synchronized ( repositories )
+        {
+            HashSet<IBundleRepository> b = levelMap.get( priorityLevel );
+            if ( b == null )
+            {
+                found = Collections.emptyList();
+            }
+            else
+            {
+                found = new ArrayList<IBundleRepository>( b );
+            }
+        }
+
+        return found;
+    }
+
+
+    public void addLibrary( ILibrary library )
+    {
+        synchronized ( libraries )
+        {
+            libraries.add( library );
+        }
+    }
+
+
+    public void removeLibrary( ILibrary library )
+    {
+        synchronized ( libraries )
+        {
+            libraries.remove( library );
+        }
+    }
+
+
+    public Collection<ILibrary> getLibraries()
+    {
+        synchronized ( libraries )
+        {
+            return libraries;
+        }
+    }
+
+
+    public ILibrary resolveLibrary( final ILibraryImport l )
+    {
+        final ArrayList<ILibrary> found = new ArrayList<ILibrary>( 1 );
+        //ISigilProjectModel p = l.getAncestor(ISigilProjectModel.class);
+        //
+        //IModelWalker w = new IModelWalker() {
+        //	public boolean visit(IModelElement element) {
+        //		if ( element instanceof ILibrary ) {
+        //			updateLibrary(l, (ILibrary) element, found);
+        //			return false;
+        //		}
+        //		
+        //		return true;
+        //	}
+        //};
+
+        //p.visit( w );
+
+        //if ( found.isEmpty() ) { // no project specific libraries - check workspace definitions
+        synchronized ( libraries )
+        {
+            for ( ILibrary lib : libraries )
+            {
+                if ( l.getLibraryName().equals( lib.getName() ) && l.getVersions().contains( lib.getVersion() ) )
+                {
+                    updateLibrary( l, lib, found );
+                }
+            }
+        }
+        //}
+
+        return found.isEmpty() ? null : found.get( 0 );
+    }
+
+
+    protected void updateLibrary( ILibraryImport li, ILibrary l, ArrayList<ILibrary> found )
+    {
+        if ( li.getLibraryName().equals( l.getName() ) && li.getVersions().contains( l.getVersion() ) )
+        {
+            if ( found.isEmpty() )
+            {
+                found.add( l );
+            }
+            else
+            {
+                ILibrary c = found.get( 0 );
+                if ( l.getVersion().compareTo( c.getVersion() ) > 0 )
+                {
+                    found.remove( 0 );
+                    found.add( l );
+                }
+            }
+        }
+    }
+
+
+    public IBundleResolver getBundleResolver()
+    {
+        return resolver;
+    }
+
+
+    public void visit( final IModelWalker walker )
+    {
+        for ( IBundleRepository rep : getRepositories() )
+        {
+            IRepositoryVisitor wrapper = new IRepositoryVisitor()
+            {
+                public boolean visit( ISigilBundle bundle )
+                {
+                    bundle.visit( walker );
+                    // return true as still want to visit other bundles
+                    return true;
+                }
+            };
+            rep.accept( wrapper );
+        }
+    }
 }
\ No newline at end of file
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/IBundleRepository.java b/sigil/common/core/src/org/apache/felix/sigil/repository/IBundleRepository.java
index 281f707..d33d691 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/IBundleRepository.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/IBundleRepository.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.repository;
 
+
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.Collection;
@@ -28,32 +29,46 @@
 import org.apache.felix.sigil.model.osgi.IPackageImport;
 import org.apache.felix.sigil.model.osgi.IRequiredBundle;
 
-public interface IBundleRepository {
-	static final int NORMAL_PRIORITY = 0;
-	static final int MAXIMUM_PRIORITY = -500;
-	static final int MINIMUM_PRIORITY = 500;
-	
-	String getId();
-	
-	void addBundleRepositoryListener(IBundleRepositoryListener listener);
-	
-	void removeBundleRepositoryListener(IBundleRepositoryListener listener);
-	
-	void accept(IRepositoryVisitor visitor);
-	
-	void accept(IRepositoryVisitor visitor, int options);
-	
-	void writeOBR(OutputStream out) throws IOException;
-	
-	void refresh();
-	
-	ISigilBundle findProvider(IPackageImport packageImport, int options);
-	
-	ISigilBundle findProvider(IRequiredBundle bundle, int options);
-	
-	Collection<ISigilBundle> findAllProviders(IRequiredBundle bundle, int options);
-	
-	Collection<ISigilBundle> findAllProviders(IPackageImport packageImport, int options);
-	
-	Collection<ISigilBundle> findProviders(ILibrary library, int options);
+
+public interface IBundleRepository
+{
+    static final int NORMAL_PRIORITY = 0;
+    static final int MAXIMUM_PRIORITY = -500;
+    static final int MINIMUM_PRIORITY = 500;
+
+
+    String getId();
+
+
+    void addBundleRepositoryListener( IBundleRepositoryListener listener );
+
+
+    void removeBundleRepositoryListener( IBundleRepositoryListener listener );
+
+
+    void accept( IRepositoryVisitor visitor );
+
+
+    void accept( IRepositoryVisitor visitor, int options );
+
+
+    void writeOBR( OutputStream out ) throws IOException;
+
+
+    void refresh();
+
+
+    ISigilBundle findProvider( IPackageImport packageImport, int options );
+
+
+    ISigilBundle findProvider( IRequiredBundle bundle, int options );
+
+
+    Collection<ISigilBundle> findAllProviders( IRequiredBundle bundle, int options );
+
+
+    Collection<ISigilBundle> findAllProviders( IPackageImport packageImport, int options );
+
+
+    Collection<ISigilBundle> findProviders( ILibrary library, int options );
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/IBundleRepositoryListener.java b/sigil/common/core/src/org/apache/felix/sigil/repository/IBundleRepositoryListener.java
index 1f94760..4b4d45b 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/IBundleRepositoryListener.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/IBundleRepositoryListener.java
@@ -19,6 +19,8 @@
 
 package org.apache.felix.sigil.repository;
 
-public interface IBundleRepositoryListener {
-	void notifyChange(IBundleRepository repository);
+
+public interface IBundleRepositoryListener
+{
+    void notifyChange( IBundleRepository repository );
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/IBundleResolver.java b/sigil/common/core/src/org/apache/felix/sigil/repository/IBundleResolver.java
index d819f24..42180ef 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/IBundleResolver.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/IBundleResolver.java
@@ -19,8 +19,12 @@
 
 package org.apache.felix.sigil.repository;
 
+
 import org.apache.felix.sigil.model.IModelElement;
 
-public interface IBundleResolver {
-	IResolution resolve(IModelElement element, ResolutionConfig config, IResolutionMonitor monitor) throws ResolutionException;
+
+public interface IBundleResolver
+{
+    IResolution resolve( IModelElement element, ResolutionConfig config, IResolutionMonitor monitor )
+        throws ResolutionException;
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/IProviderChangeListener.java b/sigil/common/core/src/org/apache/felix/sigil/repository/IProviderChangeListener.java
index 254d316..b6c4bd6 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/IProviderChangeListener.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/IProviderChangeListener.java
@@ -19,6 +19,8 @@
 
 package org.apache.felix.sigil.repository;
 
-public interface IProviderChangeListener {
-	void notifyChange(IRepositoryProvider provider);
+
+public interface IProviderChangeListener
+{
+    void notifyChange( IRepositoryProvider provider );
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryChangeListener.java b/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryChangeListener.java
index 29394be..6d85e29 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryChangeListener.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryChangeListener.java
@@ -19,6 +19,8 @@
 
 package org.apache.felix.sigil.repository;
 
-public interface IRepositoryChangeListener {
-	void repositoryChanged(RepositoryChangeEvent event);
+
+public interface IRepositoryChangeListener
+{
+    void repositoryChanged( RepositoryChangeEvent event );
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryManager.java b/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryManager.java
index 5259b95..4c4d27d 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryManager.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryManager.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.repository;
 
+
 import java.util.Collection;
 
 import org.apache.felix.sigil.model.IModelWalker;
@@ -26,26 +27,38 @@
 import org.apache.felix.sigil.model.eclipse.ILibraryImport;
 import org.eclipse.core.runtime.CoreException;
 
-public interface IRepositoryManager {
-	void addRepositoryChangeListener(IRepositoryChangeListener listener);
-	
-	void removeRepositoryChangeListener(IRepositoryChangeListener listener);
-	
-	Collection<IBundleRepository> getRepositories();
-	
-	Collection<IBundleRepository> getRepositories(int level);
-	
-	void addLibrary(ILibrary library);
 
-	void removeLibrary(ILibrary library);
+public interface IRepositoryManager
+{
+    void addRepositoryChangeListener( IRepositoryChangeListener listener );
 
-	Collection<ILibrary> getLibraries();
 
-	ILibrary resolveLibrary(final ILibraryImport l);
-	
-	IBundleResolver getBundleResolver();
+    void removeRepositoryChangeListener( IRepositoryChangeListener listener );
 
-	int[] getPriorityLevels();
 
-	void visit(IModelWalker modelWalker);	
+    Collection<IBundleRepository> getRepositories();
+
+
+    Collection<IBundleRepository> getRepositories( int level );
+
+
+    void addLibrary( ILibrary library );
+
+
+    void removeLibrary( ILibrary library );
+
+
+    Collection<ILibrary> getLibraries();
+
+
+    ILibrary resolveLibrary( final ILibraryImport l );
+
+
+    IBundleResolver getBundleResolver();
+
+
+    int[] getPriorityLevels();
+
+
+    void visit( IModelWalker modelWalker );
 }
\ No newline at end of file
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryProvider.java b/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryProvider.java
index f8a023e..48dc3b2 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryProvider.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryProvider.java
@@ -19,8 +19,11 @@
 
 package org.apache.felix.sigil.repository;
 
+
 import java.util.Properties;
 
-public interface IRepositoryProvider {
-    IBundleRepository createRepository(String id, Properties properties) throws RepositoryException;
+
+public interface IRepositoryProvider
+{
+    IBundleRepository createRepository( String id, Properties properties ) throws RepositoryException;
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryVisitor.java b/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryVisitor.java
index 6ebb192..6258a0f 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryVisitor.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/IRepositoryVisitor.java
@@ -19,14 +19,17 @@
 
 package org.apache.felix.sigil.repository;
 
+
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
 
-public interface IRepositoryVisitor {
-	/**
-	 * Visit the next bundle in the repository. 
-	 * Return true if should continue visiting other bundles, false otherwise.
-	 * @param bundle
-	 * @return
-	 */
-	boolean visit(ISigilBundle bundle);
+
+public interface IRepositoryVisitor
+{
+    /**
+     * Visit the next bundle in the repository. 
+     * Return true if should continue visiting other bundles, false otherwise.
+     * @param bundle
+     * @return
+     */
+    boolean visit( ISigilBundle bundle );
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/IResolution.java b/sigil/common/core/src/org/apache/felix/sigil/repository/IResolution.java
index 4831ad0..3bb0688 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/IResolution.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/IResolution.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.repository;
 
+
 import java.util.List;
 import java.util.Set;
 
@@ -26,10 +27,20 @@
 import org.apache.felix.sigil.model.IModelElement;
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
 
-public interface IResolution {
-	Set<ISigilBundle> getBundles();
-	ISigilBundle getProvider(IModelElement requirement);
-	List<IModelElement> getMatchedRequirements(ISigilBundle bundle);
-	void synchronize(IProgressMonitor monitor);
-	boolean isSynchronized();
+
+public interface IResolution
+{
+    Set<ISigilBundle> getBundles();
+
+
+    ISigilBundle getProvider( IModelElement requirement );
+
+
+    List<IModelElement> getMatchedRequirements( ISigilBundle bundle );
+
+
+    void synchronize( IProgressMonitor monitor );
+
+
+    boolean isSynchronized();
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/IResolutionMonitor.java b/sigil/common/core/src/org/apache/felix/sigil/repository/IResolutionMonitor.java
index 814fdae..b55679f 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/IResolutionMonitor.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/IResolutionMonitor.java
@@ -19,11 +19,18 @@
 
 package org.apache.felix.sigil.repository;
 
+
 import org.apache.felix.sigil.model.IModelElement;
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
 
-public interface IResolutionMonitor {
-	boolean isCanceled();
-	void startResolution(IModelElement requirement);
-	void endResolution(IModelElement requirement, ISigilBundle sigilBundle);
+
+public interface IResolutionMonitor
+{
+    boolean isCanceled();
+
+
+    void startResolution( IModelElement requirement );
+
+
+    void endResolution( IModelElement requirement, ISigilBundle sigilBundle );
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/RepositoryChangeEvent.java b/sigil/common/core/src/org/apache/felix/sigil/repository/RepositoryChangeEvent.java
index 54dbb7a..9938db0 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/RepositoryChangeEvent.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/RepositoryChangeEvent.java
@@ -19,21 +19,33 @@
 
 package org.apache.felix.sigil.repository;
 
-public class RepositoryChangeEvent {
-	public static enum Type { ADDED, CHANGED, REMOVED };
-	
-	private Type type;
-	private IBundleRepository repository;
-	
-	public RepositoryChangeEvent(IBundleRepository repository, Type type) {
-		this.repository = repository;
-		this.type = type;
-	}
-	
-	public Type getType() {
-		return type;
-	}
-	public IBundleRepository getRepository() {
-		return repository;
-	}
+
+public class RepositoryChangeEvent
+{
+    public static enum Type
+    {
+        ADDED, CHANGED, REMOVED
+    };
+
+    private Type type;
+    private IBundleRepository repository;
+
+
+    public RepositoryChangeEvent( IBundleRepository repository, Type type )
+    {
+        this.repository = repository;
+        this.type = type;
+    }
+
+
+    public Type getType()
+    {
+        return type;
+    }
+
+
+    public IBundleRepository getRepository()
+    {
+        return repository;
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/RepositoryException.java b/sigil/common/core/src/org/apache/felix/sigil/repository/RepositoryException.java
index b521961..332bd22 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/RepositoryException.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/RepositoryException.java
@@ -19,20 +19,28 @@
 
 package org.apache.felix.sigil.repository;
 
-public class RepositoryException extends Exception {
 
-	private static final long serialVersionUID = 1L;
+public class RepositoryException extends Exception
+{
 
-	public RepositoryException(String msg, Throwable cause) {
-		super(msg, cause);
-	}
+    private static final long serialVersionUID = 1L;
 
-	public RepositoryException(String message) {
-		super(message);
-	}
 
-	public RepositoryException(Throwable cause) {
-		super(cause);
-	}
+    public RepositoryException( String msg, Throwable cause )
+    {
+        super( msg, cause );
+    }
+
+
+    public RepositoryException( String message )
+    {
+        super( message );
+    }
+
+
+    public RepositoryException( Throwable cause )
+    {
+        super( cause );
+    }
 
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/ResolutionConfig.java b/sigil/common/core/src/org/apache/felix/sigil/repository/ResolutionConfig.java
index de49072..54571b5 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/ResolutionConfig.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/ResolutionConfig.java
@@ -19,43 +19,59 @@
 
 package org.apache.felix.sigil.repository;
 
-public class ResolutionConfig {
-	private int options;
-	
-	public static final int INCLUDE_DEPENDENTS = 1;
-	public static final int INCLUDE_OPTIONAL = 2;
-	public static final int IGNORE_ERRORS = 4;
-	/** Return only bundles that are indexed locally */
-	public static final int INDEXED_ONLY = 8;
-	/** Return only bundles that are stored or cached locally */
-	public static final int LOCAL_ONLY = 16;
 
-	public ResolutionConfig() {
-		this(INCLUDE_DEPENDENTS);
-	}
-	
-	public ResolutionConfig(int options) {
-		this.options = options;
-	}
+public class ResolutionConfig
+{
+    private int options;
 
-	public int getOptions() {
-		return options;
-	}
+    public static final int INCLUDE_DEPENDENTS = 1;
+    public static final int INCLUDE_OPTIONAL = 2;
+    public static final int IGNORE_ERRORS = 4;
+    /** Return only bundles that are indexed locally */
+    public static final int INDEXED_ONLY = 8;
+    /** Return only bundles that are stored or cached locally */
+    public static final int LOCAL_ONLY = 16;
 
-	public boolean isDependents() {
-		return (options & INCLUDE_DEPENDENTS) != 0;
-	}
 
-	public boolean isIgnoreErrors() {
-		return (options & IGNORE_ERRORS) != 0;
-	}
-	
-	public boolean isOptional() {
-		return (options & INCLUDE_OPTIONAL) != 0;
-	}
+    public ResolutionConfig()
+    {
+        this( INCLUDE_DEPENDENTS );
+    }
 
-	public boolean isCalculateLocalDependencies() {
-		// TODO Auto-generated method stub
-		return false;
-	}
+
+    public ResolutionConfig( int options )
+    {
+        this.options = options;
+    }
+
+
+    public int getOptions()
+    {
+        return options;
+    }
+
+
+    public boolean isDependents()
+    {
+        return ( options & INCLUDE_DEPENDENTS ) != 0;
+    }
+
+
+    public boolean isIgnoreErrors()
+    {
+        return ( options & IGNORE_ERRORS ) != 0;
+    }
+
+
+    public boolean isOptional()
+    {
+        return ( options & INCLUDE_OPTIONAL ) != 0;
+    }
+
+
+    public boolean isCalculateLocalDependencies()
+    {
+        // TODO Auto-generated method stub
+        return false;
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/ResolutionException.java b/sigil/common/core/src/org/apache/felix/sigil/repository/ResolutionException.java
index 92bb07f..9972110 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/ResolutionException.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/ResolutionException.java
@@ -19,45 +19,61 @@
 
 package org.apache.felix.sigil.repository;
 
+
 import org.apache.felix.sigil.model.IModelElement;
 
-public class ResolutionException extends Exception {
 
-	private static final long serialVersionUID = 1L;
-	
-	private IModelElement[] parsed;
-	
-	public ResolutionException(String message, Throwable cause) {
-		super(message, cause);
-	}
+public class ResolutionException extends Exception
+{
 
-	public ResolutionException(String message) {
-		super(message);
-	}
+    private static final long serialVersionUID = 1L;
 
-	public ResolutionException(Throwable cause) {
-		super(cause);
-	}
+    private IModelElement[] parsed;
 
-	public ResolutionException(IModelElement root, IModelElement[] parsed) {
-		super(buildMessage(root, parsed));
-		this.parsed = parsed;
-	}
-	
-	private static String buildMessage(IModelElement root, IModelElement[] parsed) {
-		StringBuilder b = new StringBuilder();
-		b.append( "Failed to resolve " );
-		b.append( root );
-		
-		if ( parsed.length > 0 ) {
-			b.append( " due to missing provider for " );
-			b.append( parsed[parsed.length - 1] );
-		}
-		
-		return b.toString();
-	}
 
-	public IModelElement[] getParsed() {
-		return parsed;
-	}
+    public ResolutionException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+
+    public ResolutionException( String message )
+    {
+        super( message );
+    }
+
+
+    public ResolutionException( Throwable cause )
+    {
+        super( cause );
+    }
+
+
+    public ResolutionException( IModelElement root, IModelElement[] parsed )
+    {
+        super( buildMessage( root, parsed ) );
+        this.parsed = parsed;
+    }
+
+
+    private static String buildMessage( IModelElement root, IModelElement[] parsed )
+    {
+        StringBuilder b = new StringBuilder();
+        b.append( "Failed to resolve " );
+        b.append( root );
+
+        if ( parsed.length > 0 )
+        {
+            b.append( " due to missing provider for " );
+            b.append( parsed[parsed.length - 1] );
+        }
+
+        return b.toString();
+    }
+
+
+    public IModelElement[] getParsed()
+    {
+        return parsed;
+    }
 }
diff --git a/sigil/common/core/src/org/apache/felix/sigil/repository/ResolutionMonitorAdapter.java b/sigil/common/core/src/org/apache/felix/sigil/repository/ResolutionMonitorAdapter.java
index 92cbbe1..4c5b676 100644
--- a/sigil/common/core/src/org/apache/felix/sigil/repository/ResolutionMonitorAdapter.java
+++ b/sigil/common/core/src/org/apache/felix/sigil/repository/ResolutionMonitorAdapter.java
@@ -19,28 +19,39 @@
 
 package org.apache.felix.sigil.repository;
 
+
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.apache.felix.sigil.model.IModelElement;
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
 
-public class ResolutionMonitorAdapter implements IResolutionMonitor {
 
-	private IProgressMonitor monitor;
-	
-	public ResolutionMonitorAdapter(IProgressMonitor monitor) {
-		this.monitor = monitor;
-	}
+public class ResolutionMonitorAdapter implements IResolutionMonitor
+{
 
-	public boolean isCanceled() {
-		return monitor.isCanceled();
-	}
+    private IProgressMonitor monitor;
 
-	public void startResolution(IModelElement requirement) {
-		monitor.subTask( "Resolving " + requirement);
-	}
 
-	public void endResolution(IModelElement requirement, ISigilBundle provider) {
-		monitor.subTask( (provider == null ? "Failed to resolve " : "Resolved ") + requirement);
-	}
+    public ResolutionMonitorAdapter( IProgressMonitor monitor )
+    {
+        this.monitor = monitor;
+    }
+
+
+    public boolean isCanceled()
+    {
+        return monitor.isCanceled();
+    }
+
+
+    public void startResolution( IModelElement requirement )
+    {
+        monitor.subTask( "Resolving " + requirement );
+    }
+
+
+    public void endResolution( IModelElement requirement, ISigilBundle provider )
+    {
+        monitor.subTask( ( provider == null ? "Failed to resolve " : "Resolved " ) + requirement );
+    }
 
 }
diff --git a/sigil/common/junit/src/org/apache/felix/sigil/junit/AbstractSigilTestCase.java b/sigil/common/junit/src/org/apache/felix/sigil/junit/AbstractSigilTestCase.java
index 53e62e8..677ed5e 100644
--- a/sigil/common/junit/src/org/apache/felix/sigil/junit/AbstractSigilTestCase.java
+++ b/sigil/common/junit/src/org/apache/felix/sigil/junit/AbstractSigilTestCase.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.junit;
 
+
 import java.lang.reflect.Method;
 import java.util.LinkedList;
 import java.util.List;
@@ -30,71 +31,99 @@
 
 import junit.framework.TestCase;
 
-public abstract class AbstractSigilTestCase extends TestCase {
 
-	private final static List<ServiceTracker> trackers = new LinkedList<ServiceTracker>();
-	
-	private BundleContext ctx;
-	
-	public void setBundleContext(BundleContext ctx) {
-		this.ctx = ctx;
-	}
-	
-	protected BundleContext getBundleContext() {
-		return ctx;
-	}
-	
-	@Override
-	protected void setUp() {
-		for ( Class<?> c : getReferences() ) {
-			ServiceTracker t = createBindTracker(c);
-			t.open();
-			trackers.add( t );
-		}
-	}
+public abstract class AbstractSigilTestCase extends TestCase
+{
 
-	@Override
-	protected void tearDown() {
-		for ( ServiceTracker t : trackers ) {
-			t.close();
-		}
-		trackers.clear();
-	}
+    private final static List<ServiceTracker> trackers = new LinkedList<ServiceTracker>();
+
+    private BundleContext ctx;
 
 
-	private ServiceTracker createBindTracker(final Class<?> c) {
-		return new ServiceTracker(ctx, c.getName(), new ServiceTrackerCustomizer() {
-			public Object addingService(ServiceReference reference) {
-				Object o = ctx.getService(reference);
-				Method m = getBindMethod(c);
-				if ( m != null ) invoke( m, o );
-				return o;
-			}
+    public void setBundleContext( BundleContext ctx )
+    {
+        this.ctx = ctx;
+    }
 
-			public void modifiedService(ServiceReference reference,
-					Object service) {
-			}
 
-			public void removedService(ServiceReference reference,
-					Object service) {
-				Method m = getUnbindMethod(c);
-				if ( m != null ) invoke( m, service );
-				ctx.ungetService(reference);
-			}
-		});
-	}
-	
-	private void invoke(Method m, Object o) {
-		try {
-			m.invoke( this,  new Object[] { o } );
-		} catch (Exception e) {
-			throw new IllegalStateException( "Failed to invoke binding method " + m, e);
-		}
-	}
+    protected BundleContext getBundleContext()
+    {
+        return ctx;
+    }
 
-	protected abstract Class<?>[] getReferences();
-	
-	protected abstract Method getBindMethod(Class<?> clazz);
-	
-	protected abstract  Method getUnbindMethod(Class<?> clazz);
+
+    @Override
+    protected void setUp()
+    {
+        for ( Class<?> c : getReferences() )
+        {
+            ServiceTracker t = createBindTracker( c );
+            t.open();
+            trackers.add( t );
+        }
+    }
+
+
+    @Override
+    protected void tearDown()
+    {
+        for ( ServiceTracker t : trackers )
+        {
+            t.close();
+        }
+        trackers.clear();
+    }
+
+
+    private ServiceTracker createBindTracker( final Class<?> c )
+    {
+        return new ServiceTracker( ctx, c.getName(), new ServiceTrackerCustomizer()
+        {
+            public Object addingService( ServiceReference reference )
+            {
+                Object o = ctx.getService( reference );
+                Method m = getBindMethod( c );
+                if ( m != null )
+                    invoke( m, o );
+                return o;
+            }
+
+
+            public void modifiedService( ServiceReference reference, Object service )
+            {
+            }
+
+
+            public void removedService( ServiceReference reference, Object service )
+            {
+                Method m = getUnbindMethod( c );
+                if ( m != null )
+                    invoke( m, service );
+                ctx.ungetService( reference );
+            }
+        } );
+    }
+
+
+    private void invoke( Method m, Object o )
+    {
+        try
+        {
+            m.invoke( this, new Object[]
+                { o } );
+        }
+        catch ( Exception e )
+        {
+            throw new IllegalStateException( "Failed to invoke binding method " + m, e );
+        }
+    }
+
+
+    protected abstract Class<?>[] getReferences();
+
+
+    protected abstract Method getBindMethod( Class<?> clazz );
+
+
+    protected abstract Method getUnbindMethod( Class<?> clazz );
 }
diff --git a/sigil/common/junit/src/org/apache/felix/sigil/junit/ReflectiveSigilTestCase.java b/sigil/common/junit/src/org/apache/felix/sigil/junit/ReflectiveSigilTestCase.java
index 424ea60..ce26599 100644
--- a/sigil/common/junit/src/org/apache/felix/sigil/junit/ReflectiveSigilTestCase.java
+++ b/sigil/common/junit/src/org/apache/felix/sigil/junit/ReflectiveSigilTestCase.java
@@ -19,80 +19,107 @@
 
 package org.apache.felix.sigil.junit;
 
+
 import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 
-public abstract class ReflectiveSigilTestCase extends AbstractSigilTestCase {
 
-	private Class<?>[] references;
-	private Map<Class<?>, Method> bindMethods;
-	private Map<Class<?>, Method> unbindMethods;
-	
-	@Override
-	protected Class<?>[] getReferences() {
-		introspect();
-		return references;
-	}
+public abstract class ReflectiveSigilTestCase extends AbstractSigilTestCase
+{
 
-	@Override
-	protected Method getBindMethod(Class<?> clazz) {
-		return bindMethods.get(clazz);
-	}
+    private Class<?>[] references;
+    private Map<Class<?>, Method> bindMethods;
+    private Map<Class<?>, Method> unbindMethods;
 
-	@Override
-	protected Method getUnbindMethod(Class<?> clazz) {
-		return unbindMethods.get(clazz);
-	}
 
-	private void introspect() {
-		if ( references == null ) {
-			bindMethods = findBindMethods(getClass(), "set", "add");
-			unbindMethods = findBindMethods(getClass(), "set", "remove");
-			
-			HashSet<Class<?>> refs = new HashSet<Class<?>>();
-			refs.addAll( bindMethods.keySet() );
-			refs.addAll( unbindMethods.keySet() );
-			references = refs.toArray( new Class<?>[refs.size()] );
-		}
-	}
+    @Override
+    protected Class<?>[] getReferences()
+    {
+        introspect();
+        return references;
+    }
 
-	private static Map<Class<?>, Method> findBindMethods(Class<?> clazz, String... prefix) {
-		HashMap<Class<?>, Method> found = new HashMap<Class<?>, Method>();
-		
-		checkDeclaredMethods(clazz, found, prefix);
-		
-		return found;
-	}
-	
-	private static void checkDeclaredMethods(Class<?> clazz, Map<Class<?>, Method> found, String...prefix) {
-		for ( Method m : clazz.getDeclaredMethods() ) {
-			if ( isMethodPrefixed(m, prefix) && isBindSignature(m) ) {
-				found.put( m.getParameterTypes()[0], m );
-			}
-		}
-		
-		Class<?> sup = clazz.getSuperclass();
-		if ( sup != null && sup != Object.class ) {
-			checkDeclaredMethods(sup, found, prefix);
-		}
-		
-		for ( Class<?> i : clazz.getInterfaces() ) {
-			checkDeclaredMethods(i, found, prefix);
-		}
-	}
 
-	private static boolean isMethodPrefixed(Method m, String...prefix) {
-		String n = m.getName();
-		for ( String p : prefix ) {
-			if ( n.startsWith( p ) && n.length() > p.length() ) {
-				return true;
-			}
-		}
-		return false;
-	}
-	private static boolean isBindSignature(Method m) {
-		return m.getReturnType() == Void.TYPE && m.getParameterTypes().length == 1;
-	}
+    @Override
+    protected Method getBindMethod( Class<?> clazz )
+    {
+        return bindMethods.get( clazz );
+    }
+
+
+    @Override
+    protected Method getUnbindMethod( Class<?> clazz )
+    {
+        return unbindMethods.get( clazz );
+    }
+
+
+    private void introspect()
+    {
+        if ( references == null )
+        {
+            bindMethods = findBindMethods( getClass(), "set", "add" );
+            unbindMethods = findBindMethods( getClass(), "set", "remove" );
+
+            HashSet<Class<?>> refs = new HashSet<Class<?>>();
+            refs.addAll( bindMethods.keySet() );
+            refs.addAll( unbindMethods.keySet() );
+            references = refs.toArray( new Class<?>[refs.size()] );
+        }
+    }
+
+
+    private static Map<Class<?>, Method> findBindMethods( Class<?> clazz, String... prefix )
+    {
+        HashMap<Class<?>, Method> found = new HashMap<Class<?>, Method>();
+
+        checkDeclaredMethods( clazz, found, prefix );
+
+        return found;
+    }
+
+
+    private static void checkDeclaredMethods( Class<?> clazz, Map<Class<?>, Method> found, String... prefix )
+    {
+        for ( Method m : clazz.getDeclaredMethods() )
+        {
+            if ( isMethodPrefixed( m, prefix ) && isBindSignature( m ) )
+            {
+                found.put( m.getParameterTypes()[0], m );
+            }
+        }
+
+        Class<?> sup = clazz.getSuperclass();
+        if ( sup != null && sup != Object.class )
+        {
+            checkDeclaredMethods( sup, found, prefix );
+        }
+
+        for ( Class<?> i : clazz.getInterfaces() )
+        {
+            checkDeclaredMethods( i, found, prefix );
+        }
+    }
+
+
+    private static boolean isMethodPrefixed( Method m, String... prefix )
+    {
+        String n = m.getName();
+        for ( String p : prefix )
+        {
+            if ( n.startsWith( p ) && n.length() > p.length() )
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    private static boolean isBindSignature( Method m )
+    {
+        return m.getReturnType() == Void.TYPE && m.getParameterTypes().length == 1;
+    }
 }
diff --git a/sigil/common/junit/src/org/apache/felix/sigil/junit/activator/Activator.java b/sigil/common/junit/src/org/apache/felix/sigil/junit/activator/Activator.java
index dbfb2b6..3ec669b 100644
--- a/sigil/common/junit/src/org/apache/felix/sigil/junit/activator/Activator.java
+++ b/sigil/common/junit/src/org/apache/felix/sigil/junit/activator/Activator.java
@@ -19,29 +19,36 @@
 
 package org.apache.felix.sigil.junit.activator;
 
+
 import org.apache.felix.sigil.junit.server.JUnitService;
 import org.apache.felix.sigil.junit.server.impl.JUnitServiceFactory;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 
+
 /**
  * @author dave
  */
-public class Activator implements BundleActivator {
-	private ServiceRegistration reg;
-	private JUnitServiceFactory service;
+public class Activator implements BundleActivator
+{
+    private ServiceRegistration reg;
+    private JUnitServiceFactory service;
 
-	public void start(final BundleContext ctx) {
-		service = new JUnitServiceFactory();
-		service.start(ctx);
-		reg = ctx.registerService(JUnitService.class.getName(), service, null);
+
+    public void start( final BundleContext ctx )
+    {
+        service = new JUnitServiceFactory();
+        service.start( ctx );
+        reg = ctx.registerService( JUnitService.class.getName(), service, null );
     }
 
-    public void stop(BundleContext ctx) {
-    	reg.unregister();
-    	reg = null;
-    	service.stop(ctx);
-    	service = null;
+
+    public void stop( BundleContext ctx )
+    {
+        reg.unregister();
+        reg = null;
+        service.stop( ctx );
+        service = null;
     }
 }
diff --git a/sigil/common/junit/src/org/apache/felix/sigil/junit/server/JUnitService.java b/sigil/common/junit/src/org/apache/felix/sigil/junit/server/JUnitService.java
index dc417f0..86af596 100644
--- a/sigil/common/junit/src/org/apache/felix/sigil/junit/server/JUnitService.java
+++ b/sigil/common/junit/src/org/apache/felix/sigil/junit/server/JUnitService.java
@@ -19,16 +19,21 @@
 
 package org.apache.felix.sigil.junit.server;
 
+
 import java.util.Set;
 
 import org.osgi.framework.BundleContext;
 
 import junit.framework.TestSuite;
 
-public interface JUnitService {
-	Set<String> getTests();
-	
-	TestSuite createTest(String test);
-	
-	TestSuite createTest(String test, BundleContext ctx);
+
+public interface JUnitService
+{
+    Set<String> getTests();
+
+
+    TestSuite createTest( String test );
+
+
+    TestSuite createTest( String test, BundleContext ctx );
 }
\ No newline at end of file
diff --git a/sigil/common/junit/src/org/apache/felix/sigil/junit/server/impl/JUnitServiceFactory.java b/sigil/common/junit/src/org/apache/felix/sigil/junit/server/impl/JUnitServiceFactory.java
index 884aae2..4a5b89d 100644
--- a/sigil/common/junit/src/org/apache/felix/sigil/junit/server/impl/JUnitServiceFactory.java
+++ b/sigil/common/junit/src/org/apache/felix/sigil/junit/server/impl/JUnitServiceFactory.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.junit.server.impl;
 
+
 import java.util.HashMap;
 import java.util.Set;
 import java.util.TreeSet;
@@ -31,49 +32,69 @@
 import org.osgi.framework.ServiceFactory;
 import org.osgi.framework.ServiceRegistration;
 
-public class JUnitServiceFactory implements ServiceFactory {
 
-	private HashMap<String, Class<? extends TestCase>> tests = new HashMap<String, Class<? extends TestCase>>();
-	private TestClassListener listener;
-	
-	public void start(BundleContext ctx) {
-		listener = new TestClassListener(this);
-		ctx.addBundleListener(listener);
-		//listener.index(ctx.getBundle());
-		for ( Bundle b : ctx.getBundles() ) {
-			if ( b.getState() == Bundle.RESOLVED ) {
-				listener.index(b);
-			}
-		}
-	}
-	
-	public void stop(BundleContext ctx) {
-		ctx.removeBundleListener(listener);
-		listener = null;
-	}
-	
-	public Object getService(Bundle bundle, ServiceRegistration reg) {
-		return new JUnitServiceImpl(this, bundle.getBundleContext());
-	}
+public class JUnitServiceFactory implements ServiceFactory
+{
 
-	public void ungetService(Bundle bundle, ServiceRegistration reg, Object service) {
-	}
+    private HashMap<String, Class<? extends TestCase>> tests = new HashMap<String, Class<? extends TestCase>>();
+    private TestClassListener listener;
 
-	public void registerTest(Class<? extends TestCase> clazz) {
-		tests.put( clazz.getName(), clazz );
-	}
 
-	public void unregister(Class<? extends TestCase> clazz) {
-		tests.remove(clazz.getName());
-	}
+    public void start( BundleContext ctx )
+    {
+        listener = new TestClassListener( this );
+        ctx.addBundleListener( listener );
+        //listener.index(ctx.getBundle());
+        for ( Bundle b : ctx.getBundles() )
+        {
+            if ( b.getState() == Bundle.RESOLVED )
+            {
+                listener.index( b );
+            }
+        }
+    }
 
-	public Set<String> getTests() {
-		return new TreeSet<String>(tests.keySet());
-	}
 
-	public TestSuite getTest(String test) {
-		Class<? extends TestCase> tc = tests.get(test);
-		return tc == null ? null : new TestSuite(tc);
-	}
+    public void stop( BundleContext ctx )
+    {
+        ctx.removeBundleListener( listener );
+        listener = null;
+    }
+
+
+    public Object getService( Bundle bundle, ServiceRegistration reg )
+    {
+        return new JUnitServiceImpl( this, bundle.getBundleContext() );
+    }
+
+
+    public void ungetService( Bundle bundle, ServiceRegistration reg, Object service )
+    {
+    }
+
+
+    public void registerTest( Class<? extends TestCase> clazz )
+    {
+        tests.put( clazz.getName(), clazz );
+    }
+
+
+    public void unregister( Class<? extends TestCase> clazz )
+    {
+        tests.remove( clazz.getName() );
+    }
+
+
+    public Set<String> getTests()
+    {
+        return new TreeSet<String>( tests.keySet() );
+    }
+
+
+    public TestSuite getTest( String test )
+    {
+        Class<? extends TestCase> tc = tests.get( test );
+        return tc == null ? null : new TestSuite( tc );
+    }
 
 }
diff --git a/sigil/common/junit/src/org/apache/felix/sigil/junit/server/impl/JUnitServiceImpl.java b/sigil/common/junit/src/org/apache/felix/sigil/junit/server/impl/JUnitServiceImpl.java
index 153eb4c..ea76683 100644
--- a/sigil/common/junit/src/org/apache/felix/sigil/junit/server/impl/JUnitServiceImpl.java
+++ b/sigil/common/junit/src/org/apache/felix/sigil/junit/server/impl/JUnitServiceImpl.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.junit.server.impl;
 
+
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Arrays;
@@ -34,119 +35,162 @@
 import org.apache.felix.sigil.junit.server.JUnitService;
 import org.osgi.framework.BundleContext;
 
-public class JUnitServiceImpl implements JUnitService {
-	
-	private static final Logger log = Logger.getLogger(JUnitServiceImpl.class.getName());
 
-	private static final Class<?>[] BUNDLE_CONTEXT_PARAMS = new Class[] { BundleContext.class };
+public class JUnitServiceImpl implements JUnitService
+{
 
-	private final JUnitServiceFactory junitServiceFactory;
-	private final BundleContext bundleContext;
+    private static final Logger log = Logger.getLogger( JUnitServiceImpl.class.getName() );
 
-	public JUnitServiceImpl(JUnitServiceFactory junitServiceFactory, BundleContext bundleContext) {
-		this.junitServiceFactory = junitServiceFactory;
-		this.bundleContext = bundleContext;
-	}
+    private static final Class<?>[] BUNDLE_CONTEXT_PARAMS = new Class[]
+        { BundleContext.class };
 
-	public Set<String> getTests() {
-		return junitServiceFactory.getTests();
-	}
-	
-	public TestSuite createTest(String test) {
-		return createTest(test, null);
-	}
-	
-	public TestSuite createTest(String test, BundleContext ctx) {
-		try {
-			TestSuite ts = junitServiceFactory.getTest(test);
-			
-			if ( ts == null ) return null;
-			
-			TestSuite ret = new TestSuite(ts.getName());
-			
-			Enumeration<Test> e = ts.tests();
-			
-			while ( e.hasMoreElements() ) {
-				Test t = e.nextElement();
-				setContext(t, ctx);
-				ret.addTest(t);
-			}
-			
-			return ret;
-		}
-		catch (final NoClassDefFoundError e) {
-			TestSuite s = new TestSuite(test);
-			s.addTest( new Test() {
-				public int countTestCases() {
-					return 1;
-				}
+    private final JUnitServiceFactory junitServiceFactory;
+    private final BundleContext bundleContext;
 
-				public void run(TestResult result) {
-					result.addError(this, e);
-				}
-			});
-			return s;
-		}
-		catch (final RuntimeException e) {
-			TestSuite s = new TestSuite(test);
-			s.addTest( new Test() {
-				public int countTestCases() {
-					return 1;
-				}
 
-				public void run(TestResult result) {
-					result.addError(this, e);
-				}
-				
-			});
-			return s;
-		}
-	}
+    public JUnitServiceImpl( JUnitServiceFactory junitServiceFactory, BundleContext bundleContext )
+    {
+        this.junitServiceFactory = junitServiceFactory;
+        this.bundleContext = bundleContext;
+    }
 
-	private void setContext(Test t, BundleContext ctx) {
-		try {
-			Method m = findMethod( t.getClass(), "setBundleContext", BUNDLE_CONTEXT_PARAMS );
-			if ( m != null )
-				m.invoke(t, ctx == null ? bundleContext : ctx );
-		} catch (SecurityException e) {
-			log.log( Level.WARNING, "Failed to set bundle context on " + t, e);
-		} catch (IllegalArgumentException e) {
-			log.log( Level.WARNING, "Failed to set bundle context on " + t, e);
-		} catch (IllegalAccessException e) {
-			log.log( Level.WARNING, "Failed to set bundle context on " + t, e);
-		} catch (InvocationTargetException e) {
-			log.log( Level.WARNING, "Failed to set bundle context on " + t, e);
-		}
-	}
 
-	private Method findMethod(Class<?> clazz, String name,
-			Class<?>[] params) {
-		Method found = null;
-		
-		for ( Method m : clazz.getDeclaredMethods() ) {
-			if ( m.getName().equals(name) && Arrays.deepEquals(m.getParameterTypes(), params) ) {
-				found = m;
-				break;
-			}
-		}
-		
-		if ( found == null ) {
-			Class<?> c = clazz.getSuperclass();
-			
-			if ( c != null && c != Object.class ) {
-				found = findMethod(c, name, params);
-			}
-		}
-		
-		if ( found == null ) {
-			for ( Class<?> c : clazz.getInterfaces() ) {
-				found = findMethod(c, name, params);
-				if ( found != null ) {
-					break;
-				}
-			}
-		}
-		
-		return found;
-	}
+    public Set<String> getTests()
+    {
+        return junitServiceFactory.getTests();
+    }
+
+
+    public TestSuite createTest( String test )
+    {
+        return createTest( test, null );
+    }
+
+
+    public TestSuite createTest( String test, BundleContext ctx )
+    {
+        try
+        {
+            TestSuite ts = junitServiceFactory.getTest( test );
+
+            if ( ts == null )
+                return null;
+
+            TestSuite ret = new TestSuite( ts.getName() );
+
+            Enumeration<Test> e = ts.tests();
+
+            while ( e.hasMoreElements() )
+            {
+                Test t = e.nextElement();
+                setContext( t, ctx );
+                ret.addTest( t );
+            }
+
+            return ret;
+        }
+        catch ( final NoClassDefFoundError e )
+        {
+            TestSuite s = new TestSuite( test );
+            s.addTest( new Test()
+            {
+                public int countTestCases()
+                {
+                    return 1;
+                }
+
+
+                public void run( TestResult result )
+                {
+                    result.addError( this, e );
+                }
+            } );
+            return s;
+        }
+        catch ( final RuntimeException e )
+        {
+            TestSuite s = new TestSuite( test );
+            s.addTest( new Test()
+            {
+                public int countTestCases()
+                {
+                    return 1;
+                }
+
+
+                public void run( TestResult result )
+                {
+                    result.addError( this, e );
+                }
+
+            } );
+            return s;
+        }
+    }
+
+
+    private void setContext( Test t, BundleContext ctx )
+    {
+        try
+        {
+            Method m = findMethod( t.getClass(), "setBundleContext", BUNDLE_CONTEXT_PARAMS );
+            if ( m != null )
+                m.invoke( t, ctx == null ? bundleContext : ctx );
+        }
+        catch ( SecurityException e )
+        {
+            log.log( Level.WARNING, "Failed to set bundle context on " + t, e );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            log.log( Level.WARNING, "Failed to set bundle context on " + t, e );
+        }
+        catch ( IllegalAccessException e )
+        {
+            log.log( Level.WARNING, "Failed to set bundle context on " + t, e );
+        }
+        catch ( InvocationTargetException e )
+        {
+            log.log( Level.WARNING, "Failed to set bundle context on " + t, e );
+        }
+    }
+
+
+    private Method findMethod( Class<?> clazz, String name, Class<?>[] params )
+    {
+        Method found = null;
+
+        for ( Method m : clazz.getDeclaredMethods() )
+        {
+            if ( m.getName().equals( name ) && Arrays.deepEquals( m.getParameterTypes(), params ) )
+            {
+                found = m;
+                break;
+            }
+        }
+
+        if ( found == null )
+        {
+            Class<?> c = clazz.getSuperclass();
+
+            if ( c != null && c != Object.class )
+            {
+                found = findMethod( c, name, params );
+            }
+        }
+
+        if ( found == null )
+        {
+            for ( Class<?> c : clazz.getInterfaces() )
+            {
+                found = findMethod( c, name, params );
+                if ( found != null )
+                {
+                    break;
+                }
+            }
+        }
+
+        return found;
+    }
 }
diff --git a/sigil/common/junit/src/org/apache/felix/sigil/junit/server/impl/TestClassListener.java b/sigil/common/junit/src/org/apache/felix/sigil/junit/server/impl/TestClassListener.java
index b7e74f8..b77ad3c 100644
--- a/sigil/common/junit/src/org/apache/felix/sigil/junit/server/impl/TestClassListener.java
+++ b/sigil/common/junit/src/org/apache/felix/sigil/junit/server/impl/TestClassListener.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.junit.server.impl;
 
+
 import java.lang.reflect.Modifier;
 import java.net.URL;
 import java.util.Enumeration;
@@ -34,101 +35,136 @@
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.SynchronousBundleListener;
 
-public class TestClassListener implements SynchronousBundleListener {
-	private static final Logger log = Logger.getLogger(TestClassListener.class.getName());
-	
-	private final JUnitServiceFactory service;
-	
-	private HashMap<Long, Class<TestCase>[]> registrations = new HashMap<Long, Class<TestCase>[]>(); 
-	
-	public TestClassListener(JUnitServiceFactory service) {
-		this.service = service;
-	}
-	
-	public void bundleChanged(BundleEvent event) {
-		switch( event.getType() ) {
-		case BundleEvent.RESOLVED:
-			index( event.getBundle() );
-			break;
-		case BundleEvent.UNRESOLVED:
-			unindex( event.getBundle() );
-			break;
-		}
-	}
 
-	void index(Bundle bundle) {
-		if ( isTestBundle( bundle ) ) {
-			List<String> tests = findTests( bundle );
-			
-			if ( !tests.isEmpty() ) {
-				LinkedList<Class<? extends TestCase>> regs = new LinkedList<Class<? extends TestCase>>();
-				
-				for ( String jc : tests ) {
-					try {
-						Class<?> clazz = bundle.loadClass(jc);
-						if ( isTestCase(clazz) ) {
-							Class<? extends TestCase> tc = clazz.asSubclass(TestCase.class);
-							regs.add( tc );
-							service.registerTest(tc);
-						}
-					} catch (ClassNotFoundException e) {
-						log.log( Level.WARNING, "Failed to load class " + jc, e );
-					} catch (NoClassDefFoundError e) {
-						log.log( Level.WARNING, "Failed to load class " + jc, e );
-					}
-				}
-				
-				registrations.put( bundle.getBundleId(), toArray(regs) );
-			}
-		}
-	}
+public class TestClassListener implements SynchronousBundleListener
+{
+    private static final Logger log = Logger.getLogger( TestClassListener.class.getName() );
 
-	private boolean isTestBundle(Bundle bundle) {
-		try {
-			bundle.loadClass(TestCase.class.getName());
-			return true;
-		} catch (ClassNotFoundException e) {
-			return false;
-		}
-	}
+    private final JUnitServiceFactory service;
 
-	@SuppressWarnings("unchecked")
-	private Class<TestCase>[] toArray(LinkedList<Class<? extends TestCase>> regs) {
-		return regs.toArray( new Class[regs.size()] );
-	}
+    private HashMap<Long, Class<TestCase>[]> registrations = new HashMap<Long, Class<TestCase>[]>();
 
-	private boolean isTestCase(Class<?> clazz) {
-		return 
-			TestCase.class.isAssignableFrom(clazz) && 
-			!Modifier.isAbstract(clazz.getModifiers()) && 
-			!clazz.getPackage().getName().startsWith( "junit" );
-	}
 
-	void unindex(Bundle bundle) {
-		Class<TestCase>[] classes = registrations.remove(bundle.getBundleId());
-		if ( classes != null ) {
-			for ( Class<TestCase> tc : classes ) {
-				service.unregister(tc);
-			}
-		}
-	}
-	
-	private List<String> findTests(Bundle bundle) {
-		@SuppressWarnings("unchecked") Enumeration<URL> urls = bundle.findEntries("", "*.class", true);
-		
-		LinkedList<String> tests = new LinkedList<String>();
-		while( urls.hasMoreElements() ) { 
-			URL url = urls.nextElement();
-			tests.add( toClassName( url ) );
-		}
-		
-		return tests;
-	}
+    public TestClassListener( JUnitServiceFactory service )
+    {
+        this.service = service;
+    }
 
-	private String toClassName(URL url) {
-		String f = url.getFile();
-		String cn = f.substring(1, f.length() - 6 );
-		return cn.replace('/', '.');
-	}
+
+    public void bundleChanged( BundleEvent event )
+    {
+        switch ( event.getType() )
+        {
+            case BundleEvent.RESOLVED:
+                index( event.getBundle() );
+                break;
+            case BundleEvent.UNRESOLVED:
+                unindex( event.getBundle() );
+                break;
+        }
+    }
+
+
+    void index( Bundle bundle )
+    {
+        if ( isTestBundle( bundle ) )
+        {
+            List<String> tests = findTests( bundle );
+
+            if ( !tests.isEmpty() )
+            {
+                LinkedList<Class<? extends TestCase>> regs = new LinkedList<Class<? extends TestCase>>();
+
+                for ( String jc : tests )
+                {
+                    try
+                    {
+                        Class<?> clazz = bundle.loadClass( jc );
+                        if ( isTestCase( clazz ) )
+                        {
+                            Class<? extends TestCase> tc = clazz.asSubclass( TestCase.class );
+                            regs.add( tc );
+                            service.registerTest( tc );
+                        }
+                    }
+                    catch ( ClassNotFoundException e )
+                    {
+                        log.log( Level.WARNING, "Failed to load class " + jc, e );
+                    }
+                    catch ( NoClassDefFoundError e )
+                    {
+                        log.log( Level.WARNING, "Failed to load class " + jc, e );
+                    }
+                }
+
+                registrations.put( bundle.getBundleId(), toArray( regs ) );
+            }
+        }
+    }
+
+
+    private boolean isTestBundle( Bundle bundle )
+    {
+        try
+        {
+            bundle.loadClass( TestCase.class.getName() );
+            return true;
+        }
+        catch ( ClassNotFoundException e )
+        {
+            return false;
+        }
+    }
+
+
+    @SuppressWarnings("unchecked")
+    private Class<TestCase>[] toArray( LinkedList<Class<? extends TestCase>> regs )
+    {
+        return regs.toArray( new Class[regs.size()] );
+    }
+
+
+    private boolean isTestCase( Class<?> clazz )
+    {
+        return TestCase.class.isAssignableFrom( clazz ) && !Modifier.isAbstract( clazz.getModifiers() )
+            && !clazz.getPackage().getName().startsWith( "junit" );
+    }
+
+
+    void unindex( Bundle bundle )
+    {
+        Class<TestCase>[] classes = registrations.remove( bundle.getBundleId() );
+        if ( classes != null )
+        {
+            for ( Class<TestCase> tc : classes )
+            {
+                service.unregister( tc );
+            }
+        }
+    }
+
+
+    private List<String> findTests( Bundle bundle )
+    {
+        @SuppressWarnings("unchecked")
+        Enumeration<URL> urls = bundle.findEntries( "", "*.class", true );
+
+        LinkedList<String> tests = new LinkedList<String>();
+        while ( urls.hasMoreElements() )
+        {
+            URL url = urls.nextElement();
+            tests.add( toClassName( url ) );
+        }
+
+        return tests;
+    }
+
+
+    private String toClassName( URL url )
+    {
+        String f = url.getFile();
+        String cn = f.substring( 1, f.length() - 6 );
+        return cn.replace( '/', '.' );
+    }
 
 }
diff --git a/sigil/common/obr/src/org/apache/felix/sigil/obr/AbstractOBRBundleRepository.java b/sigil/common/obr/src/org/apache/felix/sigil/obr/AbstractOBRBundleRepository.java
index 06654ae..3e2b54d 100644
--- a/sigil/common/obr/src/org/apache/felix/sigil/obr/AbstractOBRBundleRepository.java
+++ b/sigil/common/obr/src/org/apache/felix/sigil/obr/AbstractOBRBundleRepository.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.obr;
 
+
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -32,113 +33,153 @@
 
 import org.apache.felix.sigil.repository.AbstractBundleRepository;
 
-public abstract class AbstractOBRBundleRepository extends AbstractBundleRepository {
-	private static SAXParserFactory factory = SAXParserFactory.newInstance();
-	
-	private URL obrURL;
-	private File obrlCache;
-	private File bundleCache;
-	private long updatePeriod;
-	
-	public AbstractOBRBundleRepository(String id, URL repositoryURL, File obrCache, File bundleCache, long updatePeriod) {
-		super(id);
-		this.obrURL = repositoryURL;
-		this.obrlCache = obrCache;
-		this.bundleCache = bundleCache;
-		this.updatePeriod = updatePeriod;
-	}
-	
-	public void refresh() {
-		obrlCache.delete();
-	}
-	
-	protected void readBundles(OBRListener listener) throws Exception {
-		syncOBRIndex();		
-		OBRHandler handler = new OBRHandler(getObrURL(), getBundleCache(), listener);
-		SAXParser parser = factory.newSAXParser();
-		parser.parse(getObrlCache(), handler );
-	}
-	
-	private void syncOBRIndex() {
-		if ( isUpdated() ) {
-			InputStream in = null;
-			OutputStream out = null;
-			
-			try {
-				URLConnection c = getObrURL().openConnection();
-				c.connect();
-				in = c.getInputStream();
-				File file = getObrlCache();
-				if ( !file.getParentFile().mkdirs() ) {
-					throw new IOException( "Failed to create obr cache" );
-				}
-				out = new FileOutputStream(file);
-				stream(in, out);
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-				getObrlCache().setLastModified(0);
-			}
-			finally {
-				close(in, out);
-			}
-		}		
-	}
 
-	private void close(InputStream in, OutputStream out) {
-		if ( in != null ) {
-			try {
-				in.close();
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-		}
-		if ( out != null ) {
-			try {
-				out.close();
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-		}
-	}
+public abstract class AbstractOBRBundleRepository extends AbstractBundleRepository
+{
+    private static SAXParserFactory factory = SAXParserFactory.newInstance();
 
-	private void stream(InputStream in, OutputStream out) throws IOException {
-		byte[] buf = new byte[1024];
-		for(;;) {
-			int r = in.read(buf);
-			if ( r == -1 ) {
-				break;
-			}
-			out.write(buf, 0, r);
-		}
-		out.flush();
-	}
+    private URL obrURL;
+    private File obrlCache;
+    private File bundleCache;
+    private long updatePeriod;
 
-	private boolean isUpdated() {
-		if ( !getObrlCache().exists() ) {
-			return true;
-		}
-		
-		return getObrlCache().lastModified() + getUpdatePeriod() < System.currentTimeMillis();
-	}
 
-	public URL getObrURL() {
-		return obrURL;
-	}
+    public AbstractOBRBundleRepository( String id, URL repositoryURL, File obrCache, File bundleCache, long updatePeriod )
+    {
+        super( id );
+        this.obrURL = repositoryURL;
+        this.obrlCache = obrCache;
+        this.bundleCache = bundleCache;
+        this.updatePeriod = updatePeriod;
+    }
 
-	public File getObrlCache() {
-		return obrlCache;
-	}
 
-	public File getBundleCache() {
-		return bundleCache;
-	}
+    public void refresh()
+    {
+        obrlCache.delete();
+    }
 
-	public long getUpdatePeriod() {
-		return updatePeriod;
-	}
 
+    protected void readBundles( OBRListener listener ) throws Exception
+    {
+        syncOBRIndex();
+        OBRHandler handler = new OBRHandler( getObrURL(), getBundleCache(), listener );
+        SAXParser parser = factory.newSAXParser();
+        parser.parse( getObrlCache(), handler );
+    }
+
+
+    private void syncOBRIndex()
+    {
+        if ( isUpdated() )
+        {
+            InputStream in = null;
+            OutputStream out = null;
+
+            try
+            {
+                URLConnection c = getObrURL().openConnection();
+                c.connect();
+                in = c.getInputStream();
+                File file = getObrlCache();
+                if ( !file.getParentFile().mkdirs() )
+                {
+                    throw new IOException( "Failed to create obr cache" );
+                }
+                out = new FileOutputStream( file );
+                stream( in, out );
+            }
+            catch ( IOException e )
+            {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+                getObrlCache().setLastModified( 0 );
+            }
+            finally
+            {
+                close( in, out );
+            }
+        }
+    }
+
+
+    private void close( InputStream in, OutputStream out )
+    {
+        if ( in != null )
+        {
+            try
+            {
+                in.close();
+            }
+            catch ( IOException e )
+            {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+        if ( out != null )
+        {
+            try
+            {
+                out.close();
+            }
+            catch ( IOException e )
+            {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+    }
+
+
+    private void stream( InputStream in, OutputStream out ) throws IOException
+    {
+        byte[] buf = new byte[1024];
+        for ( ;; )
+        {
+            int r = in.read( buf );
+            if ( r == -1 )
+            {
+                break;
+            }
+            out.write( buf, 0, r );
+        }
+        out.flush();
+    }
+
+
+    private boolean isUpdated()
+    {
+        if ( !getObrlCache().exists() )
+        {
+            return true;
+        }
+
+        return getObrlCache().lastModified() + getUpdatePeriod() < System.currentTimeMillis();
+    }
+
+
+    public URL getObrURL()
+    {
+        return obrURL;
+    }
+
+
+    public File getObrlCache()
+    {
+        return obrlCache;
+    }
+
+
+    public File getBundleCache()
+    {
+        return bundleCache;
+    }
+
+
+    public long getUpdatePeriod()
+    {
+        return updatePeriod;
+    }
 
 }
diff --git a/sigil/common/obr/src/org/apache/felix/sigil/obr/CachingOBRBundleRepository.java b/sigil/common/obr/src/org/apache/felix/sigil/obr/CachingOBRBundleRepository.java
index c18cce6..cbd800d 100644
--- a/sigil/common/obr/src/org/apache/felix/sigil/obr/CachingOBRBundleRepository.java
+++ b/sigil/common/obr/src/org/apache/felix/sigil/obr/CachingOBRBundleRepository.java
@@ -19,59 +19,78 @@
 
 package org.apache.felix.sigil.obr;
 
+
 import java.io.File;
 import java.lang.ref.SoftReference;
 import java.net.URL;
 import java.util.LinkedList;
 import java.util.List;
 
-
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
 import org.apache.felix.sigil.repository.IRepositoryVisitor;
 
-public class CachingOBRBundleRepository extends AbstractOBRBundleRepository {
 
-	private SoftReference<List<ISigilBundle>> bundles;
-	
-	public CachingOBRBundleRepository(String id, URL repositoryURL, File obrCache, File bundleCache, long updatePeriod) {
-		super(id, repositoryURL, obrCache, bundleCache, updatePeriod);
-	}
-	
-	@Override
-	public void accept(IRepositoryVisitor visitor, int options) {
-		for ( ISigilBundle b : loadFromCache(options) ) {
-			if ( !visitor.visit(b) ) {
-				break;
-			}
-		}
-	}
-	
-	public synchronized void refresh() {
-		super.refresh();
-		if ( bundles != null ) {
-			bundles.clear();
-			notifyChange();
-		}
-	}
+public class CachingOBRBundleRepository extends AbstractOBRBundleRepository
+{
 
-	private synchronized List<ISigilBundle> loadFromCache(int options) {
-		List<ISigilBundle> cached = bundles == null ? null : bundles.get();
-		if ( cached == null ) {
-			try {
-				final LinkedList<ISigilBundle> read = new LinkedList<ISigilBundle>();
-				readBundles(new OBRListener() {
-					public void handleBundle(ISigilBundle bundle) {
-						read.add(bundle);
-					}
-				});
-				cached = read;
-				bundles = new SoftReference<List<ISigilBundle>>(cached);
-			} catch (Exception e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} 
-		}
-		
-		return cached;
-	}
+    private SoftReference<List<ISigilBundle>> bundles;
+
+
+    public CachingOBRBundleRepository( String id, URL repositoryURL, File obrCache, File bundleCache, long updatePeriod )
+    {
+        super( id, repositoryURL, obrCache, bundleCache, updatePeriod );
+    }
+
+
+    @Override
+    public void accept( IRepositoryVisitor visitor, int options )
+    {
+        for ( ISigilBundle b : loadFromCache( options ) )
+        {
+            if ( !visitor.visit( b ) )
+            {
+                break;
+            }
+        }
+    }
+
+
+    public synchronized void refresh()
+    {
+        super.refresh();
+        if ( bundles != null )
+        {
+            bundles.clear();
+            notifyChange();
+        }
+    }
+
+
+    private synchronized List<ISigilBundle> loadFromCache( int options )
+    {
+        List<ISigilBundle> cached = bundles == null ? null : bundles.get();
+        if ( cached == null )
+        {
+            try
+            {
+                final LinkedList<ISigilBundle> read = new LinkedList<ISigilBundle>();
+                readBundles( new OBRListener()
+                {
+                    public void handleBundle( ISigilBundle bundle )
+                    {
+                        read.add( bundle );
+                    }
+                } );
+                cached = read;
+                bundles = new SoftReference<List<ISigilBundle>>( cached );
+            }
+            catch ( Exception e )
+            {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+
+        return cached;
+    }
 }
diff --git a/sigil/common/obr/src/org/apache/felix/sigil/obr/NonCachingOBRBundleRepository.java b/sigil/common/obr/src/org/apache/felix/sigil/obr/NonCachingOBRBundleRepository.java
index 1deadb3..17b555c 100644
--- a/sigil/common/obr/src/org/apache/felix/sigil/obr/NonCachingOBRBundleRepository.java
+++ b/sigil/common/obr/src/org/apache/felix/sigil/obr/NonCachingOBRBundleRepository.java
@@ -19,49 +19,63 @@
 
 package org.apache.felix.sigil.obr;
 
+
 import java.io.File;
 import java.net.URL;
 
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
 import org.apache.felix.sigil.repository.IRepositoryVisitor;
 
-public class NonCachingOBRBundleRepository extends AbstractOBRBundleRepository {
 
-	/*public static void main(String[] args) throws Exception {
-		String url = args[0];
-		String obr = args[1];
-		String cache = args[2];
-		String update = args[3];
-		BldCore.init();
-		NonCachingOBRBundleRepository rep = new NonCachingOBRBundleRepository( "main", new URL(url), new File(obr), new File(cache), Long.parseLong(update));
-		rep.accept(new IRepositoryVisitor() {
-			public boolean visit(ISigilBundle bundle) {
-				System.out.println( "Found " + bundle );
-				return true;
-			}
-		});
-	} */
-	
-	public NonCachingOBRBundleRepository(String id, URL repositoryURL, File obrCache, File bundleCache, long updatePeriod) {
-		super(id, repositoryURL, obrCache, bundleCache, updatePeriod);
-	}
+public class NonCachingOBRBundleRepository extends AbstractOBRBundleRepository
+{
 
-	@Override
-	public void accept(final IRepositoryVisitor visitor, int options) {
-		try {
-			readBundles(new OBRListener() {
-				boolean visit = true;
-				public void handleBundle(ISigilBundle bundle) {
-					if ( visit ) {
-						visit = visitor.visit(bundle);
-					}
-				}
-			});
-		} catch (Exception e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}
+    /*public static void main(String[] args) throws Exception {
+    	String url = args[0];
+    	String obr = args[1];
+    	String cache = args[2];
+    	String update = args[3];
+    	BldCore.init();
+    	NonCachingOBRBundleRepository rep = new NonCachingOBRBundleRepository( "main", new URL(url), new File(obr), new File(cache), Long.parseLong(update));
+    	rep.accept(new IRepositoryVisitor() {
+    		public boolean visit(ISigilBundle bundle) {
+    			System.out.println( "Found " + bundle );
+    			return true;
+    		}
+    	});
+    } */
 
+    public NonCachingOBRBundleRepository( String id, URL repositoryURL, File obrCache, File bundleCache,
+        long updatePeriod )
+    {
+        super( id, repositoryURL, obrCache, bundleCache, updatePeriod );
+    }
+
+
+    @Override
+    public void accept( final IRepositoryVisitor visitor, int options )
+    {
+        try
+        {
+            readBundles( new OBRListener()
+            {
+                boolean visit = true;
+
+
+                public void handleBundle( ISigilBundle bundle )
+                {
+                    if ( visit )
+                    {
+                        visit = visitor.visit( bundle );
+                    }
+                }
+            } );
+        }
+        catch ( Exception e )
+        {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
 
 }
diff --git a/sigil/common/obr/src/org/apache/felix/sigil/obr/OBRHandler.java b/sigil/common/obr/src/org/apache/felix/sigil/obr/OBRHandler.java
index aa8737c..fe97e8f 100644
--- a/sigil/common/obr/src/org/apache/felix/sigil/obr/OBRHandler.java
+++ b/sigil/common/obr/src/org/apache/felix/sigil/obr/OBRHandler.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.obr;
 
+
 import java.io.File;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -49,241 +50,320 @@
 import org.xml.sax.SAXParseException;
 import org.xml.sax.helpers.DefaultHandler;
 
-final class OBRHandler extends DefaultHandler {
-	private static final String PACKAGE = "package";
-	private static final String URI = "uri";
-	private static final String PRESENTATION_NAME = "presentationname";
-	private static final String VERSION = "version";
-	private static final String SYMBOLIC_NAME = "symbolicname";
-	private final File cacheDir;
-	private final URL obrURL;
-	private final OBRListener listener;
-	
-	private HashSet<String> sanity = new HashSet<String>();
-	private Locator locator;
-	private ISigilBundle bundle;
-	private IPackageExport export;
-	
-	public OBRHandler(URL obrURL, File bundleCache, OBRListener listener) {
-		this.obrURL = obrURL;
-		this.cacheDir = bundleCache;
-		this.listener = listener;
-	}
-	
-    public void setDocumentLocator (Locator locator) {
-    	this.locator = locator;
+
+final class OBRHandler extends DefaultHandler
+{
+    private static final String PACKAGE = "package";
+    private static final String URI = "uri";
+    private static final String PRESENTATION_NAME = "presentationname";
+    private static final String VERSION = "version";
+    private static final String SYMBOLIC_NAME = "symbolicname";
+    private final File cacheDir;
+    private final URL obrURL;
+    private final OBRListener listener;
+
+    private HashSet<String> sanity = new HashSet<String>();
+    private Locator locator;
+    private ISigilBundle bundle;
+    private IPackageExport export;
+
+
+    public OBRHandler( URL obrURL, File bundleCache, OBRListener listener )
+    {
+        this.obrURL = obrURL;
+        this.cacheDir = bundleCache;
+        this.listener = listener;
     }
 
-	public void startElement (String uri, String localName,
-			String qName, Attributes attributes) throws SAXException {
-		if ( "resource".equals( qName ) ) {
-			startResource(attributes);
-		}
-		else if ( "capability".equals( qName ) ) {
-			startCapability(attributes);
-		}
-		else if( "require".equals( qName ) ) {
-			startRequire(attributes);
-		}
-		else if ( "p".equals( qName ) ) {
-			startProperty(attributes);
-		}
-	}
 
-	public void endElement (String uri, String localName, String qName)
-	throws SAXException {
-		if ( "resource".equals( qName ) ) {
-			endResource();
-		}
-		else if ( "capability".equals( qName ) ) {
-			endCapability();
-		}
-		else if( "require".equals( qName ) ) {
-			endRequire();
-		}
-		else if ( "p".equals( qName ) ) {
-			endProperty();
-		}
-	}
+    public void setDocumentLocator( Locator locator )
+    {
+        this.locator = locator;
+    }
 
-	private void startResource(Attributes attributes) throws SAXException {
-		try {
-			String uri = attributes.getValue("", URI);
-			if ( uri.endsWith( ".jar" ) ) {
-				if ( !sanity.add(uri) ) {
-					throw new RuntimeException(uri);
-				}
-				ISigilBundle b = ModelElementFactory.getInstance().newModelElement(ISigilBundle.class);
-				IBundleModelElement info = ModelElementFactory.getInstance().newModelElement(IBundleModelElement.class);
-				info.setSymbolicName(attributes.getValue("", SYMBOLIC_NAME));
-				info.setVersion(new Version(attributes.getValue("", VERSION)));
-				info.setName(attributes.getValue("", PRESENTATION_NAME));
-				URI	l = makeAbsolute(uri);
-				info.setUpdateLocation(l);
-				b.setLocation(cachePath(info));
-				b.setBundleInfo(info);
-				bundle = b;
-			}
-		}
-		catch (Exception e) {
-			throw new SAXParseException("Failed to build bundle info", locator, e);
-		}
-	}
 
-	private URI makeAbsolute(String uri) throws URISyntaxException {
-		URI l = new URI(uri);
-		if ( !l.isAbsolute() ) {
-			String base = obrURL.toExternalForm();
-			int i = base.lastIndexOf("/");
-			if ( i != -1 ) {
-				base = base.substring(0, i);
-				l = new URI( base + (uri.startsWith("/") ? "" : "/") + uri );
-			}
-		}
-		return l;
-	}
+    public void startElement( String uri, String localName, String qName, Attributes attributes ) throws SAXException
+    {
+        if ( "resource".equals( qName ) )
+        {
+            startResource( attributes );
+        }
+        else if ( "capability".equals( qName ) )
+        {
+            startCapability( attributes );
+        }
+        else if ( "require".equals( qName ) )
+        {
+            startRequire( attributes );
+        }
+        else if ( "p".equals( qName ) )
+        {
+            startProperty( attributes );
+        }
+    }
 
-	private IPath cachePath(IBundleModelElement info) {
-		return new Path(cacheDir.getAbsolutePath()).append( info.getSymbolicName() + "_" + info.getVersion() + ".jar" );
-	}
 
-	private void startCapability(Attributes attributes) {
-		if ( bundle != null ) {
-			if ( PACKAGE.equals( attributes.getValue("", "name") ) ) {
-				export = ModelElementFactory.getInstance().newModelElement(IPackageExport.class);
-			}
-		}
-	}
+    public void endElement( String uri, String localName, String qName ) throws SAXException
+    {
+        if ( "resource".equals( qName ) )
+        {
+            endResource();
+        }
+        else if ( "capability".equals( qName ) )
+        {
+            endCapability();
+        }
+        else if ( "require".equals( qName ) )
+        {
+            endRequire();
+        }
+        else if ( "p".equals( qName ) )
+        {
+            endProperty();
+        }
+    }
 
-	private void startRequire(Attributes attributes) throws SAXParseException {
-		if ( bundle != null ) {
-			String name = attributes.getValue("name");
-			if ( PACKAGE.equals( name ) ) {
-				IPackageImport pi = ModelElementFactory.getInstance().newModelElement(IPackageImport.class);
-				try {
-					LDAPExpr expr = LDAPParser.parseExpression(attributes.getValue("filter") );
-					pi.setPackageName(decodePackage(expr, locator));
-					pi.setVersions(decodeVersions(expr, locator));
-					pi.setOptional(Boolean.valueOf(attributes.getValue("optional")));
-					bundle.getBundleInfo().addImport(pi);
-				} catch (LDAPParseException e) {
-					throw new SAXParseException("Failed to parse filter", locator, e);
-				}
-			}
-			else if ( "bundle".equals( name ) ) {
-				IRequiredBundle b = ModelElementFactory.getInstance().newModelElement(IRequiredBundle.class);
-				try {
-					LDAPExpr expr = LDAPParser.parseExpression(attributes.getValue("filter") );
-					b.setSymbolicName(decodeSymbolicName(expr, locator));
-					b.setVersions(decodeVersions(expr, locator));
-					b.setOptional(Boolean.valueOf(attributes.getValue("optional")));
-					bundle.getBundleInfo().addRequiredBundle(b);
-				} catch (Exception e) {
-					System.err.println( "Failed to parse filter in bundle " + bundle.getBundleInfo().getSymbolicName() );
-					throw new SAXParseException("Failed to parse filter in bundle " + bundle.getBundleInfo().getSymbolicName(), locator, e);
-				}
-			}
-			//else if ( "ee".equals( name ) ) {
-				// TODO ignore for now...
-			//}
-			//else if ( "service".equals( name ) ) {
-				// TODO ignore for now...
-			//}
-			//else {
-			//	for ( int i = 0; i < attributes.getLength(); i++ ) {
-			//		System.out.println( "Found requirement " + attributes.getValue(i) );				
-			//	}
-			//}
-		}
-	}
 
-	private static VersionRange decodeVersions(LDAPExpr expr, Locator locator) throws SAXParseException {
-		try {
-			return VersionRangeHelper.decodeVersions(expr);			
-		}
-		catch (NumberFormatException e) {
-			throw new SAXParseException(e.getMessage(), locator);
-		}
-	}
+    private void startResource( Attributes attributes ) throws SAXException
+    {
+        try
+        {
+            String uri = attributes.getValue( "", URI );
+            if ( uri.endsWith( ".jar" ) )
+            {
+                if ( !sanity.add( uri ) )
+                {
+                    throw new RuntimeException( uri );
+                }
+                ISigilBundle b = ModelElementFactory.getInstance().newModelElement( ISigilBundle.class );
+                IBundleModelElement info = ModelElementFactory.getInstance()
+                    .newModelElement( IBundleModelElement.class );
+                info.setSymbolicName( attributes.getValue( "", SYMBOLIC_NAME ) );
+                info.setVersion( new Version( attributes.getValue( "", VERSION ) ) );
+                info.setName( attributes.getValue( "", PRESENTATION_NAME ) );
+                URI l = makeAbsolute( uri );
+                info.setUpdateLocation( l );
+                b.setLocation( cachePath( info ) );
+                b.setBundleInfo( info );
+                bundle = b;
+            }
+        }
+        catch ( Exception e )
+        {
+            throw new SAXParseException( "Failed to build bundle info", locator, e );
+        }
+    }
 
-	private void startProperty(Attributes attributes) {
-		if ( export != null ) {
-			String name = attributes.getValue("", "n");
-			String value = attributes.getValue("", "v");
-			if ( PACKAGE.equals( name ) ) {
-				export.setPackageName(value);
-			}
-			else if ( "uses".equals( name ) ) {
-				String[] split = value.split(",");
-				export.setUses( Arrays.asList(split) );
-			}
-			else if ( "version".equals( name ) ) {
-				export.setVersion( new Version(value) );
-			}
-		}
-	}
 
-	private void endResource() {
-		if ( bundle != null ) {
-			listener.handleBundle(bundle);
-			bundle = null;
-		}
-	}
+    private URI makeAbsolute( String uri ) throws URISyntaxException
+    {
+        URI l = new URI( uri );
+        if ( !l.isAbsolute() )
+        {
+            String base = obrURL.toExternalForm();
+            int i = base.lastIndexOf( "/" );
+            if ( i != -1 )
+            {
+                base = base.substring( 0, i );
+                l = new URI( base + ( uri.startsWith( "/" ) ? "" : "/" ) + uri );
+            }
+        }
+        return l;
+    }
 
-	private void endCapability() {
-		if ( bundle != null ) {
-			if ( export != null ) {
-				bundle.getBundleInfo().addExport(export);
-				export = null;
-			}
-		}
-	}
 
-	private void endRequire() {
-		// TODO Auto-generated method stub
-		
-	}
+    private IPath cachePath( IBundleModelElement info )
+    {
+        return new Path( cacheDir.getAbsolutePath() )
+            .append( info.getSymbolicName() + "_" + info.getVersion() + ".jar" );
+    }
 
-	private void endProperty() {
-		// TODO Auto-generated method stub
-		
-	}
 
-	private static String decodePackage(LDAPExpr expr, Locator locator) throws SAXParseException {
-		ArrayList<SimpleTerm> terms = new ArrayList<SimpleTerm>(1);
-		
-		findTerms("package", expr, terms);
-		
-		if ( terms.isEmpty() ) {
-			throw new SAXParseException("Missing name filter in " + expr, locator);
-		}
-		
-		return terms.get(0).getRval();
-	}
-	
-	private static String decodeSymbolicName(LDAPExpr expr, Locator locator) throws SAXParseException {
-		ArrayList<SimpleTerm> terms = new ArrayList<SimpleTerm>(1);
-		
-		findTerms("symbolicname", expr, terms);
-		
-		if ( terms.isEmpty() ) {
-			throw new SAXParseException("Missing name filter in " + expr, locator);
-		}
-		
-		return terms.get(0).getRval();
-	}
-	
-	private static void findTerms(String string, LDAPExpr expr, List<SimpleTerm> terms) throws SAXParseException {
-		if ( expr instanceof SimpleTerm ) {
-			SimpleTerm term = (SimpleTerm) expr;
-			if ( term.getName().equals(string) ) {
-				terms.add(term);
-			}
-		}
-		else {
-			for ( LDAPExpr c : expr.getChildren() ) {
-				findTerms(string, c, terms);
-			}
-		}
-	}
+    private void startCapability( Attributes attributes )
+    {
+        if ( bundle != null )
+        {
+            if ( PACKAGE.equals( attributes.getValue( "", "name" ) ) )
+            {
+                export = ModelElementFactory.getInstance().newModelElement( IPackageExport.class );
+            }
+        }
+    }
+
+
+    private void startRequire( Attributes attributes ) throws SAXParseException
+    {
+        if ( bundle != null )
+        {
+            String name = attributes.getValue( "name" );
+            if ( PACKAGE.equals( name ) )
+            {
+                IPackageImport pi = ModelElementFactory.getInstance().newModelElement( IPackageImport.class );
+                try
+                {
+                    LDAPExpr expr = LDAPParser.parseExpression( attributes.getValue( "filter" ) );
+                    pi.setPackageName( decodePackage( expr, locator ) );
+                    pi.setVersions( decodeVersions( expr, locator ) );
+                    pi.setOptional( Boolean.valueOf( attributes.getValue( "optional" ) ) );
+                    bundle.getBundleInfo().addImport( pi );
+                }
+                catch ( LDAPParseException e )
+                {
+                    throw new SAXParseException( "Failed to parse filter", locator, e );
+                }
+            }
+            else if ( "bundle".equals( name ) )
+            {
+                IRequiredBundle b = ModelElementFactory.getInstance().newModelElement( IRequiredBundle.class );
+                try
+                {
+                    LDAPExpr expr = LDAPParser.parseExpression( attributes.getValue( "filter" ) );
+                    b.setSymbolicName( decodeSymbolicName( expr, locator ) );
+                    b.setVersions( decodeVersions( expr, locator ) );
+                    b.setOptional( Boolean.valueOf( attributes.getValue( "optional" ) ) );
+                    bundle.getBundleInfo().addRequiredBundle( b );
+                }
+                catch ( Exception e )
+                {
+                    System.err.println( "Failed to parse filter in bundle " + bundle.getBundleInfo().getSymbolicName() );
+                    throw new SAXParseException( "Failed to parse filter in bundle "
+                        + bundle.getBundleInfo().getSymbolicName(), locator, e );
+                }
+            }
+            //else if ( "ee".equals( name ) ) {
+            // TODO ignore for now...
+            //}
+            //else if ( "service".equals( name ) ) {
+            // TODO ignore for now...
+            //}
+            //else {
+            //	for ( int i = 0; i < attributes.getLength(); i++ ) {
+            //		System.out.println( "Found requirement " + attributes.getValue(i) );				
+            //	}
+            //}
+        }
+    }
+
+
+    private static VersionRange decodeVersions( LDAPExpr expr, Locator locator ) throws SAXParseException
+    {
+        try
+        {
+            return VersionRangeHelper.decodeVersions( expr );
+        }
+        catch ( NumberFormatException e )
+        {
+            throw new SAXParseException( e.getMessage(), locator );
+        }
+    }
+
+
+    private void startProperty( Attributes attributes )
+    {
+        if ( export != null )
+        {
+            String name = attributes.getValue( "", "n" );
+            String value = attributes.getValue( "", "v" );
+            if ( PACKAGE.equals( name ) )
+            {
+                export.setPackageName( value );
+            }
+            else if ( "uses".equals( name ) )
+            {
+                String[] split = value.split( "," );
+                export.setUses( Arrays.asList( split ) );
+            }
+            else if ( "version".equals( name ) )
+            {
+                export.setVersion( new Version( value ) );
+            }
+        }
+    }
+
+
+    private void endResource()
+    {
+        if ( bundle != null )
+        {
+            listener.handleBundle( bundle );
+            bundle = null;
+        }
+    }
+
+
+    private void endCapability()
+    {
+        if ( bundle != null )
+        {
+            if ( export != null )
+            {
+                bundle.getBundleInfo().addExport( export );
+                export = null;
+            }
+        }
+    }
+
+
+    private void endRequire()
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    private void endProperty()
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    private static String decodePackage( LDAPExpr expr, Locator locator ) throws SAXParseException
+    {
+        ArrayList<SimpleTerm> terms = new ArrayList<SimpleTerm>( 1 );
+
+        findTerms( "package", expr, terms );
+
+        if ( terms.isEmpty() )
+        {
+            throw new SAXParseException( "Missing name filter in " + expr, locator );
+        }
+
+        return terms.get( 0 ).getRval();
+    }
+
+
+    private static String decodeSymbolicName( LDAPExpr expr, Locator locator ) throws SAXParseException
+    {
+        ArrayList<SimpleTerm> terms = new ArrayList<SimpleTerm>( 1 );
+
+        findTerms( "symbolicname", expr, terms );
+
+        if ( terms.isEmpty() )
+        {
+            throw new SAXParseException( "Missing name filter in " + expr, locator );
+        }
+
+        return terms.get( 0 ).getRval();
+    }
+
+
+    private static void findTerms( String string, LDAPExpr expr, List<SimpleTerm> terms ) throws SAXParseException
+    {
+        if ( expr instanceof SimpleTerm )
+        {
+            SimpleTerm term = ( SimpleTerm ) expr;
+            if ( term.getName().equals( string ) )
+            {
+                terms.add( term );
+            }
+        }
+        else
+        {
+            for ( LDAPExpr c : expr.getChildren() )
+            {
+                findTerms( string, c, terms );
+            }
+        }
+    }
 }
diff --git a/sigil/common/obr/src/org/apache/felix/sigil/obr/OBRListener.java b/sigil/common/obr/src/org/apache/felix/sigil/obr/OBRListener.java
index 5cef89c..a8a5439 100644
--- a/sigil/common/obr/src/org/apache/felix/sigil/obr/OBRListener.java
+++ b/sigil/common/obr/src/org/apache/felix/sigil/obr/OBRListener.java
@@ -19,8 +19,11 @@
 
 package org.apache.felix.sigil.obr;
 
+
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
 
-public interface OBRListener {
-	void handleBundle(ISigilBundle bundle);
+
+public interface OBRListener
+{
+    void handleBundle( ISigilBundle bundle );
 }
diff --git a/sigil/common/obr/src/org/apache/felix/sigil/obr/OBRRepositoryProvider.java b/sigil/common/obr/src/org/apache/felix/sigil/obr/OBRRepositoryProvider.java
index 07a2442..e96e3c2 100644
--- a/sigil/common/obr/src/org/apache/felix/sigil/obr/OBRRepositoryProvider.java
+++ b/sigil/common/obr/src/org/apache/felix/sigil/obr/OBRRepositoryProvider.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.obr;
 
+
 import java.io.File;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -29,23 +30,30 @@
 import org.apache.felix.sigil.repository.IRepositoryProvider;
 import org.apache.felix.sigil.repository.RepositoryException;
 
-public class OBRRepositoryProvider implements IRepositoryProvider {
-	public IBundleRepository createRepository(String id, Properties preferences) throws RepositoryException {
-		try {
-			URL repositoryURL = new URL( preferences.getProperty("url") );
-			File indexCache = new File( preferences.getProperty("index") );
-			File localCache = new File( preferences.getProperty("cache") );
-			// TODO create user configurable updatePeriod
-			long updatePeriod = TimeUnit.MILLISECONDS.convert(60*60*24*7, TimeUnit.SECONDS);
-			if ( preferences.getProperty("inmemory") == null ) {
-				return new NonCachingOBRBundleRepository(id, repositoryURL, indexCache, localCache, updatePeriod);
-			}
-			else {
-				return new CachingOBRBundleRepository(id, repositoryURL, indexCache, localCache, updatePeriod);
-			}
-		}
-		catch (MalformedURLException e) {
-			throw new RepositoryException("Invalid repository url", e);
-		}
-	}
+
+public class OBRRepositoryProvider implements IRepositoryProvider
+{
+    public IBundleRepository createRepository( String id, Properties preferences ) throws RepositoryException
+    {
+        try
+        {
+            URL repositoryURL = new URL( preferences.getProperty( "url" ) );
+            File indexCache = new File( preferences.getProperty( "index" ) );
+            File localCache = new File( preferences.getProperty( "cache" ) );
+            // TODO create user configurable updatePeriod
+            long updatePeriod = TimeUnit.MILLISECONDS.convert( 60 * 60 * 24 * 7, TimeUnit.SECONDS );
+            if ( preferences.getProperty( "inmemory" ) == null )
+            {
+                return new NonCachingOBRBundleRepository( id, repositoryURL, indexCache, localCache, updatePeriod );
+            }
+            else
+            {
+                return new CachingOBRBundleRepository( id, repositoryURL, indexCache, localCache, updatePeriod );
+            }
+        }
+        catch ( MalformedURLException e )
+        {
+            throw new RepositoryException( "Invalid repository url", e );
+        }
+    }
 }
diff --git a/sigil/common/obr/src/org/apache/felix/sigil/obr/VersionRangeHelper.java b/sigil/common/obr/src/org/apache/felix/sigil/obr/VersionRangeHelper.java
index c00d744..051baf3 100644
--- a/sigil/common/obr/src/org/apache/felix/sigil/obr/VersionRangeHelper.java
+++ b/sigil/common/obr/src/org/apache/felix/sigil/obr/VersionRangeHelper.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.obr;
 
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -31,162 +32,208 @@
 import org.apache.felix.sigil.model.common.VersionRange;
 import org.osgi.framework.Version;
 
-class VersionRangeHelper {
-	
-	// e.g. (&(version>=1.0.0)(version<=2.0.0)) (&(version>1.0.0)(version<2.0.0)) (&(!(version<1.0.0))(!(version>2.0.0))) (&(!(version<=1.0.0))(!(version>=2.0.0))) (version=1.0.0) (version>=1.0.0) (version<=2.0.0) (version>1.0.0) (version<2.0.0)  (!(version>2.0.0)) (!(version<1.0.0)) (!(version>=2.0.0)) (!(version<=1.0.0))
-	public static void main(String[] args) throws LDAPParseException {
-		for ( String arg : args ) {
-			LDAPExpr expr = LDAPParser.parseExpression(arg.trim());
-			System.out.println( expr + " -> " + decodeVersions(expr) ); 
-		}
-	}
-	
-	static VersionRange decodeVersions(LDAPExpr expr) throws NumberFormatException {
-		ArrayList<LDAPExpr> terms = new ArrayList<LDAPExpr>(1);
-		
-		findExpr("version", expr, terms);
-		
-		if ( terms.isEmpty() ) {
-			// woo hoo!
-			return VersionRange.ANY_VERSION;
-		}
-		else {
-			switch ( terms.size() ) {
-			case 1: {
-				return parseSimpleVersionRange(terms.get(0));
-			}
-			case 2: {
-				return parseCompoundVersionRange(terms.get(0), terms.get(1));
-			}
-			default: {
-				// (&(version>=min)(!(version=min))(version<=max)(!(version=max))) 	- (min,max) - not dealt with!!
-				// (&(|(version>min)(version=min))(|(version<max)(version=max))) 	- [min,max] - not dealt with!!
-				throw new NumberFormatException("Failed to parse complicated version expression " + expr);				
-			}
-			}
-		}
-	}
 
-	// (&(version>=min)(version<=max)) 									- [min,max]
-	// (&(version>min)(version<max))									- (min,max)
-	//
-	// (&(!(version<min))(!(version>max)))								- [min,max]
-	// (&(!(version<=min))(!(version>=max)) 							- (min,max)
-	private static VersionRange parseCompoundVersionRange(LDAPExpr left, LDAPExpr right) throws NumberFormatException {
-		VersionRange one = parseSimpleVersionRange(left);
-		VersionRange two = parseSimpleVersionRange(right);
-		
-		// sanity check
-		if ( one.isPointVersion() || two.isPointVersion() ) {
-			throw new NumberFormatException("Unexpected point version in compound expression " + left);				
-		}
-		
-		VersionRange max = one.getFloor().equals( Version.emptyVersion ) ? one : two;
-		VersionRange min = max == one ? two : one;
+class VersionRangeHelper
+{
 
-		return new VersionRange( min.isOpenFloor(), min.getFloor(), max.getCeiling(), max.isOpenCeiling() );
-	}
+    // e.g. (&(version>=1.0.0)(version<=2.0.0)) (&(version>1.0.0)(version<2.0.0)) (&(!(version<1.0.0))(!(version>2.0.0))) (&(!(version<=1.0.0))(!(version>=2.0.0))) (version=1.0.0) (version>=1.0.0) (version<=2.0.0) (version>1.0.0) (version<2.0.0)  (!(version>2.0.0)) (!(version<1.0.0)) (!(version>=2.0.0)) (!(version<=1.0.0))
+    public static void main( String[] args ) throws LDAPParseException
+    {
+        for ( String arg : args )
+        {
+            LDAPExpr expr = LDAPParser.parseExpression( arg.trim() );
+            System.out.println( expr + " -> " + decodeVersions( expr ) );
+        }
+    }
 
-	// possible variations				
-	// (version=v)														- [v,v]
-	//
-	// (version>=min)													- [min,*)
-	// (version<=max)													- [0,max]
-	//
-	// (version>min)													- (min,*)
-	// (version<max)													- [0,max)
-	//
-	// (!(version>max))													- [0,max]
-	// (!(version<min))													- [min,*)
-	// (!(version>=max))												- [0,max)
-	// (!(version<=min))												- (0,*)
-	private static VersionRange parseSimpleVersionRange(LDAPExpr expr) throws NumberFormatException {
-		Version min = Version.emptyVersion;
-		Version max = VersionRange.INFINITE_VERSION;
-		boolean openFloor = false;
-		boolean openCeiling = false;
-		if ( expr instanceof Not ) {
-			Not n = (Not) expr;
-			SimpleTerm t = (SimpleTerm) n.getEx();
-			if ( t.getOp() == Ops.EQ ) {
-				throw new NumberFormatException("Unexpected point version in negated expression " + expr);								
-			}
-			if ( !isMax(t.getOp()) ) {
-				max = toVersion(t);
-				openCeiling = !openFloor(t);
-			}
-			else if ( !isMin(t.getOp()) ) {
-				min = toVersion(t);
-				openFloor = !openCeiling(t);
-			}
-			else {
-				throw new IllegalStateException("Unexpected operator " + t.getOp());
-			}
-		}
-		else {
-			SimpleTerm t = (SimpleTerm) expr;
-			if ( t.getOp().equals( Ops.EQ ) ) {
-				max = toVersion(t);
-				min = max;
-				openFloor = false;
-				openCeiling = false;
-			}
-			else if ( isMax(t.getOp()) ) {
-				max = toVersion(t); 
-				openCeiling = openCeiling(t);
-			}
-			else if ( isMin(t.getOp()) ) {
-				min = toVersion(t);
-				openFloor = openFloor(t);
-			}
-			else {
-				throw new IllegalStateException("Unexpected operator " + t.getOp());
-			}
-		}
 
-		return new VersionRange( openFloor, min, max, openCeiling );
-	}
+    static VersionRange decodeVersions( LDAPExpr expr ) throws NumberFormatException
+    {
+        ArrayList<LDAPExpr> terms = new ArrayList<LDAPExpr>( 1 );
 
-	private static Version toVersion(SimpleTerm t) {
-		return new Version(t.getRval());
-	}
+        findExpr( "version", expr, terms );
 
-	private static boolean isMax(Ops op) {
-		return op == Ops.LE || op == Ops.LT;
-	}
-	
-	private static boolean isMin(Ops op) {
-		return op == Ops.GE || op == Ops.GT;
-	}
+        if ( terms.isEmpty() )
+        {
+            // woo hoo!
+            return VersionRange.ANY_VERSION;
+        }
+        else
+        {
+            switch ( terms.size() )
+            {
+                case 1:
+                {
+                    return parseSimpleVersionRange( terms.get( 0 ) );
+                }
+                case 2:
+                {
+                    return parseCompoundVersionRange( terms.get( 0 ), terms.get( 1 ) );
+                }
+                default:
+                {
+                    // (&(version>=min)(!(version=min))(version<=max)(!(version=max))) 	- (min,max) - not dealt with!!
+                    // (&(|(version>min)(version=min))(|(version<max)(version=max))) 	- [min,max] - not dealt with!!
+                    throw new NumberFormatException( "Failed to parse complicated version expression " + expr );
+                }
+            }
+        }
+    }
 
-	private static boolean openFloor(SimpleTerm t) {
-		return t.getOp() == Ops.GT;
-	}
 
-	private static boolean openCeiling(SimpleTerm t) {
-		return t.getOp() == Ops.LT;
-	}
-	
-	private static void findExpr(String string, LDAPExpr expr, List<LDAPExpr> terms) {
-		if ( expr instanceof SimpleTerm ) {
-			SimpleTerm term = (SimpleTerm) expr;
-			if ( term.getName().equals(string) ) {
-				terms.add(term);
-			}
-		}
-		else if ( expr instanceof Not ) {
-			Not not = (Not) expr;
-			if ( not.getEx() instanceof SimpleTerm ) {
-				SimpleTerm term = (SimpleTerm) not.getEx();
-				if ( term.getName().equals(string) ) {
-					terms.add(not);
-				}
-			}
-		}
-		else {
-			for ( LDAPExpr c : expr.getChildren() ) {
-				findExpr(string, c, terms);
-			}
-		}
-	}
+    // (&(version>=min)(version<=max)) 									- [min,max]
+    // (&(version>min)(version<max))									- (min,max)
+    //
+    // (&(!(version<min))(!(version>max)))								- [min,max]
+    // (&(!(version<=min))(!(version>=max)) 							- (min,max)
+    private static VersionRange parseCompoundVersionRange( LDAPExpr left, LDAPExpr right ) throws NumberFormatException
+    {
+        VersionRange one = parseSimpleVersionRange( left );
+        VersionRange two = parseSimpleVersionRange( right );
+
+        // sanity check
+        if ( one.isPointVersion() || two.isPointVersion() )
+        {
+            throw new NumberFormatException( "Unexpected point version in compound expression " + left );
+        }
+
+        VersionRange max = one.getFloor().equals( Version.emptyVersion ) ? one : two;
+        VersionRange min = max == one ? two : one;
+
+        return new VersionRange( min.isOpenFloor(), min.getFloor(), max.getCeiling(), max.isOpenCeiling() );
+    }
+
+
+    // possible variations				
+    // (version=v)														- [v,v]
+    //
+    // (version>=min)													- [min,*)
+    // (version<=max)													- [0,max]
+    //
+    // (version>min)													- (min,*)
+    // (version<max)													- [0,max)
+    //
+    // (!(version>max))													- [0,max]
+    // (!(version<min))													- [min,*)
+    // (!(version>=max))												- [0,max)
+    // (!(version<=min))												- (0,*)
+    private static VersionRange parseSimpleVersionRange( LDAPExpr expr ) throws NumberFormatException
+    {
+        Version min = Version.emptyVersion;
+        Version max = VersionRange.INFINITE_VERSION;
+        boolean openFloor = false;
+        boolean openCeiling = false;
+        if ( expr instanceof Not )
+        {
+            Not n = ( Not ) expr;
+            SimpleTerm t = ( SimpleTerm ) n.getEx();
+            if ( t.getOp() == Ops.EQ )
+            {
+                throw new NumberFormatException( "Unexpected point version in negated expression " + expr );
+            }
+            if ( !isMax( t.getOp() ) )
+            {
+                max = toVersion( t );
+                openCeiling = !openFloor( t );
+            }
+            else if ( !isMin( t.getOp() ) )
+            {
+                min = toVersion( t );
+                openFloor = !openCeiling( t );
+            }
+            else
+            {
+                throw new IllegalStateException( "Unexpected operator " + t.getOp() );
+            }
+        }
+        else
+        {
+            SimpleTerm t = ( SimpleTerm ) expr;
+            if ( t.getOp().equals( Ops.EQ ) )
+            {
+                max = toVersion( t );
+                min = max;
+                openFloor = false;
+                openCeiling = false;
+            }
+            else if ( isMax( t.getOp() ) )
+            {
+                max = toVersion( t );
+                openCeiling = openCeiling( t );
+            }
+            else if ( isMin( t.getOp() ) )
+            {
+                min = toVersion( t );
+                openFloor = openFloor( t );
+            }
+            else
+            {
+                throw new IllegalStateException( "Unexpected operator " + t.getOp() );
+            }
+        }
+
+        return new VersionRange( openFloor, min, max, openCeiling );
+    }
+
+
+    private static Version toVersion( SimpleTerm t )
+    {
+        return new Version( t.getRval() );
+    }
+
+
+    private static boolean isMax( Ops op )
+    {
+        return op == Ops.LE || op == Ops.LT;
+    }
+
+
+    private static boolean isMin( Ops op )
+    {
+        return op == Ops.GE || op == Ops.GT;
+    }
+
+
+    private static boolean openFloor( SimpleTerm t )
+    {
+        return t.getOp() == Ops.GT;
+    }
+
+
+    private static boolean openCeiling( SimpleTerm t )
+    {
+        return t.getOp() == Ops.LT;
+    }
+
+
+    private static void findExpr( String string, LDAPExpr expr, List<LDAPExpr> terms )
+    {
+        if ( expr instanceof SimpleTerm )
+        {
+            SimpleTerm term = ( SimpleTerm ) expr;
+            if ( term.getName().equals( string ) )
+            {
+                terms.add( term );
+            }
+        }
+        else if ( expr instanceof Not )
+        {
+            Not not = ( Not ) expr;
+            if ( not.getEx() instanceof SimpleTerm )
+            {
+                SimpleTerm term = ( SimpleTerm ) not.getEx();
+                if ( term.getName().equals( string ) )
+                {
+                    terms.add( not );
+                }
+            }
+        }
+        else
+        {
+            for ( LDAPExpr c : expr.getChildren() )
+            {
+                findExpr( string, c, terms );
+            }
+        }
+    }
 }
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 df2d42e..5b31977 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
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse;
 
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
@@ -80,491 +81,618 @@
 import org.osgi.framework.BundleContext;
 import org.osgi.util.tracker.ServiceTracker;
 
+
 /**
  * The activator class controls the plug-in life cycle
  */
-public class SigilCore extends AbstractUIPlugin {
+public class SigilCore extends AbstractUIPlugin
+{
 
-	private static final String BASE = "org.apache.felix.sigil";
-	// The plug-in ID
-	public static final String PLUGIN_ID = BASE + ".eclipse.core";
+    private static final String BASE = "org.apache.felix.sigil";
+    // The plug-in ID
+    public static final String PLUGIN_ID = BASE + ".eclipse.core";
     public static final String NATURE_ID = BASE + ".sigilnature";
     public static final String PREFERENCES_ID = BASE + ".ui.preferences.SigilPreferencePage";
     public static final String OSGI_INSTALLS_PREFERENCES_ID = BASE + ".ui.preferences.osgiInstalls";
     public static final String EXCLUDED_RESOURCES_PREFERENCES_ID = BASE + ".ui.preferences.excludedResources";
-	public static final String REPOSITORIES_PREFERENCES_ID = BASE + ".ui.preferences.repositoriesPreferencePage";
+    public static final String REPOSITORIES_PREFERENCES_ID = BASE + ".ui.preferences.repositoriesPreferencePage";
     public static final String SIGIL_PROJECT_FILE = IBldProject.PROJECT_FILE;
-	public static final String BUILDER_ID = PLUGIN_ID + ".sigilBuilder";
-	public static final String CLASSPATH_CONTAINER_PATH = BASE + ".classpathContainer";
+    public static final String BUILDER_ID = PLUGIN_ID + ".sigilBuilder";
+    public static final String CLASSPATH_CONTAINER_PATH = BASE + ".classpathContainer";
 
     public static final String OSGI_INSTALLS = BASE + ".osgi.installs";
-	public static final String OSGI_DEFAULT_INSTALL_ID = BASE + ".osgi.default.install.id";
-	public static final String OSGI_INSTALL_PREFIX = BASE + ".osgi.install.";
-	public static final String OSGI_SOURCE_LOCATION = BASE + ".osgi.source.location";
-	public static final String OSGI_INSTALL_CHECK_PREFERENCE = BASE + ".osgi.install.check";
-	public static final String LIBRARY_KEYS_PREF = BASE + ".library.keys";
-	public static final String PREFERENCES_REBUILD_PROJECTS = BASE + ".rebuild.projects";
-	public static final String QUALIFY_VERSIONS = BASE + ".qualify.versions";
-	
-	public static final String DEFAULT_VERSION_LOWER_BOUND = BASE + ".versionLowerBound";
-	public static final String DEFAULT_VERSION_UPPER_BOUND = BASE + ".versionUpperBound";
+    public static final String OSGI_DEFAULT_INSTALL_ID = BASE + ".osgi.default.install.id";
+    public static final String OSGI_INSTALL_PREFIX = BASE + ".osgi.install.";
+    public static final String OSGI_SOURCE_LOCATION = BASE + ".osgi.source.location";
+    public static final String OSGI_INSTALL_CHECK_PREFERENCE = BASE + ".osgi.install.check";
+    public static final String LIBRARY_KEYS_PREF = BASE + ".library.keys";
+    public static final String PREFERENCES_REBUILD_PROJECTS = BASE + ".rebuild.projects";
+    public static final String QUALIFY_VERSIONS = BASE + ".qualify.versions";
 
-	public static final String DEFAULT_EXCLUDED_RESOURCES = BASE + ".excludedResources";
-	public static final String PREFERENCES_NOASK_OSGI_INSTALL = BASE + ".noAskOSGIHome";
-	public static final String PREFERENCES_ADD_IMPORT_FOR_EXPORT = BASE + ".addImportForExport";
-	public static final String INCLUDE_OPTIONAL_DEPENDENCIES = BASE + ".includeOptionalDependencies";
+    public static final String DEFAULT_VERSION_LOWER_BOUND = BASE + ".versionLowerBound";
+    public static final String DEFAULT_VERSION_UPPER_BOUND = BASE + ".versionUpperBound";
 
-	public static final String INSTALL_BUILDER_EXTENSION_POINT_ID = BASE + ".installbuilder";
-	public static final String REPOSITORY_PROVIDER_EXTENSION_POINT_ID = BASE + ".repositoryprovider";
-	
-	public static final String MARKER_UNRESOLVED_DEPENDENCY = BASE + ".unresolvedDependencyMarker";
-	public static final String MARKER_UNRESOLVED_IMPORT_PACKAGE = BASE + ".unresolvedDependencyMarker.importPackage";
-	public static final String MARKER_UNRESOLVED_REQUIRE_BUNDLE = BASE + ".unresolvedDependencyMarker.requireBundle";
-	public static final String REPOSITORY_SET = PLUGIN_ID + ".repository.set";
-	public static final String PREFERENCES_INCLUDE_OPTIONAL = PLUGIN_ID + ".include.optional";
-	
-	private static final Object NULL = new Object();
+    public static final String DEFAULT_EXCLUDED_RESOURCES = BASE + ".excludedResources";
+    public static final String PREFERENCES_NOASK_OSGI_INSTALL = BASE + ".noAskOSGIHome";
+    public static final String PREFERENCES_ADD_IMPORT_FOR_EXPORT = BASE + ".addImportForExport";
+    public static final String INCLUDE_OPTIONAL_DEPENDENCIES = BASE + ".includeOptionalDependencies";
 
-	// The shared instance
-	private static SigilCore plugin;
+    public static final String INSTALL_BUILDER_EXTENSION_POINT_ID = BASE + ".installbuilder";
+    public static final String REPOSITORY_PROVIDER_EXTENSION_POINT_ID = BASE + ".repositoryprovider";
 
-	private ServiceTracker descriptorTracker;
-	private ServiceTracker registryTracker;
-	private ServiceTracker serializerTracker;
+    public static final String MARKER_UNRESOLVED_DEPENDENCY = BASE + ".unresolvedDependencyMarker";
+    public static final String MARKER_UNRESOLVED_IMPORT_PACKAGE = BASE + ".unresolvedDependencyMarker.importPackage";
+    public static final String MARKER_UNRESOLVED_REQUIRE_BUNDLE = BASE + ".unresolvedDependencyMarker.requireBundle";
+    public static final String REPOSITORY_SET = PLUGIN_ID + ".repository.set";
+    public static final String PREFERENCES_INCLUDE_OPTIONAL = PLUGIN_ID + ".include.optional";
 
-	private static IRepositoryConfiguration repositoryConfig;
-	private static OSGiInstallManager installs;
-	private static ISigilModelRoot modelRoot;
-	private static HashMap<Object, SigilRepositoryManager> repositoryManagers = new HashMap<Object, SigilRepositoryManager>();
-	private static GlobalRepositoryManager globalRepositoryManager;
+    private static final Object NULL = new Object();
 
-	/**
-	 * Returns the shared instance
-	 * 
-	 * @return the shared instance
-	 */
-	public static SigilCore getDefault() {
-		return plugin;
-	}
+    // The shared instance
+    private static SigilCore plugin;
 
-	public static CoreException newCoreException(String msg, Throwable t) {
-		return new CoreException(makeStatus(msg, t, IStatus.ERROR));
-	}
+    private ServiceTracker descriptorTracker;
+    private ServiceTracker registryTracker;
+    private ServiceTracker serializerTracker;
 
-	public static void log(String msg) {
-		DebugPlugin.log(makeStatus(msg, null, IStatus.INFO));
-	}
-
-	public static void error(String msg) {
-		DebugPlugin.log(makeStatus(msg, null, IStatus.ERROR));
-	}
-
-	public static void error(String msg, Throwable t) {
-		DebugPlugin.log(makeStatus(msg, t, IStatus.ERROR));
-	}
-
-	public static void warn(String msg) {
-		DebugPlugin.log(makeStatus(msg, null, IStatus.WARNING));
-	}
-
-	public static void warn(String msg, Throwable t) {
-		DebugPlugin.log(makeStatus(msg, t, IStatus.WARNING));
-	}
-	
-	private static IStatus makeStatus(String msg, Throwable t, int status) {
-		if (t instanceof CoreException) {
-			CoreException c = (CoreException) t;
-			return c.getStatus();
-		} else {
-			return new Status(status, SigilCore.PLUGIN_ID, status, msg, t);
-		}
-	}
-
-	public static boolean isSigilProject(IProject resource) {
-		if ( resource == null ) return false;
-		
-		if ( resource.isAccessible() && resource instanceof IProject ) {
-			IProject project = (IProject) resource;
-			try {
-				return project.hasNature(NATURE_ID);
-			} catch (CoreException e) {
-				error( e.getMessage(), e );
-				return false;
-			}
-		}
-		else {
-			return false;
-		}
-	}
-	
-	public static boolean hasProjectNature(IProject project)
-			throws CoreException {
-		return project.getNature(NATURE_ID) != null;
-	}
-
-	public static ResourceBundle getResourceBundle() {
-		return ResourceBundle.getBundle("resources."
-				+ SigilCore.class.getName(), Locale.getDefault(),
-				SigilCore.class.getClassLoader());
-	}
-
-	public static ISigilProjectModel create(IProject project)
-			throws CoreException {
-		if (project.hasNature(NATURE_ID)) {
-			return new SigilProject(project);
-		} else {
-			throw newCoreException("Project " + project.getName()
-					+ " is not a sigil project", null);
-		}
-	}
-
-	/**
-	 * The constructor
-	 */
-	public SigilCore() {
-		plugin = this;
-	}
-
-	public void earlyStartup() {
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see
-	 * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
-	 * )
-	 */
-	public void start(final BundleContext context) throws Exception {
-		super.start(context);
-
-		modelRoot = new SigilModelRoot();
-		
-		repositoryConfig = new RepositoryConfiguration();
-
-		installs = new OSGiInstallManager();
-		
-		globalRepositoryManager = new GlobalRepositoryManager();
-
-		registerModelElements(context);
-		registerResourceListeners();
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see
-	 * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
-	 * )
-	 */
-	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;
-		}
-		
-		for ( SigilRepositoryManager m : repositoryManagers.values() ) {
-			m.destroy();
-		}
-		
-		repositoryManagers.clear();
-		
-		globalRepositoryManager.destroy();
-		globalRepositoryManager = null;
-
-		plugin = null;
-
-		super.stop(context);
-	}
+    private static IRepositoryConfiguration repositoryConfig;
+    private static OSGiInstallManager installs;
+    private static ISigilModelRoot modelRoot;
+    private static HashMap<Object, SigilRepositoryManager> repositoryManagers = new HashMap<Object, SigilRepositoryManager>();
+    private static GlobalRepositoryManager globalRepositoryManager;
 
 
-	public static boolean isBundledPath(String bp) throws CoreException {
-		boolean bundle = JavaHelper.isCachedBundle(bp);
-
-		if (!bundle) {
-			bundle = isProjectPath(bp);
-
-			if (!bundle) {
-				for (IBundleRepository r : getGlobalRepositoryManager().getRepositories()) {
-					bundle = isBundlePath(bp, r);
-					if (bundle)
-						break;
-				}
-			}
-		}
-
-		return bundle;
-	}
-
-	private static boolean isBundlePath(final String bp, IBundleRepository r) {
-		final AtomicBoolean flag = new AtomicBoolean();
-
-		IRepositoryVisitor visitor = new IRepositoryVisitor() {
-			public boolean visit(ISigilBundle b) {
-				IPath path = b.getLocation();
-				if (path != null && path.toOSString().equals(bp)) {
-					flag.set(true);
-					return false;
-				} else {
-					return true;
-				}
-			}
-
-		};
-
-		r.accept(visitor, ResolutionConfig.INDEXED_ONLY
-				| ResolutionConfig.LOCAL_ONLY);
-
-		return flag.get();
-	}
-
-	private static boolean isProjectPath(String bp) throws CoreException {
-		for (ISigilProjectModel p : SigilCore.getRoot().getProjects()) {
-			IPath path = p.findOutputLocation();
-			
-			if (path.toOSString().equals(bp)) {
-				return true;
-			}
-		}
-
-		return false;
-	}
-	
-	private void registerResourceListeners() {
-		final IResourceChangeListener listener = new IResourceChangeListener() {
-			public void resourceChanged(IResourceChangeEvent event) {
-				IResourceDelta delta = event.getDelta();
-				if ( delta != null ) {
-					try {
-						delta.accept(new IResourceDeltaVisitor() {
-							public boolean visit(IResourceDelta delta) throws CoreException {
-								IResource resource = delta.getResource();
-								if(resource instanceof IProject) {
-									IProject project = (IProject) resource;
-									if ( SigilCore.isSigilProject(project) ) {
-										switch (delta.getKind()) {
-										case IResourceDelta.REMOVED:
-										case IResourceDelta.ADDED:
-											rebuildAllBundleDependencies(Job.getJobManager().createProgressGroup());
-											break;
-										}									
-									}
-									// Recurse no more
-									return false;
-								}							
-								return true;
-							}
-						});
-					} catch (CoreException e) {
-						error("Failed to update after change", e);
-					}
-				}
-			}
-		};
-		
-		Job job = new Job("Initialising sigil resource listeners") {
-			@Override
-			protected IStatus run(IProgressMonitor monitor) {
-				ResourcesPlugin.getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.POST_CHANGE);
-				return Status.OK_STATUS;
-			}
-		};
-		job.setSystem(true);
-		job.schedule();
-	}
-
-	private void registerModelElements(BundleContext context) {
-		// trick to get eclipse to lazy load BldCore for model elements
-		BldCore.getLicenseManager();
-		String uri = "http://sigil.codecauldron.org/xml/sigil-namespace";
-		ModelElementFactory.getInstance().register(ISigilProjectModel.class,
-				SigilProject.class, "project", "sigil", uri);
-	}
-
-	public static IOSGiInstallManager getInstallManager() {
-		return installs;
-	}
-
-	public static ISigilModelRoot getRoot() {
-		return modelRoot;
-	}
-	
-	public static IRepositoryManager getGlobalRepositoryManager() {
-		return globalRepositoryManager;
-	}
-
-	public static IRepositoryManager getRepositoryManager(String set) {
-		SigilRepositoryManager manager = null;
-		
-		if ( set == null ) {
-			manager = repositoryManagers.get( NULL );
-			if ( manager == null ) {
-				manager = new SigilRepositoryManager(null);
-				manager.initialise();
-				repositoryManagers.put( NULL, manager );
-			}
-		}
-		else {
-			manager = repositoryManagers.get(set);
-			
-			if ( manager == null ) {
-				manager = new SigilRepositoryManager(set);
-				manager.initialise();
-				repositoryManagers.put( set, manager );
-			}			
-		}
-		
-		return manager;
-	}
-	public static IRepositoryManager getRepositoryManager(ISigilProjectModel model) {
-		return getRepositoryManager(loadProjectRepositorySet(model));
-	}
-	
-	private static String loadProjectRepositorySet(ISigilProjectModel model) {
-		if ( model == null ) {
-			return null;
-		}
-		
-		return model.getPreferences().get(REPOSITORY_SET, null );
-	}		
+    /**
+     * Returns the shared instance
+     * 
+     * @return the shared instance
+     */
+    public static SigilCore getDefault()
+    {
+        return plugin;
+    }
 
 
-	public static IRepositoryConfiguration getRepositoryConfiguration() {
-		return repositoryConfig;
-	}	
+    public static CoreException newCoreException( String msg, Throwable t )
+    {
+        return new CoreException( makeStatus( msg, t, IStatus.ERROR ) );
+    }
 
-	public static void rebuildAllBundleDependencies(IProgressMonitor monitor) {
-		Collection<ISigilProjectModel> projects = getRoot().getProjects();
-		if ( !projects.isEmpty() ) {
-			SubMonitor progress = SubMonitor.convert(monitor, projects.size()*20);
-			for ( ISigilProjectModel p : projects ) {
-				rebuild(p, progress);
-			}			
-		}
-		
-		monitor.done();
-	}
-	
-	public static void rebuildBundleDependencies(ISigilProjectModel project, IProgressMonitor monitor) {
-		HashSet<ISigilProjectModel> affected = new HashSet<ISigilProjectModel>(project.findDependentProjects(monitor));
-		affected.add(project);
 
-		SubMonitor progress = SubMonitor.convert(monitor, affected.size()*20);
-		for (ISigilProjectModel dependent : affected) {
-			rebuild(dependent, progress);
-		}
-	}	
-	
-	
-	private static void rebuild(ISigilProjectModel dependent, SubMonitor progress) {
-		try {
-			dependent.resetClasspath(progress.newChild(10));
-			dependent.getProject().build(IncrementalProjectBuilder.FULL_BUILD, progress.newChild(10));
-		} catch (CoreException e) {
-			SigilCore.error("Failed to rebuild " + dependent, e);
-		}
-	}
+    public static void log( String msg )
+    {
+        DebugPlugin.log( makeStatus( msg, null, IStatus.INFO ) );
+    }
 
-	public IPath findDefaultBundleLocation(ISigilProjectModel m)
-			throws CoreException {
-		IPath loc = m.getProject().getLocation();
-		loc = loc.append(m.getJavaModel().getOutputLocation().removeFirstSegments(1));
-		loc = loc.removeLastSegments(1).append( "lib" );
-		return loc.append(m.getSymbolicName() + ".jar");
-	}
 
-	public static void makeSigilProject(IProject project,
-			IProgressMonitor monitor) throws CoreException {
-		IProjectDescription description = project.getDescription();
+    public static void error( String msg )
+    {
+        DebugPlugin.log( makeStatus( msg, null, IStatus.ERROR ) );
+    }
 
-		String[] natures = description.getNatureIds();
-		String[] newNatures = new String[natures.length + 1];
-		System.arraycopy(natures, 0, newNatures, 0, natures.length);
-		newNatures[natures.length] = SigilCore.NATURE_ID;
-		description.setNatureIds(newNatures);
 
-		ICommand sigilBuild = description.newCommand();
-		sigilBuild.setBuilderName(SigilCore.BUILDER_ID);
+    public static void error( String msg, Throwable t )
+    {
+        DebugPlugin.log( makeStatus( msg, t, IStatus.ERROR ) );
+    }
 
-		ICommand javaBuild = description.newCommand();
-		javaBuild.setBuilderName(JavaCore.BUILDER_ID);
 
-		description.setBuildSpec(new ICommand[] { javaBuild, sigilBuild });
+    public static void warn( String msg )
+    {
+        DebugPlugin.log( makeStatus( msg, null, IStatus.WARNING ) );
+    }
 
-		project.setDescription(description, new SubProgressMonitor(monitor, 2));
 
-		IJavaProject java = JavaCore.create(project);
-		if (java.exists()) {
-			IClasspathEntry[] cp = java.getRawClasspath();
-			// XXX fix for http://jira.codecauldron.org/browse/SIGIL-304
-			if ( !isSigilOnClasspath(cp) ) {
-				ArrayList<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(
-						Arrays.asList(cp));
-				entries.add(JavaCore.newContainerEntry(new Path(
-						SigilCore.CLASSPATH_CONTAINER_PATH)));
-				java.setRawClasspath(entries.toArray(new IClasspathEntry[entries
-						.size()]), monitor);
-			}
-		}
-	}
+    public static void warn( String msg, Throwable t )
+    {
+        DebugPlugin.log( makeStatus( msg, t, IStatus.WARNING ) );
+    }
 
-	/**
-	 * @param cp
-	 * @return
-	 */
-	private static boolean isSigilOnClasspath(IClasspathEntry[] cp) {
-		for ( IClasspathEntry e : cp ) {
-			if ( e.getEntryKind() == IClasspathEntry.CPE_CONTAINER && e.getPath().segment(0).equals(SigilCore.CLASSPATH_CONTAINER_PATH) ) {
-				return true;
-			}
-		}
-		return false;
-	}
 
-	public static Image loadImage(URL url) throws IOException {
-		ImageRegistry registry = getDefault().getImageRegistry();
-		
-		String key = url.toExternalForm();
-		Image img = registry.get( key );
-		
-		if ( img == null ) {
-			img = openImage(url);
-			registry.put( key, img );
-		}
-		
-		return img;
-	}
+    private static IStatus makeStatus( String msg, Throwable t, int status )
+    {
+        if ( t instanceof CoreException )
+        {
+            CoreException c = ( CoreException ) t;
+            return c.getStatus();
+        }
+        else
+        {
+            return new Status( status, SigilCore.PLUGIN_ID, status, msg, t );
+        }
+    }
 
-	private static Image openImage(URL url) throws IOException {
-		Display display = Display.getCurrent();
-		if ( display == null ) {
-			display = Display.getDefault();
-		}
-		
-		InputStream in = null;
-		try {
-			in = url.openStream();
-			return new Image(display, in);
-		}
-		finally {
-			if ( in != null ) {
-				try {
-					in.close();
-				} catch (IOException e) {
-					error( "Failed to close stream", e );
-				}
-			}
-		}
-	}
+
+    public static boolean isSigilProject( IProject resource )
+    {
+        if ( resource == null )
+            return false;
+
+        if ( resource.isAccessible() && resource instanceof IProject )
+        {
+            IProject project = ( IProject ) resource;
+            try
+            {
+                return project.hasNature( NATURE_ID );
+            }
+            catch ( CoreException e )
+            {
+                error( e.getMessage(), e );
+                return false;
+            }
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    public static boolean hasProjectNature( IProject project ) throws CoreException
+    {
+        return project.getNature( NATURE_ID ) != null;
+    }
+
+
+    public static ResourceBundle getResourceBundle()
+    {
+        return ResourceBundle.getBundle( "resources." + SigilCore.class.getName(), Locale.getDefault(), SigilCore.class
+            .getClassLoader() );
+    }
+
+
+    public static ISigilProjectModel create( IProject project ) throws CoreException
+    {
+        if ( project.hasNature( NATURE_ID ) )
+        {
+            return new SigilProject( project );
+        }
+        else
+        {
+            throw newCoreException( "Project " + project.getName() + " is not a sigil project", null );
+        }
+    }
+
+
+    /**
+     * The constructor
+     */
+    public SigilCore()
+    {
+        plugin = this;
+    }
+
+
+    public void earlyStartup()
+    {
+    }
+
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
+     * )
+     */
+    public void start( final BundleContext context ) throws Exception
+    {
+        super.start( context );
+
+        modelRoot = new SigilModelRoot();
+
+        repositoryConfig = new RepositoryConfiguration();
+
+        installs = new OSGiInstallManager();
+
+        globalRepositoryManager = new GlobalRepositoryManager();
+
+        registerModelElements( context );
+        registerResourceListeners();
+    }
+
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+     * )
+     */
+    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;
+        }
+
+        for ( SigilRepositoryManager m : repositoryManagers.values() )
+        {
+            m.destroy();
+        }
+
+        repositoryManagers.clear();
+
+        globalRepositoryManager.destroy();
+        globalRepositoryManager = null;
+
+        plugin = null;
+
+        super.stop( context );
+    }
+
+
+    public static boolean isBundledPath( String bp ) throws CoreException
+    {
+        boolean bundle = JavaHelper.isCachedBundle( bp );
+
+        if ( !bundle )
+        {
+            bundle = isProjectPath( bp );
+
+            if ( !bundle )
+            {
+                for ( IBundleRepository r : getGlobalRepositoryManager().getRepositories() )
+                {
+                    bundle = isBundlePath( bp, r );
+                    if ( bundle )
+                        break;
+                }
+            }
+        }
+
+        return bundle;
+    }
+
+
+    private static boolean isBundlePath( final String bp, IBundleRepository r )
+    {
+        final AtomicBoolean flag = new AtomicBoolean();
+
+        IRepositoryVisitor visitor = new IRepositoryVisitor()
+        {
+            public boolean visit( ISigilBundle b )
+            {
+                IPath path = b.getLocation();
+                if ( path != null && path.toOSString().equals( bp ) )
+                {
+                    flag.set( true );
+                    return false;
+                }
+                else
+                {
+                    return true;
+                }
+            }
+
+        };
+
+        r.accept( visitor, ResolutionConfig.INDEXED_ONLY | ResolutionConfig.LOCAL_ONLY );
+
+        return flag.get();
+    }
+
+
+    private static boolean isProjectPath( String bp ) throws CoreException
+    {
+        for ( ISigilProjectModel p : SigilCore.getRoot().getProjects() )
+        {
+            IPath path = p.findOutputLocation();
+
+            if ( path.toOSString().equals( bp ) )
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+
+    private void registerResourceListeners()
+    {
+        final IResourceChangeListener listener = new IResourceChangeListener()
+        {
+            public void resourceChanged( IResourceChangeEvent event )
+            {
+                IResourceDelta delta = event.getDelta();
+                if ( delta != null )
+                {
+                    try
+                    {
+                        delta.accept( new IResourceDeltaVisitor()
+                        {
+                            public boolean visit( IResourceDelta delta ) throws CoreException
+                            {
+                                IResource resource = delta.getResource();
+                                if ( resource instanceof IProject )
+                                {
+                                    IProject project = ( IProject ) resource;
+                                    if ( SigilCore.isSigilProject( project ) )
+                                    {
+                                        switch ( delta.getKind() )
+                                        {
+                                            case IResourceDelta.REMOVED:
+                                            case IResourceDelta.ADDED:
+                                                rebuildAllBundleDependencies( Job.getJobManager().createProgressGroup() );
+                                                break;
+                                        }
+                                    }
+                                    // Recurse no more
+                                    return false;
+                                }
+                                return true;
+                            }
+                        } );
+                    }
+                    catch ( CoreException e )
+                    {
+                        error( "Failed to update after change", e );
+                    }
+                }
+            }
+        };
+
+        Job job = new Job( "Initialising sigil resource listeners" )
+        {
+            @Override
+            protected IStatus run( IProgressMonitor monitor )
+            {
+                ResourcesPlugin.getWorkspace().addResourceChangeListener( listener,
+                    IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.POST_CHANGE );
+                return Status.OK_STATUS;
+            }
+        };
+        job.setSystem( true );
+        job.schedule();
+    }
+
+
+    private void registerModelElements( BundleContext context )
+    {
+        // trick to get eclipse to lazy load BldCore for model elements
+        BldCore.getLicenseManager();
+        String uri = "http://sigil.codecauldron.org/xml/sigil-namespace";
+        ModelElementFactory.getInstance().register( ISigilProjectModel.class, SigilProject.class, "project", "sigil",
+            uri );
+    }
+
+
+    public static IOSGiInstallManager getInstallManager()
+    {
+        return installs;
+    }
+
+
+    public static ISigilModelRoot getRoot()
+    {
+        return modelRoot;
+    }
+
+
+    public static IRepositoryManager getGlobalRepositoryManager()
+    {
+        return globalRepositoryManager;
+    }
+
+
+    public static IRepositoryManager getRepositoryManager( String set )
+    {
+        SigilRepositoryManager manager = null;
+
+        if ( set == null )
+        {
+            manager = repositoryManagers.get( NULL );
+            if ( manager == null )
+            {
+                manager = new SigilRepositoryManager( null );
+                manager.initialise();
+                repositoryManagers.put( NULL, manager );
+            }
+        }
+        else
+        {
+            manager = repositoryManagers.get( set );
+
+            if ( manager == null )
+            {
+                manager = new SigilRepositoryManager( set );
+                manager.initialise();
+                repositoryManagers.put( set, manager );
+            }
+        }
+
+        return manager;
+    }
+
+
+    public static IRepositoryManager getRepositoryManager( ISigilProjectModel model )
+    {
+        return getRepositoryManager( loadProjectRepositorySet( model ) );
+    }
+
+
+    private static String loadProjectRepositorySet( ISigilProjectModel model )
+    {
+        if ( model == null )
+        {
+            return null;
+        }
+
+        return model.getPreferences().get( REPOSITORY_SET, null );
+    }
+
+
+    public static IRepositoryConfiguration getRepositoryConfiguration()
+    {
+        return repositoryConfig;
+    }
+
+
+    public static void rebuildAllBundleDependencies( IProgressMonitor monitor )
+    {
+        Collection<ISigilProjectModel> projects = getRoot().getProjects();
+        if ( !projects.isEmpty() )
+        {
+            SubMonitor progress = SubMonitor.convert( monitor, projects.size() * 20 );
+            for ( ISigilProjectModel p : projects )
+            {
+                rebuild( p, progress );
+            }
+        }
+
+        monitor.done();
+    }
+
+
+    public static void rebuildBundleDependencies( ISigilProjectModel project, IProgressMonitor monitor )
+    {
+        HashSet<ISigilProjectModel> affected = new HashSet<ISigilProjectModel>( project.findDependentProjects( monitor ) );
+        affected.add( project );
+
+        SubMonitor progress = SubMonitor.convert( monitor, affected.size() * 20 );
+        for ( ISigilProjectModel dependent : affected )
+        {
+            rebuild( dependent, progress );
+        }
+    }
+
+
+    private static void rebuild( ISigilProjectModel dependent, SubMonitor progress )
+    {
+        try
+        {
+            dependent.resetClasspath( progress.newChild( 10 ) );
+            dependent.getProject().build( IncrementalProjectBuilder.FULL_BUILD, progress.newChild( 10 ) );
+        }
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Failed to rebuild " + dependent, e );
+        }
+    }
+
+
+    public IPath findDefaultBundleLocation( ISigilProjectModel m ) throws CoreException
+    {
+        IPath loc = m.getProject().getLocation();
+        loc = loc.append( m.getJavaModel().getOutputLocation().removeFirstSegments( 1 ) );
+        loc = loc.removeLastSegments( 1 ).append( "lib" );
+        return loc.append( m.getSymbolicName() + ".jar" );
+    }
+
+
+    public static void makeSigilProject( IProject project, IProgressMonitor monitor ) throws CoreException
+    {
+        IProjectDescription description = project.getDescription();
+
+        String[] natures = description.getNatureIds();
+        String[] newNatures = new String[natures.length + 1];
+        System.arraycopy( natures, 0, newNatures, 0, natures.length );
+        newNatures[natures.length] = SigilCore.NATURE_ID;
+        description.setNatureIds( newNatures );
+
+        ICommand sigilBuild = description.newCommand();
+        sigilBuild.setBuilderName( SigilCore.BUILDER_ID );
+
+        ICommand javaBuild = description.newCommand();
+        javaBuild.setBuilderName( JavaCore.BUILDER_ID );
+
+        description.setBuildSpec( new ICommand[]
+            { javaBuild, sigilBuild } );
+
+        project.setDescription( description, new SubProgressMonitor( monitor, 2 ) );
+
+        IJavaProject java = JavaCore.create( project );
+        if ( java.exists() )
+        {
+            IClasspathEntry[] cp = java.getRawClasspath();
+            // XXX fix for http://jira.codecauldron.org/browse/SIGIL-304
+            if ( !isSigilOnClasspath( cp ) )
+            {
+                ArrayList<IClasspathEntry> entries = new ArrayList<IClasspathEntry>( Arrays.asList( cp ) );
+                entries.add( JavaCore.newContainerEntry( new Path( SigilCore.CLASSPATH_CONTAINER_PATH ) ) );
+                java.setRawClasspath( entries.toArray( new IClasspathEntry[entries.size()] ), monitor );
+            }
+        }
+    }
+
+
+    /**
+     * @param cp
+     * @return
+     */
+    private static boolean isSigilOnClasspath( IClasspathEntry[] cp )
+    {
+        for ( IClasspathEntry e : cp )
+        {
+            if ( e.getEntryKind() == IClasspathEntry.CPE_CONTAINER
+                && e.getPath().segment( 0 ).equals( SigilCore.CLASSPATH_CONTAINER_PATH ) )
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    public static Image loadImage( URL url ) throws IOException
+    {
+        ImageRegistry registry = getDefault().getImageRegistry();
+
+        String key = url.toExternalForm();
+        Image img = registry.get( key );
+
+        if ( img == null )
+        {
+            img = openImage( url );
+            registry.put( key, img );
+        }
+
+        return img;
+    }
+
+
+    private static Image openImage( URL url ) throws IOException
+    {
+        Display display = Display.getCurrent();
+        if ( display == null )
+        {
+            display = Display.getDefault();
+        }
+
+        InputStream in = null;
+        try
+        {
+            in = url.openStream();
+            return new Image( display, in );
+        }
+        finally
+        {
+            if ( in != null )
+            {
+                try
+                {
+                    in.close();
+                }
+                catch ( IOException e )
+                {
+                    error( "Failed to close stream", e );
+                }
+            }
+        }
+    }
 
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstall.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstall.java
index 5cf85dc..154826a 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstall.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstall.java
@@ -19,47 +19,55 @@
 
 package org.apache.felix.sigil.eclipse.install;
 
+
 import java.util.Map;
 
 import org.eclipse.core.runtime.IPath;
 
+
 /**
  * Encapsulates all information about a particular OSGi install.
  * 
  * @author dave
  *
  */
-public interface IOSGiInstall {
-	
-	/**
-	 * A unique id which can be used to refer to this install within the eclipse runtime.
-	 * @return
-	 */
-	String getId();
-	
-	/**
-	 * Where this install is located
-	 * @return
-	 */
-	IPath getInstallLocation();
+public interface IOSGiInstall
+{
 
-	/**
-	 * @return
-	 */
-	Map<String, String> getProperties();
-	
-	/**
-	 * @return
-	 */
-	String[] getLaunchArguments();	
-	
-	/**
-	 * @return
-	 */
-	IPath getVarDirectory();
-	
-	/**
-	 * @return
-	 */
-	IOSGiInstallType getType();
+    /**
+     * A unique id which can be used to refer to this install within the eclipse runtime.
+     * @return
+     */
+    String getId();
+
+
+    /**
+     * Where this install is located
+     * @return
+     */
+    IPath getInstallLocation();
+
+
+    /**
+     * @return
+     */
+    Map<String, String> getProperties();
+
+
+    /**
+     * @return
+     */
+    String[] getLaunchArguments();
+
+
+    /**
+     * @return
+     */
+    IPath getVarDirectory();
+
+
+    /**
+     * @return
+     */
+    IOSGiInstallType getType();
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstallBuilder.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstallBuilder.java
index 42329a6..69cdbdc 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstallBuilder.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstallBuilder.java
@@ -19,9 +19,12 @@
 
 package org.apache.felix.sigil.eclipse.install;
 
+
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 
-public interface IOSGiInstallBuilder {
-	IOSGiInstall build(String id, IPath path) throws CoreException;
+
+public interface IOSGiInstallBuilder
+{
+    IOSGiInstall build( String id, IPath path ) throws CoreException;
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstallManager.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstallManager.java
index a3776bc..3661463 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstallManager.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstallManager.java
@@ -19,10 +19,20 @@
 
 package org.apache.felix.sigil.eclipse.install;
 
-public interface IOSGiInstallManager {
-	IOSGiInstall findInstall(String id);
-	String[] getInstallIDs();
-	IOSGiInstall[] getInstalls();
-	IOSGiInstall getDefaultInstall();
-	IOSGiInstallType findInstallType(String location);
+
+public interface IOSGiInstallManager
+{
+    IOSGiInstall findInstall( String id );
+
+
+    String[] getInstallIDs();
+
+
+    IOSGiInstall[] getInstalls();
+
+
+    IOSGiInstall getDefaultInstall();
+
+
+    IOSGiInstallType findInstallType( String location );
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstallType.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstallType.java
index 6a2cdd5..933f54d 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstallType.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/IOSGiInstallType.java
@@ -19,50 +19,61 @@
 
 package org.apache.felix.sigil.eclipse.install;
 
+
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.swt.graphics.Image;
 
+
 //import org.eclipse.swt.graphics.Image;
 
-public interface IOSGiInstallType {
-	/**
-	 * @return
-	 */
-	String getName();
+public interface IOSGiInstallType
+{
+    /**
+     * @return
+     */
+    String getName();
 
-	/**
-	 * 
-	 * @return
-	 */
-	String getVersion();
-	
-	/**
-	 * @return
-	 */
-	String getMainClass();
-	
-	/**
-	 * @return
-	 */
-	String[] getClassPath();
 
-	/**
-	 * @return
-	 */
-	IPath getSourceLocation();
-	
-	/**
-	 * @return
-	 */
-	IPath getJavaDocLocation();
-	
-	/**
-	 * Return the paths of any bundles that are started by default in this OSGi instance.
-	 * @return
-	 */
-	IPath[] getDefaultBundleLocations();
+    /**
+     * 
+     * @return
+     */
+    String getVersion();
 
-	String getId();
 
-	Image getIcon();
+    /**
+     * @return
+     */
+    String getMainClass();
+
+
+    /**
+     * @return
+     */
+    String[] getClassPath();
+
+
+    /**
+     * @return
+     */
+    IPath getSourceLocation();
+
+
+    /**
+     * @return
+     */
+    IPath getJavaDocLocation();
+
+
+    /**
+     * Return the paths of any bundles that are started by default in this OSGi instance.
+     * @return
+     */
+    IPath[] getDefaultBundleLocations();
+
+
+    String getId();
+
+
+    Image getIcon();
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/OSGiInstall.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/OSGiInstall.java
index 4316e6f..4cf4604 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/OSGiInstall.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/OSGiInstall.java
@@ -19,75 +19,99 @@
 
 package org.apache.felix.sigil.eclipse.install;
 
+
 import java.util.Arrays;
 import java.util.Map;
 
 import org.eclipse.core.runtime.IPath;
 
-public class OSGiInstall implements IOSGiInstall {
 
-	private String id;
-	private IPath installLocation;
-	private String[] launchArgs;
-	private Map<String, String> properties;
-	private IPath varDirectory;
-	private IOSGiInstallType type;
-	
-	public IPath getVarDirectory() {
-		return varDirectory;
-	}
+public class OSGiInstall implements IOSGiInstall
+{
 
-	public void setVarDirectory(IPath varDirectory) {
-		this.varDirectory = varDirectory;
-	}
+    private String id;
+    private IPath installLocation;
+    private String[] launchArgs;
+    private Map<String, String> properties;
+    private IPath varDirectory;
+    private IOSGiInstallType type;
 
-	public OSGiInstall(String id) {
-		this.id = id;
-	}
 
-	public String getId() {
-		return id;
-	}
+    public IPath getVarDirectory()
+    {
+        return varDirectory;
+    }
 
-	public IPath getInstallLocation() {
-		return installLocation;
-	}
 
-	public void setInstallLocation(IPath installLocation) {
-		this.installLocation = installLocation;
-	}
+    public void setVarDirectory( IPath varDirectory )
+    {
+        this.varDirectory = varDirectory;
+    }
 
-	public String[] getLaunchArguments() {
-		return launchArgs;
-	}
-	
-	public void setLaunchArguments(String[] launchArgs) {
-		this.launchArgs = launchArgs;
-	}
 
-	public Map<String, String> getProperties() {
-		return properties;
-	}
-	
-	public void setProperties(Map<String,String> properties) {
-		this.properties = properties;
-	}
+    public OSGiInstall( String id )
+    {
+        this.id = id;
+    }
 
-	public String toString() {
-		return "OSGiInstall[\n" + 
-			"id=" + id + "\n" +
-			"type=" + type + "\n" +
-			"installLocation=" + installLocation + "\n" +
-			"launchArgs=" + Arrays.asList(launchArgs) + "\n" +
-			"properties=" + properties + "\n" +
-			"]";
-	}
 
-        public IOSGiInstallType getType() {
-                return type;
-        }
-        
-        public void setType(IOSGiInstallType type) {
-                this.type = type;
-        }
+    public String getId()
+    {
+        return id;
+    }
+
+
+    public IPath getInstallLocation()
+    {
+        return installLocation;
+    }
+
+
+    public void setInstallLocation( IPath installLocation )
+    {
+        this.installLocation = installLocation;
+    }
+
+
+    public String[] getLaunchArguments()
+    {
+        return launchArgs;
+    }
+
+
+    public void setLaunchArguments( String[] launchArgs )
+    {
+        this.launchArgs = launchArgs;
+    }
+
+
+    public Map<String, String> getProperties()
+    {
+        return properties;
+    }
+
+
+    public void setProperties( Map<String, String> properties )
+    {
+        this.properties = properties;
+    }
+
+
+    public String toString()
+    {
+        return "OSGiInstall[\n" + "id=" + id + "\n" + "type=" + type + "\n" + "installLocation=" + installLocation
+            + "\n" + "launchArgs=" + Arrays.asList( launchArgs ) + "\n" + "properties=" + properties + "\n" + "]";
+    }
+
+
+    public IOSGiInstallType getType()
+    {
+        return type;
+    }
+
+
+    public void setType( IOSGiInstallType type )
+    {
+        this.type = type;
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/OSGiInstallType.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/OSGiInstallType.java
index c670363..18472a7 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/OSGiInstallType.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/install/OSGiInstallType.java
@@ -19,104 +19,140 @@
 
 package org.apache.felix.sigil.eclipse.install;
 
+
 import java.util.Arrays;
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.swt.graphics.Image;
 
-public class OSGiInstallType implements IOSGiInstallType {
 
-	private String id;
-	private String name;
-	private String version;
-	private String mainClass;
-	private String[] classPath;
-	private IPath javaDocLocation;
-	private IPath sourceLocation;
-	private IPath[] defaultBundleLocations;
-	private Image icon;
-	
-	public Image getIcon() {
-		return icon;
-	}
+public class OSGiInstallType implements IOSGiInstallType
+{
 
-	public void setIcon(Image icon) {
-		this.icon = icon;
-	}
+    private String id;
+    private String name;
+    private String version;
+    private String mainClass;
+    private String[] classPath;
+    private IPath javaDocLocation;
+    private IPath sourceLocation;
+    private IPath[] defaultBundleLocations;
+    private Image icon;
 
-	public String getId() {
-		return id;
-	}
-	
-	public String[] getClassPath() {
-		return classPath;
-	}
 
-	public IPath[] getDefaultBundleLocations() {
-		return defaultBundleLocations;
-	}
+    public Image getIcon()
+    {
+        return icon;
+    }
 
-	public IPath getJavaDocLocation() {
-		return javaDocLocation;
-	}
 
-	public String getMainClass() {
-		return mainClass;
-	}
+    public void setIcon( Image icon )
+    {
+        this.icon = icon;
+    }
 
-	public String getName() {
-		return name;
-	}
 
-	public IPath getSourceLocation() {
-		return sourceLocation;
-	}
+    public String getId()
+    {
+        return id;
+    }
 
-	public String getVersion() {
-		return version;
-	}
-	
-	public void setId(String id) {
-		this.id = id;
-	}
 
-	public void setName(String name) {
-		this.name = name;
-	}
+    public String[] getClassPath()
+    {
+        return classPath;
+    }
 
-	public void setVersion(String version) {
-		this.version = version;
-	}
 
-	public void setMainClass(String mainClass) {
-		this.mainClass = mainClass;
-	}
+    public IPath[] getDefaultBundleLocations()
+    {
+        return defaultBundleLocations;
+    }
 
-	public void setClassPath(String[] classPath) {
-		this.classPath = classPath;
-	}
 
-	public void setJavaDocLocation(IPath javaDocLocation) {
-		this.javaDocLocation = javaDocLocation;
-	}
+    public IPath getJavaDocLocation()
+    {
+        return javaDocLocation;
+    }
 
-	public void setSourceLocation(IPath sourceLocation) {
-		this.sourceLocation = sourceLocation;
-	}
 
-	public void setDefaultBundleLocations(IPath[] defaultBundleLocations) {
-		this.defaultBundleLocations = defaultBundleLocations;
-	}
-	
-	public String toString() {
-		return "OSGiInstallType[\n" + 
-			"name=" + name + "\n" +
-			"version=" + version + "\n" +
-			"mainClass=" + mainClass + "\n" +
-			"classPath=" + Arrays.asList(classPath) + "\n" +
-			"javaDocLocation=" + javaDocLocation + "\n" +
-			"sourceLocation=" + sourceLocation + "\n" +
-			"defaultBundleLocations=" + Arrays.asList(defaultBundleLocations) + "\n" +
-			"]";
-	}
+    public String getMainClass()
+    {
+        return mainClass;
+    }
+
+
+    public String getName()
+    {
+        return name;
+    }
+
+
+    public IPath getSourceLocation()
+    {
+        return sourceLocation;
+    }
+
+
+    public String getVersion()
+    {
+        return version;
+    }
+
+
+    public void setId( String id )
+    {
+        this.id = id;
+    }
+
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+
+    public void setVersion( String version )
+    {
+        this.version = version;
+    }
+
+
+    public void setMainClass( String mainClass )
+    {
+        this.mainClass = mainClass;
+    }
+
+
+    public void setClassPath( String[] classPath )
+    {
+        this.classPath = classPath;
+    }
+
+
+    public void setJavaDocLocation( IPath javaDocLocation )
+    {
+        this.javaDocLocation = javaDocLocation;
+    }
+
+
+    public void setSourceLocation( IPath sourceLocation )
+    {
+        this.sourceLocation = sourceLocation;
+    }
+
+
+    public void setDefaultBundleLocations( IPath[] defaultBundleLocations )
+    {
+        this.defaultBundleLocations = defaultBundleLocations;
+    }
+
+
+    public String toString()
+    {
+        return "OSGiInstallType[\n" + "name=" + name + "\n" + "version=" + version + "\n" + "mainClass=" + mainClass
+            + "\n" + "classPath=" + Arrays.asList( classPath ) + "\n" + "javaDocLocation=" + javaDocLocation + "\n"
+            + "sourceLocation=" + sourceLocation + "\n" + "defaultBundleLocations="
+            + Arrays.asList( defaultBundleLocations ) + "\n" + "]";
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/adapter/FileAdaptorFactory.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/adapter/FileAdaptorFactory.java
index e8c8ee2..9465027 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/adapter/FileAdaptorFactory.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/adapter/FileAdaptorFactory.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.internal.adapter;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.apache.felix.sigil.model.ModelElementFactory;
@@ -29,58 +30,75 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IAdapterFactory;
 
+
 /**
  * @author savage
  *
  */
-public class FileAdaptorFactory implements IAdapterFactory {
+public class FileAdaptorFactory implements IAdapterFactory
+{
 
-	public FileAdaptorFactory() {
-		
-	}
-	private Class<?>[] types = new Class<?>[] { ISigilBundle.class };
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
-	 */
-	@SuppressWarnings("unchecked")
-	public Object getAdapter( Object adaptableObject, Class adapterType ) {
+    public FileAdaptorFactory()
+    {
+
+    }
+
+    private Class<?>[] types = new Class<?>[]
+        { ISigilBundle.class };
+
+
+    /* (non-Javadoc)
+     * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
+     */
+    @SuppressWarnings("unchecked")
+    public Object getAdapter( Object adaptableObject, Class adapterType )
+    {
         Object adapted = null;
-        
-        IFile file = (IFile) adaptableObject;
-        
-        if ( ISigilBundle.class.equals( adapterType ) ) {
-        	adapted = adaptBundle(file);
+
+        IFile file = ( IFile ) adaptableObject;
+
+        if ( ISigilBundle.class.equals( adapterType ) )
+        {
+            adapted = adaptBundle( file );
         }
-		
-		return adapted;
-	}
-    
-    private Object adaptBundle(IFile file) {
+
+        return adapted;
+    }
+
+
+    private Object adaptBundle( IFile file )
+    {
         Object adapted = null;
         IProject project = file.getProject();
-        try {
-            if ( SigilCore.hasProjectNature( project ) ) {
+        try
+        {
+            if ( SigilCore.hasProjectNature( project ) )
+            {
                 ISigilProjectModel sigil = SigilCore.create( project );
                 ISigilBundle bundle = ModelElementFactory.getInstance().newModelElement( ISigilBundle.class );
                 bundle.setParent( sigil );
                 adapted = bundle;
             }
         }
-        catch ( CoreException e ) {
-			SigilCore.error( "Failed to construct bundle", e );
-        } catch (ModelElementFactoryException e) {
-			SigilCore.error( "Failed to construct bundle", e );
-		}
-        
-        return adapted;
-	}
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Failed to construct bundle", e );
+        }
+        catch ( ModelElementFactoryException e )
+        {
+            SigilCore.error( "Failed to construct bundle", e );
+        }
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
-	 */
-	@SuppressWarnings("unchecked")
-	public Class[] getAdapterList() {
-		return types;
-	}
+        return adapted;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
+     */
+    @SuppressWarnings("unchecked")
+    public Class[] getAdapterList()
+    {
+        return types;
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/adapter/ProjectAdaptorFactory.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/adapter/ProjectAdaptorFactory.java
index d6a3543..0bb9f7e 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/adapter/ProjectAdaptorFactory.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/adapter/ProjectAdaptorFactory.java
@@ -19,53 +19,68 @@
 
 package org.apache.felix.sigil.eclipse.internal.adapter;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IAdapterFactory;
 
+
 /**
  * @author savage
  *
  */
-public class ProjectAdaptorFactory implements IAdapterFactory {
+public class ProjectAdaptorFactory implements IAdapterFactory
+{
 
-	private Class<?>[] types = new Class<?>[] { ISigilProjectModel.class };
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
-	 */
-	@SuppressWarnings("unchecked")
-	public Object getAdapter( Object adaptableObject, Class adapterType ) {
+    private Class<?>[] types = new Class<?>[]
+        { ISigilProjectModel.class };
+
+
+    /* (non-Javadoc)
+     * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
+     */
+    @SuppressWarnings("unchecked")
+    public Object getAdapter( Object adaptableObject, Class adapterType )
+    {
         Object adapted = null;
-        
-        IProject project = (IProject) adaptableObject;
-        
-		if ( ISigilProjectModel.class.equals( adapterType ) ) {
-			adapted = adaptProject(project);
-		}
-		
-		return adapted;
-	}
-    
-    private Object adaptProject(IProject project) {
-    	try {
-			if ( SigilCore.isSigilProject(project) ) {
-				return SigilCore.create(project);
-			}
-		} catch (CoreException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-		return null;
-	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
-	 */
-	@SuppressWarnings("unchecked")
-	public Class[] getAdapterList() {
-		return types;
-	}
+        IProject project = ( IProject ) adaptableObject;
+
+        if ( ISigilProjectModel.class.equals( adapterType ) )
+        {
+            adapted = adaptProject( project );
+        }
+
+        return adapted;
+    }
+
+
+    private Object adaptProject( IProject project )
+    {
+        try
+        {
+            if ( SigilCore.isSigilProject( project ) )
+            {
+                return SigilCore.create( project );
+            }
+        }
+        catch ( CoreException e )
+        {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
+     */
+    @SuppressWarnings("unchecked")
+    public Class[] getAdapterList()
+    {
+        return types;
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/builders/BuildConsole.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/builders/BuildConsole.java
index bd96066..34eae26 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/builders/BuildConsole.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/builders/BuildConsole.java
@@ -19,24 +19,32 @@
 
 package org.apache.felix.sigil.eclipse.internal.builders;
 
+
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.ui.console.MessageConsole;
 import org.eclipse.ui.console.MessageConsoleStream;
 
-public class BuildConsole extends MessageConsole {
 
-	private static final ImageDescriptor imageDescriptor = null;
-	private MessageConsoleStream stream;
+public class BuildConsole extends MessageConsole
+{
 
-	public BuildConsole() {
-		super("Sigil Build", imageDescriptor, true);
-	}
+    private static final ImageDescriptor imageDescriptor = null;
+    private MessageConsoleStream stream;
 
-	public synchronized MessageConsoleStream getMessageStream() {
-		if ( stream == null ) {
-			stream = newMessageStream();
-		}
-		return stream;
-	}
+
+    public BuildConsole()
+    {
+        super( "Sigil Build", imageDescriptor, true );
+    }
+
+
+    public synchronized MessageConsoleStream getMessageStream()
+    {
+        if ( stream == null )
+        {
+            stream = newMessageStream();
+        }
+        return stream;
+    }
 
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/builders/SigilIncrementalProjectBuilder.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/builders/SigilIncrementalProjectBuilder.java
index d2b2fa9..09451d0 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/builders/SigilIncrementalProjectBuilder.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/builders/SigilIncrementalProjectBuilder.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.internal.builders;
 
+
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -51,261 +52,334 @@
 import org.eclipse.ui.console.IConsoleManager;
 import org.eclipse.ui.console.MessageConsoleStream;
 
-public class SigilIncrementalProjectBuilder extends IncrementalProjectBuilder {
 
-	@Override
-	protected IProject[] build(int kind, @SuppressWarnings("unchecked")Map args, IProgressMonitor monitor)
-			throws CoreException {
-		IProject project = getProject();
-		
-		if ( checkOk( project ) ) {
-			switch ( kind ) {
-			case CLEAN_BUILD:
-			case FULL_BUILD:
-				fullBuild( project, monitor );
-				break;
-			case AUTO_BUILD:
-			case INCREMENTAL_BUILD:
-				autoBuild( project, monitor );
-				break;
-			}
-		}
-        
-		return null;
-	}
+public class SigilIncrementalProjectBuilder extends IncrementalProjectBuilder
+{
+
+    @Override
+    protected IProject[] build( int kind, @SuppressWarnings("unchecked") Map args, IProgressMonitor monitor )
+        throws CoreException
+    {
+        IProject project = getProject();
+
+        if ( checkOk( project ) )
+        {
+            switch ( kind )
+            {
+                case CLEAN_BUILD:
+                case FULL_BUILD:
+                    fullBuild( project, monitor );
+                    break;
+                case AUTO_BUILD:
+                case INCREMENTAL_BUILD:
+                    autoBuild( project, monitor );
+                    break;
+            }
+        }
+
+        return null;
+    }
+
 
     /**
-	 * @param install
-	 * @param project
-	 * @param monitor
+     * @param install
+     * @param project
+     * @param monitor
      * @throws CoreException 
-	 */
-	private void autoBuild(IProject project,
-			IProgressMonitor monitor) throws CoreException {
-		IResourceDelta delta = getDelta(project);
-		final boolean[] changed = new boolean[1];
-		ISigilProjectModel sigil = SigilCore.create(project);
-		final IPath bldRoot = sigil.findBundleLocation().removeLastSegments(1);
-		
-		delta.accept(new IResourceDeltaVisitor() {
-			public boolean visit(IResourceDelta delta) throws CoreException {
-				if ( !changed[0] ) {
-					IResource res = delta.getResource();
-					if ( res.getType() == IResource.FILE ) {
-						changed[0] = !bldRoot.isPrefixOf(res.getLocation());
-					}
-				}
-				return !changed[0];
-			}			
-		});
-		
-		if ( changed[0] ) {
-			doBuild(project, monitor);
-		}
-	}
+     */
+    private void autoBuild( IProject project, IProgressMonitor monitor ) throws CoreException
+    {
+        IResourceDelta delta = getDelta( project );
+        final boolean[] changed = new boolean[1];
+        ISigilProjectModel sigil = SigilCore.create( project );
+        final IPath bldRoot = sigil.findBundleLocation().removeLastSegments( 1 );
 
-	/**
-	 * @param install
-	 * @param project
-	 * @param monitor
-	 * @throws CoreException 
-	 */
-	private void fullBuild(IProject project,
-			IProgressMonitor monitor) throws CoreException {
-		doBuild(project, monitor);
-	}
+        delta.accept( new IResourceDeltaVisitor()
+        {
+            public boolean visit( IResourceDelta delta ) throws CoreException
+            {
+                if ( !changed[0] )
+                {
+                    IResource res = delta.getResource();
+                    if ( res.getType() == IResource.FILE )
+                    {
+                        changed[0] = !bldRoot.isPrefixOf( res.getLocation() );
+                    }
+                }
+                return !changed[0];
+            }
+        } );
 
-	private boolean checkOk(IProject project) throws CoreException {
-		IMarker[] markers = project.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
-		
-		for ( IMarker m : markers ) {
-			Integer s = (Integer) m.getAttribute(IMarker.SEVERITY);
-			if ( s != null && s.equals( IMarker.SEVERITY_ERROR ) ) {
-				SigilCore.log( "Skipping " + project.getName() + " build due to unresolved errors" );
-				return false;
-			}
-		}
-		
-		return true;
-	}
+        if ( changed[0] )
+        {
+            doBuild( project, monitor );
+        }
+    }
 
-	private void doBuild(IProject project, IProgressMonitor monitor ) throws CoreException {
-		ISigilProjectModel sigil = SigilCore.create(project);
-		IBldProject bld = sigil.getBldProject();
 
-		File[] classpath = buildClasspath(sigil, monitor);
-		
-		String destPattern = buildDestPattern(sigil);
-		
-		Properties env = new Properties();
-		
-		BundleBuilder bb = new BundleBuilder(bld, classpath, destPattern, env);
+    /**
+     * @param install
+     * @param project
+     * @param monitor
+     * @throws CoreException 
+     */
+    private void fullBuild( IProject project, IProgressMonitor monitor ) throws CoreException
+    {
+        doBuild( project, monitor );
+    }
 
-    	for (IBldProject.IBldBundle bundle : bld.getBundles()) {
-    		String id = bundle.getId();
-    		loginfo("creating bundle: " + id);
-    		int nWarn = 0;
-    		int nErr = 0;
-    		String msg = "";
 
-    		try {
-    			boolean modified = bb.createBundle(bundle, false, new BundleBuilder.Log() {
-    				public void warn(String msg) {
-    					logwarn(msg);
-    				}
-    				public void verbose(String msg) {
-    					loginfo(msg);
-    				}
-    			});
-    			nWarn = bb.warnings().size();
-    			if (!modified) {
-    				msg = " (not modified)";
-    			}
-    		} catch (Exception e) {
-    			List<String> errors = bb.errors();
-    			if (errors != null) {
-    				nErr = errors.size();
-    				for (String err : errors) {
-    					logerror(err);
-    				}
-    			}
-    			throw SigilCore.newCoreException("Failed to create: " + id + ": " + e, e);
-    		} finally {
-    			loginfo(id + ": " + count(nErr, "error") + ", " + count(nWarn, "warning") + msg);
-    		}
-    	}
-	}
-    
-	private static void loginfo(String message) {
-		BuildConsole console = findConsole();
-		MessageConsoleStream stream = console.getMessageStream();
-		stream.println("INFO: " + message);
-	}
+    private boolean checkOk( IProject project ) throws CoreException
+    {
+        IMarker[] markers = project.findMarkers( IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true,
+            IResource.DEPTH_INFINITE );
 
-	private static void logwarn(String message) {
-		BuildConsole console = findConsole();
-		MessageConsoleStream stream = console.getMessageStream();
-		stream.println("WARN: " + message);
-	}
-	
-	private static void logerror(String message) {
-		BuildConsole console = findConsole();
-		MessageConsoleStream stream = console.getMessageStream();
-		stream.println("ERROR: " + message);
-	}
-	
-	private static BuildConsole findConsole() {
-		BuildConsole console = null;
-		
+        for ( IMarker m : markers )
+        {
+            Integer s = ( Integer ) m.getAttribute( IMarker.SEVERITY );
+            if ( s != null && s.equals( IMarker.SEVERITY_ERROR ) )
+            {
+                SigilCore.log( "Skipping " + project.getName() + " build due to unresolved errors" );
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+
+    private void doBuild( IProject project, IProgressMonitor monitor ) throws CoreException
+    {
+        ISigilProjectModel sigil = SigilCore.create( project );
+        IBldProject bld = sigil.getBldProject();
+
+        File[] classpath = buildClasspath( sigil, monitor );
+
+        String destPattern = buildDestPattern( sigil );
+
+        Properties env = new Properties();
+
+        BundleBuilder bb = new BundleBuilder( bld, classpath, destPattern, env );
+
+        for ( IBldProject.IBldBundle bundle : bld.getBundles() )
+        {
+            String id = bundle.getId();
+            loginfo( "creating bundle: " + id );
+            int nWarn = 0;
+            int nErr = 0;
+            String msg = "";
+
+            try
+            {
+                boolean modified = bb.createBundle( bundle, false, new BundleBuilder.Log()
+                {
+                    public void warn( String msg )
+                    {
+                        logwarn( msg );
+                    }
+
+
+                    public void verbose( String msg )
+                    {
+                        loginfo( msg );
+                    }
+                } );
+                nWarn = bb.warnings().size();
+                if ( !modified )
+                {
+                    msg = " (not modified)";
+                }
+            }
+            catch ( Exception e )
+            {
+                List<String> errors = bb.errors();
+                if ( errors != null )
+                {
+                    nErr = errors.size();
+                    for ( String err : errors )
+                    {
+                        logerror( err );
+                    }
+                }
+                throw SigilCore.newCoreException( "Failed to create: " + id + ": " + e, e );
+            }
+            finally
+            {
+                loginfo( id + ": " + count( nErr, "error" ) + ", " + count( nWarn, "warning" ) + msg );
+            }
+        }
+    }
+
+
+    private static void loginfo( String message )
+    {
+        BuildConsole console = findConsole();
+        MessageConsoleStream stream = console.getMessageStream();
+        stream.println( "INFO: " + message );
+    }
+
+
+    private static void logwarn( String message )
+    {
+        BuildConsole console = findConsole();
+        MessageConsoleStream stream = console.getMessageStream();
+        stream.println( "WARN: " + message );
+    }
+
+
+    private static void logerror( String message )
+    {
+        BuildConsole console = findConsole();
+        MessageConsoleStream stream = console.getMessageStream();
+        stream.println( "ERROR: " + message );
+    }
+
+
+    private static BuildConsole findConsole()
+    {
+        BuildConsole console = null;
+
         IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
-        
-        for ( IConsole c : manager.getConsoles() ) {
-        	if ( c instanceof BuildConsole ) {
-        		console = (BuildConsole) c;
-        		break;
-        	}
+
+        for ( IConsole c : manager.getConsoles() )
+        {
+            if ( c instanceof BuildConsole )
+            {
+                console = ( BuildConsole ) c;
+                break;
+            }
         }
-        
-        if ( console == null ) {
-        	console = new BuildConsole();
-        	manager.addConsoles( new IConsole[] { console } );
+
+        if ( console == null )
+        {
+            console = new BuildConsole();
+            manager.addConsoles( new IConsole[]
+                { console } );
         }
-        
+
         return console;
-	}
+    }
 
-	private String buildDestPattern(ISigilProjectModel sigil) throws CoreException {
-		IPath loc = sigil.findBundleLocation().removeLastSegments(1);
-		
-		loc.toFile().mkdirs();
-		
-		return loc.toOSString() + File.separator + "[name].jar";
-	}
 
-	private File[] buildClasspath(ISigilProjectModel sigil, IProgressMonitor monitor) throws CoreException {
-		ArrayList<File> files = new ArrayList<File>();
-		
-		buildLocalClasspath(sigil, files);
-		buildExternalClasspath(sigil, files, monitor);
-			
-		return files.toArray( new File[files.size()] );
-	}
+    private String buildDestPattern( ISigilProjectModel sigil ) throws CoreException
+    {
+        IPath loc = sigil.findBundleLocation().removeLastSegments( 1 );
 
-	private void buildExternalClasspath(ISigilProjectModel sigil,
-			ArrayList<File> files, IProgressMonitor monitor) throws CoreException {
-		Collection<IClasspathEntry> entries = sigil.findExternalClasspath(monitor);
-		files.ensureCapacity(files.size() + entries.size());
-		
-		for ( IClasspathEntry cp : entries ) {
-			convert(cp, sigil, files);
-		}
-	}
+        loc.toFile().mkdirs();
 
-	private void buildLocalClasspath(ISigilProjectModel sigil, ArrayList<File> files) throws CoreException {
-		Collection<IClasspathEntry> entries = JavaHelper.findClasspathEntries(sigil.getBundle());
-		files.ensureCapacity(files.size() + entries.size());
-		for ( IClasspathEntry cp : entries ) {
-			convert(cp, sigil, files);
-		}
-		
-		if ( !sigil.getBundle().getComposites().isEmpty() ) {
-			throw new IllegalStateException("XXX-FIXME-XXX");
-		}
-	}
+        return loc.toOSString() + File.separator + "[name].jar";
+    }
 
-	private void convert(IClasspathEntry cp, ISigilProjectModel sigil, ArrayList<File> files) throws CoreException {
-		switch( cp.getEntryKind() ) {
-		case IClasspathEntry.CPE_PROJECT: {
-			IProject p = findProject(cp.getPath());
-			ISigilProjectModel project = SigilCore.create(p);
-			for ( String scp : project.getBundle().getClasspathEntrys() ) {
-				IClasspathEntry jcp = project.getJavaModel().decodeClasspathEntry(scp);
-				convert( jcp, project, files );
-			}
-			break;
-		}
-		case IClasspathEntry.CPE_SOURCE : {
-			IPath path = cp.getOutputLocation() == null ? sigil.getJavaModel().getOutputLocation() : cp.getOutputLocation();
-			IFolder buildFolder = sigil.getProject().getFolder(path.removeFirstSegments(1));
-			if ( buildFolder.exists() ) {
-				files.add(buildFolder.getLocation().toFile());
-			}
-			break;
-		}
-		case IClasspathEntry.CPE_LIBRARY: {
-			IPath p = cp.getPath();
-			
-			IProject project = sigil.getProject().getWorkspace().getRoot().getProject(p.segment(0));
-			if ( project.exists() ) {
-				p = project.getLocation().append( p.removeFirstSegments(1) );
-			}				
-			
-			files.add( p.toFile() );
-			break;
-		}
-		case IClasspathEntry.CPE_VARIABLE:
-			cp = JavaCore.getResolvedClasspathEntry(cp);
-			if ( cp != null ) {
-				IPath p = cp.getPath();
-				files.add( p.toFile() );
-			}
-			break;
-		}
-	}
 
-	private IProject findProject(IPath path) throws CoreException {
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-		for ( IProject p : root.getProjects() ) {
-			IPath projectPath = p.getFullPath();
-			if ( projectPath.equals( path ) ) {
-				return p;
-			}
-		}
-		
-		throw SigilCore.newCoreException("No such project " + path, null);
-	}
+    private File[] buildClasspath( ISigilProjectModel sigil, IProgressMonitor monitor ) throws CoreException
+    {
+        ArrayList<File> files = new ArrayList<File>();
 
-	private String count(int count, String msg) {
-		return count + " " + msg + (count == 1 ? "" : "s");
-	}
+        buildLocalClasspath( sigil, files );
+        buildExternalClasspath( sigil, files, monitor );
+
+        return files.toArray( new File[files.size()] );
+    }
+
+
+    private void buildExternalClasspath( ISigilProjectModel sigil, ArrayList<File> files, IProgressMonitor monitor )
+        throws CoreException
+    {
+        Collection<IClasspathEntry> entries = sigil.findExternalClasspath( monitor );
+        files.ensureCapacity( files.size() + entries.size() );
+
+        for ( IClasspathEntry cp : entries )
+        {
+            convert( cp, sigil, files );
+        }
+    }
+
+
+    private void buildLocalClasspath( ISigilProjectModel sigil, ArrayList<File> files ) throws CoreException
+    {
+        Collection<IClasspathEntry> entries = JavaHelper.findClasspathEntries( sigil.getBundle() );
+        files.ensureCapacity( files.size() + entries.size() );
+        for ( IClasspathEntry cp : entries )
+        {
+            convert( cp, sigil, files );
+        }
+
+        if ( !sigil.getBundle().getComposites().isEmpty() )
+        {
+            throw new IllegalStateException( "XXX-FIXME-XXX" );
+        }
+    }
+
+
+    private void convert( IClasspathEntry cp, ISigilProjectModel sigil, ArrayList<File> files ) throws CoreException
+    {
+        switch ( cp.getEntryKind() )
+        {
+            case IClasspathEntry.CPE_PROJECT:
+            {
+                IProject p = findProject( cp.getPath() );
+                ISigilProjectModel project = SigilCore.create( p );
+                for ( String scp : project.getBundle().getClasspathEntrys() )
+                {
+                    IClasspathEntry jcp = project.getJavaModel().decodeClasspathEntry( scp );
+                    convert( jcp, project, files );
+                }
+                break;
+            }
+            case IClasspathEntry.CPE_SOURCE:
+            {
+                IPath path = cp.getOutputLocation() == null ? sigil.getJavaModel().getOutputLocation() : cp
+                    .getOutputLocation();
+                IFolder buildFolder = sigil.getProject().getFolder( path.removeFirstSegments( 1 ) );
+                if ( buildFolder.exists() )
+                {
+                    files.add( buildFolder.getLocation().toFile() );
+                }
+                break;
+            }
+            case IClasspathEntry.CPE_LIBRARY:
+            {
+                IPath p = cp.getPath();
+
+                IProject project = sigil.getProject().getWorkspace().getRoot().getProject( p.segment( 0 ) );
+                if ( project.exists() )
+                {
+                    p = project.getLocation().append( p.removeFirstSegments( 1 ) );
+                }
+
+                files.add( p.toFile() );
+                break;
+            }
+            case IClasspathEntry.CPE_VARIABLE:
+                cp = JavaCore.getResolvedClasspathEntry( cp );
+                if ( cp != null )
+                {
+                    IPath p = cp.getPath();
+                    files.add( p.toFile() );
+                }
+                break;
+        }
+    }
+
+
+    private IProject findProject( IPath path ) throws CoreException
+    {
+        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+        for ( IProject p : root.getProjects() )
+        {
+            IPath projectPath = p.getFullPath();
+            if ( projectPath.equals( path ) )
+            {
+                return p;
+            }
+        }
+
+        throw SigilCore.newCoreException( "No such project " + path, null );
+    }
+
+
+    private String count( int count, String msg )
+    {
+        return count + " " + msg + ( count == 1 ? "" : "s" );
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/install/OSGiInstallManager.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/install/OSGiInstallManager.java
index 98bc195..40748c6 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/install/OSGiInstallManager.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/install/OSGiInstallManager.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.internal.install;
 
+
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
@@ -48,220 +49,296 @@
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.dialogs.PreferencesUtil;
 
-public class OSGiInstallManager implements IOSGiInstallManager, IPropertyChangeListener {
-	private static final int NORMAL_PRIORITY = 0;
-	
-	private LinkedList<IOSGiInstallBuilder> builders = new LinkedList<IOSGiInstallBuilder>();
 
-	private HashMap<IPath, IOSGiInstall> pathToinstall = new HashMap<IPath, IOSGiInstall>();
-	private HashMap<String, IOSGiInstall> idToInstall = new HashMap<String, IOSGiInstall>();
-	
-	private String defaultId;
-	
-	private boolean initialised;
-		
-	public IOSGiInstall findInstall(String id) {
-		init();
-		return idToInstall.get(id);
-	}
+public class OSGiInstallManager implements IOSGiInstallManager, IPropertyChangeListener
+{
+    private static final int NORMAL_PRIORITY = 0;
 
-	public String[] getInstallIDs() {
-		init();
-		return idToInstall.keySet().toArray( new String[idToInstall.size()] );
-	}
+    private LinkedList<IOSGiInstallBuilder> builders = new LinkedList<IOSGiInstallBuilder>();
 
-	public IOSGiInstall[] getInstalls() {
-		init();
-		return idToInstall.values().toArray( new IOSGiInstall[idToInstall.size()] );
-	}
+    private HashMap<IPath, IOSGiInstall> pathToinstall = new HashMap<IPath, IOSGiInstall>();
+    private HashMap<String, IOSGiInstall> idToInstall = new HashMap<String, IOSGiInstall>();
 
-	public IOSGiInstall getDefaultInstall() {
-		init();
-		return findInstall(defaultId);
-	}
+    private String defaultId;
 
-	public IOSGiInstallType findInstallType(String location) {
-		IOSGiInstallType type = null;
-		
-		try {
-			IOSGiInstall install = buildInstall("tmp", new Path( location ) );
-			type = install == null ? null : install.getType();
-		} catch (CoreException e) {
-			SigilCore.error( "Failed to build install", e);
-		}
-		
-		return type;
-	}
-	
-	public void propertyChange(PropertyChangeEvent event) {
-		synchronized( this ) {
-			if ( event.getProperty().equals(SigilCore.OSGI_INSTALLS) ) {
-				clearInstalls();
-				String val = (String) event.getNewValue();
-				addInstalls(val);
-			}
-			else if ( event.getProperty().equals( SigilCore.OSGI_DEFAULT_INSTALL_ID ) ) {
-				defaultId = (String) event.getNewValue();
-			}
-		}
-	}
+    private boolean initialised;
 
-	private void init() {
-		boolean show = false;
-		
-		IPreferenceStore prefs = getPreferenceStore(); 
-		
-		synchronized( this ) {
-			if ( !initialised ) {
-				initialised = true;
-				
-				prefs.addPropertyChangeListener(this);
-				
-				String val = prefs.getString(SigilCore.OSGI_INSTALLS);
-				
-				boolean noAsk = prefs.getBoolean(SigilCore.PREFERENCES_NOASK_OSGI_INSTALL);
-				if(val == null || val.trim().length() == 0) {
-					show = !noAsk;
-				}
-				else {
-					addInstalls(val);
-					defaultId = prefs.getString(SigilCore.OSGI_DEFAULT_INSTALL_ID);
-				}
-			}
-		}
-		
-		if ( show ) {
-			showInstallPrefs(prefs);
-		}		
-	}
-	
-	private void addInstalls(String prop) {
-		if ( prop != null && prop.trim().length() > 0 ) {
-			IPreferenceStore prefs = getPreferenceStore();
-			
-			for (String id : prop.split(",")) {
-				String path = prefs.getString( SigilCore.OSGI_INSTALL_PREFIX + id );
-				addInstall(id, new Path( path ) );
-			}
-		}				
-	}
 
-	private IPreferenceStore getPreferenceStore() {
-		return SigilCore.getDefault().getPreferenceStore();
-	}
+    public IOSGiInstall findInstall( String id )
+    {
+        init();
+        return idToInstall.get( id );
+    }
 
-	private void showInstallPrefs(final IPreferenceStore prefs) {
-		Runnable r = new Runnable() {
-			public void run() {
-				MessageDialogWithToggle questionDialog = MessageDialogWithToggle.openYesNoQuestion(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Sigil Configuration", "Missing OSGi installation. Open preferences to configure it now?", "Do not show this message again", false, null, null);
-				prefs.setValue(SigilCore.PREFERENCES_NOASK_OSGI_INSTALL, questionDialog.getToggleState());
-				if(questionDialog.getReturnCode() == IDialogConstants.YES_ID) {
-					PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn(null, SigilCore.OSGI_INSTALLS_PREFERENCES_ID, null, null);
-					dialog.open();
-				}
-			}
-		};
-		Display d = Display.getCurrent();
-		if ( d == null ) {
-			d = Display.getDefault();
-			d.asyncExec(r);
-		}
-		else {
-			d.syncExec(r);
-		}
-	}
 
-	private IOSGiInstall addInstall(String id, IPath path) {
-		IOSGiInstall install = pathToinstall.get(path);
-		
-		if ( install == null ) {
-			try {
-				install = buildInstall(id, path);
-				if ( install != null ) {
-					pathToinstall.put( path, install );
-					idToInstall.put( install.getId(), install );
-				}
-			}
-			catch (CoreException e) {
-				SigilCore.error( "Failed to build install for " + path, e);
-			}
-		}
-		
-		return install;
-	}
-	
-	private IOSGiInstall buildInstall(String id, IPath path) throws CoreException {
-		initBuilders();
-		IOSGiInstall install = null;
-		
-		for ( IOSGiInstallBuilder b : builders ) {
-			install = b.build(id, path);
+    public String[] getInstallIDs()
+    {
+        init();
+        return idToInstall.keySet().toArray( new String[idToInstall.size()] );
+    }
 
-			if ( install != null ) {
-				break;
-			}
-		}
-		
-		return install;
-	}
 
-	private void clearInstalls() {
-		idToInstall.clear();
-		pathToinstall.clear();
-	}
+    public IOSGiInstall[] getInstalls()
+    {
+        init();
+        return idToInstall.values().toArray( new IOSGiInstall[idToInstall.size()] );
+    }
 
-	private void initBuilders() {
-		synchronized( builders ) {
-			if ( builders.isEmpty() ) {
-				final HashMap<IOSGiInstallBuilder, Integer> tmp = new HashMap<IOSGiInstallBuilder, Integer>();
-				
-				IExtensionRegistry registry = Platform.getExtensionRegistry();
-				IExtensionPoint p = registry.getExtensionPoint(SigilCore.INSTALL_BUILDER_EXTENSION_POINT_ID);
-				for ( IExtension e : p.getExtensions() ) {
-					for ( IConfigurationElement c : e.getConfigurationElements() ) {
-						createBuilderFromElement(c, tmp);
-					}
-				}
-				
-				builders = new LinkedList<IOSGiInstallBuilder>(tmp.keySet());
-				Collections.sort(builders, new Comparator<IOSGiInstallBuilder>() {
-					public int compare(IOSGiInstallBuilder o1, IOSGiInstallBuilder o2) {
-						int p1 = tmp.get(o1);
-						int p2 = tmp.get(o2);
-						
-						if ( p1 == p2 ) {
-							return 0;
-						}
-						else if ( p1 > p2 ) {
-							return -1;
-						}
-						else {
-							return 1;
-						}
-					}
-				});
-			}
-		}
-	}
 
-	private void createBuilderFromElement(IConfigurationElement c, Map<IOSGiInstallBuilder, Integer> builder) {
-		try {
-			IOSGiInstallBuilder b = (IOSGiInstallBuilder) c.createExecutableExtension("class");
-			int priority = parsePriority( c );
-			builder.put(b, priority);
-		} catch (CoreException e) {
-			SigilCore.error("Failed to create builder", e);
-		}
-	}
-	
-	private int parsePriority(IConfigurationElement c) {
-		String str = c.getAttribute("priority");
-		
-		if ( str == null ) {
-			return NORMAL_PRIORITY;
-		}
-		else {
-			return Integer.parseInt(str);
-		}
-	}
+    public IOSGiInstall getDefaultInstall()
+    {
+        init();
+        return findInstall( defaultId );
+    }
+
+
+    public IOSGiInstallType findInstallType( String location )
+    {
+        IOSGiInstallType type = null;
+
+        try
+        {
+            IOSGiInstall install = buildInstall( "tmp", new Path( location ) );
+            type = install == null ? null : install.getType();
+        }
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Failed to build install", e );
+        }
+
+        return type;
+    }
+
+
+    public void propertyChange( PropertyChangeEvent event )
+    {
+        synchronized ( this )
+        {
+            if ( event.getProperty().equals( SigilCore.OSGI_INSTALLS ) )
+            {
+                clearInstalls();
+                String val = ( String ) event.getNewValue();
+                addInstalls( val );
+            }
+            else if ( event.getProperty().equals( SigilCore.OSGI_DEFAULT_INSTALL_ID ) )
+            {
+                defaultId = ( String ) event.getNewValue();
+            }
+        }
+    }
+
+
+    private void init()
+    {
+        boolean show = false;
+
+        IPreferenceStore prefs = getPreferenceStore();
+
+        synchronized ( this )
+        {
+            if ( !initialised )
+            {
+                initialised = true;
+
+                prefs.addPropertyChangeListener( this );
+
+                String val = prefs.getString( SigilCore.OSGI_INSTALLS );
+
+                boolean noAsk = prefs.getBoolean( SigilCore.PREFERENCES_NOASK_OSGI_INSTALL );
+                if ( val == null || val.trim().length() == 0 )
+                {
+                    show = !noAsk;
+                }
+                else
+                {
+                    addInstalls( val );
+                    defaultId = prefs.getString( SigilCore.OSGI_DEFAULT_INSTALL_ID );
+                }
+            }
+        }
+
+        if ( show )
+        {
+            showInstallPrefs( prefs );
+        }
+    }
+
+
+    private void addInstalls( String prop )
+    {
+        if ( prop != null && prop.trim().length() > 0 )
+        {
+            IPreferenceStore prefs = getPreferenceStore();
+
+            for ( String id : prop.split( "," ) )
+            {
+                String path = prefs.getString( SigilCore.OSGI_INSTALL_PREFIX + id );
+                addInstall( id, new Path( path ) );
+            }
+        }
+    }
+
+
+    private IPreferenceStore getPreferenceStore()
+    {
+        return SigilCore.getDefault().getPreferenceStore();
+    }
+
+
+    private void showInstallPrefs( final IPreferenceStore prefs )
+    {
+        Runnable r = new Runnable()
+        {
+            public void run()
+            {
+                MessageDialogWithToggle questionDialog = MessageDialogWithToggle.openYesNoQuestion( PlatformUI
+                    .getWorkbench().getActiveWorkbenchWindow().getShell(), "Sigil Configuration",
+                    "Missing OSGi installation. Open preferences to configure it now?",
+                    "Do not show this message again", false, null, null );
+                prefs.setValue( SigilCore.PREFERENCES_NOASK_OSGI_INSTALL, questionDialog.getToggleState() );
+                if ( questionDialog.getReturnCode() == IDialogConstants.YES_ID )
+                {
+                    PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn( null,
+                        SigilCore.OSGI_INSTALLS_PREFERENCES_ID, null, null );
+                    dialog.open();
+                }
+            }
+        };
+        Display d = Display.getCurrent();
+        if ( d == null )
+        {
+            d = Display.getDefault();
+            d.asyncExec( r );
+        }
+        else
+        {
+            d.syncExec( r );
+        }
+    }
+
+
+    private IOSGiInstall addInstall( String id, IPath path )
+    {
+        IOSGiInstall install = pathToinstall.get( path );
+
+        if ( install == null )
+        {
+            try
+            {
+                install = buildInstall( id, path );
+                if ( install != null )
+                {
+                    pathToinstall.put( path, install );
+                    idToInstall.put( install.getId(), install );
+                }
+            }
+            catch ( CoreException e )
+            {
+                SigilCore.error( "Failed to build install for " + path, e );
+            }
+        }
+
+        return install;
+    }
+
+
+    private IOSGiInstall buildInstall( String id, IPath path ) throws CoreException
+    {
+        initBuilders();
+        IOSGiInstall install = null;
+
+        for ( IOSGiInstallBuilder b : builders )
+        {
+            install = b.build( id, path );
+
+            if ( install != null )
+            {
+                break;
+            }
+        }
+
+        return install;
+    }
+
+
+    private void clearInstalls()
+    {
+        idToInstall.clear();
+        pathToinstall.clear();
+    }
+
+
+    private void initBuilders()
+    {
+        synchronized ( builders )
+        {
+            if ( builders.isEmpty() )
+            {
+                final HashMap<IOSGiInstallBuilder, Integer> tmp = new HashMap<IOSGiInstallBuilder, Integer>();
+
+                IExtensionRegistry registry = Platform.getExtensionRegistry();
+                IExtensionPoint p = registry.getExtensionPoint( SigilCore.INSTALL_BUILDER_EXTENSION_POINT_ID );
+                for ( IExtension e : p.getExtensions() )
+                {
+                    for ( IConfigurationElement c : e.getConfigurationElements() )
+                    {
+                        createBuilderFromElement( c, tmp );
+                    }
+                }
+
+                builders = new LinkedList<IOSGiInstallBuilder>( tmp.keySet() );
+                Collections.sort( builders, new Comparator<IOSGiInstallBuilder>()
+                {
+                    public int compare( IOSGiInstallBuilder o1, IOSGiInstallBuilder o2 )
+                    {
+                        int p1 = tmp.get( o1 );
+                        int p2 = tmp.get( o2 );
+
+                        if ( p1 == p2 )
+                        {
+                            return 0;
+                        }
+                        else if ( p1 > p2 )
+                        {
+                            return -1;
+                        }
+                        else
+                        {
+                            return 1;
+                        }
+                    }
+                } );
+            }
+        }
+    }
+
+
+    private void createBuilderFromElement( IConfigurationElement c, Map<IOSGiInstallBuilder, Integer> builder )
+    {
+        try
+        {
+            IOSGiInstallBuilder b = ( IOSGiInstallBuilder ) c.createExecutableExtension( "class" );
+            int priority = parsePriority( c );
+            builder.put( b, priority );
+        }
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Failed to create builder", e );
+        }
+    }
+
+
+    private int parsePriority( IConfigurationElement c )
+    {
+        String str = c.getAttribute( "priority" );
+
+        if ( str == null )
+        {
+            return NORMAL_PRIORITY;
+        }
+        else
+        {
+            return Integer.parseInt( str );
+        }
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilModelRoot.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilModelRoot.java
index 050ce1f..c521808 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilModelRoot.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilModelRoot.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.internal.model.project;
 
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
@@ -44,83 +45,109 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 
-public class SigilModelRoot implements ISigilModelRoot {
-	public List<ISigilProjectModel> getProjects() {
-		IProject[] all = ResourcesPlugin.getWorkspace().getRoot().getProjects();
-		ArrayList<ISigilProjectModel> projects = new ArrayList<ISigilProjectModel>(all.length);
-		for (IProject p : all) {
-			try {
-				if (p.isOpen() && p.hasNature(SigilCore.NATURE_ID)) {
-					ISigilProjectModel n = SigilCore.create(p);
-					projects.add(n);
-				}
-			} catch (CoreException e) {
-				SigilCore.error("Failed to build model element", e);
-			}
-		}
 
-		return projects;
-	}
+public class SigilModelRoot implements ISigilModelRoot
+{
+    public List<ISigilProjectModel> getProjects()
+    {
+        IProject[] all = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+        ArrayList<ISigilProjectModel> projects = new ArrayList<ISigilProjectModel>( all.length );
+        for ( IProject p : all )
+        {
+            try
+            {
+                if ( p.isOpen() && p.hasNature( SigilCore.NATURE_ID ) )
+                {
+                    ISigilProjectModel n = SigilCore.create( p );
+                    projects.add( n );
+                }
+            }
+            catch ( CoreException e )
+            {
+                SigilCore.error( "Failed to build model element", e );
+            }
+        }
 
-	public Collection<ISigilProjectModel> resolveDependentProjects(
-			ISigilProjectModel sigil, IProgressMonitor monitor) {
-		HashSet<ISigilProjectModel> dependents = new HashSet<ISigilProjectModel>();
+        return projects;
+    }
 
-		for (ISigilProjectModel n : getProjects()) {
-			if (!sigil.equals(n)) {
-				for (IPackageExport pe : sigil.getBundle().getBundleInfo().getExports()) {
-					for (IPackageImport i : n.getBundle().getBundleInfo()
-							.getImports()) {
-						if (pe.getPackageName().equals(i.getPackageName())
-								&& i.getVersions().contains(pe.getVersion())) {
-							dependents.add(n);
-						}
-					}
 
-					for (ILibraryImport l : n.getBundle().getBundleInfo().getLibraryImports()) {
-						ILibrary lib = SigilCore.getRepositoryManager(sigil).resolveLibrary(l);
+    public Collection<ISigilProjectModel> resolveDependentProjects( ISigilProjectModel sigil, IProgressMonitor monitor )
+    {
+        HashSet<ISigilProjectModel> dependents = new HashSet<ISigilProjectModel>();
 
-						if (lib != null) {
-							for (IPackageImport i : lib.getImports()) {
-								if (pe.getPackageName().equals(
-										i.getPackageName())
-										&& i.getVersions().contains(
-												pe.getVersion())) {
-									dependents.add(n);
-								}
-							}
-						} else {
-							SigilCore.error("No library found for " + l);
-						}
-					}
-				}
+        for ( ISigilProjectModel n : getProjects() )
+        {
+            if ( !sigil.equals( n ) )
+            {
+                for ( IPackageExport pe : sigil.getBundle().getBundleInfo().getExports() )
+                {
+                    for ( IPackageImport i : n.getBundle().getBundleInfo().getImports() )
+                    {
+                        if ( pe.getPackageName().equals( i.getPackageName() )
+                            && i.getVersions().contains( pe.getVersion() ) )
+                        {
+                            dependents.add( n );
+                        }
+                    }
 
-				for (IRequiredBundle r : n.getBundle().getBundleInfo().getRequiredBundles()) {
-					if (sigil.getSymbolicName().equals(r.getSymbolicName())
-							&& r.getVersions().contains(sigil.getVersion())) {
-						dependents.add(n);
-					}
-				}
-			}
-		}
+                    for ( ILibraryImport l : n.getBundle().getBundleInfo().getLibraryImports() )
+                    {
+                        ILibrary lib = SigilCore.getRepositoryManager( sigil ).resolveLibrary( l );
 
-		return dependents;
-	}
+                        if ( lib != null )
+                        {
+                            for ( IPackageImport i : lib.getImports() )
+                            {
+                                if ( pe.getPackageName().equals( i.getPackageName() )
+                                    && i.getVersions().contains( pe.getVersion() ) )
+                                {
+                                    dependents.add( n );
+                                }
+                            }
+                        }
+                        else
+                        {
+                            SigilCore.error( "No library found for " + l );
+                        }
+                    }
+                }
 
-	public Collection<ISigilBundle> resolveBundles(ISigilProjectModel sigil, IModelElement element, boolean includeOptional, IProgressMonitor monitor) throws CoreException {
-		int options = ResolutionConfig.INCLUDE_DEPENDENTS;
-		if ( includeOptional ) {
-			options |= ResolutionConfig.INCLUDE_OPTIONAL;
-		}
-		
-		ResolutionConfig config = new ResolutionConfig(options);
-		try {
-			IBundleResolver resolver = SigilCore.getRepositoryManager(sigil).getBundleResolver();
-			IResolution resolution = resolver.resolve(element, config, new ResolutionMonitorAdapter(monitor));
-			resolution.synchronize(monitor);
-			return resolution.getBundles();
-		} catch (ResolutionException e) {
-			throw SigilCore.newCoreException(e.getMessage(), e);
-		}
-	}
+                for ( IRequiredBundle r : n.getBundle().getBundleInfo().getRequiredBundles() )
+                {
+                    if ( sigil.getSymbolicName().equals( r.getSymbolicName() )
+                        && r.getVersions().contains( sigil.getVersion() ) )
+                    {
+                        dependents.add( n );
+                    }
+                }
+            }
+        }
+
+        return dependents;
+    }
+
+
+    public Collection<ISigilBundle> resolveBundles( ISigilProjectModel sigil, IModelElement element,
+        boolean includeOptional, IProgressMonitor monitor ) throws CoreException
+    {
+        int options = ResolutionConfig.INCLUDE_DEPENDENTS;
+        if ( includeOptional )
+        {
+            options |= ResolutionConfig.INCLUDE_OPTIONAL;
+        }
+
+        ResolutionConfig config = new ResolutionConfig( options );
+        try
+        {
+            IBundleResolver resolver = SigilCore.getRepositoryManager( sigil ).getBundleResolver();
+            IResolution resolution = resolver.resolve( element, config, new ResolutionMonitorAdapter( monitor ) );
+            resolution.synchronize( monitor );
+            return resolution.getBundles();
+        }
+        catch ( ResolutionException e )
+        {
+            throw SigilCore.newCoreException( e.getMessage(), e );
+        }
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilProject.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilProject.java
index 62f6734..3050151 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilProject.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/project/SigilProject.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.internal.model.project;
 
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -71,390 +72,519 @@
 import org.osgi.framework.Version;
 import org.osgi.service.prefs.Preferences;
 
+
 /**
  * @author dave
  *
  */
-public class SigilProject extends AbstractCompoundModelElement implements ISigilProjectModel {
+public class SigilProject extends AbstractCompoundModelElement implements ISigilProjectModel
+{
 
-	private static final long serialVersionUID = 1L;
-	
-	private IFile bldProjectFile;
+    private static final long serialVersionUID = 1L;
+
+    private IFile bldProjectFile;
     private IProject project;
     private IBldProject bldProject;
-    
+
     private ISigilBundle bundle;
 
-	private IEclipsePreferences preferences;
+    private IEclipsePreferences preferences;
 
-    public SigilProject() {
-    	super( "Sigil Project" );
+
+    public SigilProject()
+    {
+        super( "Sigil Project" );
     }
-    
-    public SigilProject(IProject project) throws CoreException {
-    	this();
+
+
+    public SigilProject( IProject project ) throws CoreException
+    {
+        this();
         this.project = project;
-        bldProjectFile = project.getFile( new Path( SigilCore.SIGIL_PROJECT_FILE) );
+        bldProjectFile = project.getFile( new Path( SigilCore.SIGIL_PROJECT_FILE ) );
     }
-    
+
+
     // to aid testing conversion between project file formats
-    public InputStream saveBundle(ISigilBundle b) throws CoreException {
-    	setBundle(b);
-    	// FIXME causes NPE in JavaHelper
-    	// calculateUses();
-    	return buildContents();
+    public InputStream saveBundle( ISigilBundle b ) throws CoreException
+    {
+        setBundle( b );
+        // FIXME causes NPE in JavaHelper
+        // calculateUses();
+        return buildContents();
     }
-    
-	public void save(IProgressMonitor monitor) throws CoreException {
-		SubMonitor progress = SubMonitor.convert(monitor, 100);
-		
-    	calculateUses();
-    	
-    	bldProjectFile.setContents( buildContents(), IFile.KEEP_HISTORY, progress.newChild(10));
-    	
-		IRepositoryManager manager = SigilCore.getRepositoryManager(this);
-		ResolutionConfig config = new ResolutionConfig(ResolutionConfig.INCLUDE_OPTIONAL);
-		
-		try {
-			IResolution res = manager.getBundleResolver().resolve(this, config, new ResolutionMonitorAdapter(progress.newChild(10)));
-			if ( !res.isSynchronized() ) {
-				res.synchronize(progress.newChild(60));
-			}
-		} catch (ResolutionException e) {
-			throw SigilCore.newCoreException("Failed to synchronize dependencies", e);
-		}
-		
-		
-		progress.setWorkRemaining(40);
-		
-    	SigilCore.rebuildBundleDependencies( this, progress.newChild(20) );
+
+
+    public void save( IProgressMonitor monitor ) throws CoreException
+    {
+        SubMonitor progress = SubMonitor.convert( monitor, 100 );
+
+        calculateUses();
+
+        bldProjectFile.setContents( buildContents(), IFile.KEEP_HISTORY, progress.newChild( 10 ) );
+
+        IRepositoryManager manager = SigilCore.getRepositoryManager( this );
+        ResolutionConfig config = new ResolutionConfig( ResolutionConfig.INCLUDE_OPTIONAL );
+
+        try
+        {
+            IResolution res = manager.getBundleResolver().resolve( this, config,
+                new ResolutionMonitorAdapter( progress.newChild( 10 ) ) );
+            if ( !res.isSynchronized() )
+            {
+                res.synchronize( progress.newChild( 60 ) );
+            }
+        }
+        catch ( ResolutionException e )
+        {
+            throw SigilCore.newCoreException( "Failed to synchronize dependencies", e );
+        }
+
+        progress.setWorkRemaining( 40 );
+
+        SigilCore.rebuildBundleDependencies( this, progress.newChild( 20 ) );
     }
-	
-	/**
-	 * Returns the project custom preference pool.
-	 * Project preferences may include custom encoding.
-	 * @return IEclipsePreferences or <code>null</code> if the project
-	 * 	does not have a java nature.
-	 */
-	public Preferences getPreferences(){
-		synchronized(this) {
-			if ( preferences == null ) {
-				preferences = loadPreferences();
-			}
-			
-			return preferences;
-		}
-	}
-	
-	
-	/**
-	 * @return
-	 */
-	private synchronized IEclipsePreferences loadPreferences() {
-		IScopeContext context = new ProjectScope(getProject());
-		final IEclipsePreferences eclipsePreferences = context.getNode(SigilCore.PLUGIN_ID);
-		
-		// Listen to node removal from parent in order to reset cache
-		INodeChangeListener nodeListener = new IEclipsePreferences.INodeChangeListener() {
-			public void added(IEclipsePreferences.NodeChangeEvent event) {
-				// do nothing
-			}
-			
-			public void removed(IEclipsePreferences.NodeChangeEvent event) {
-				if (event.getChild() == eclipsePreferences) {
-					synchronized( SigilProject.this ) {
-						preferences = null;
-					}
-					((IEclipsePreferences) eclipsePreferences.parent()).removeNodeChangeListener(this);
-				}
-			}
-		};
 
-		((IEclipsePreferences) eclipsePreferences.parent()).addNodeChangeListener(nodeListener);
-		
-		return eclipsePreferences;
-	}
 
-	public Collection<IClasspathEntry> findExternalClasspath(IProgressMonitor monitor) throws CoreException {
-		return JavaHelper.resolveClasspathEntrys(this, monitor);
-	}
+    /**
+     * Returns the project custom preference pool.
+     * Project preferences may include custom encoding.
+     * @return IEclipsePreferences or <code>null</code> if the project
+     * 	does not have a java nature.
+     */
+    public Preferences getPreferences()
+    {
+        synchronized ( this )
+        {
+            if ( preferences == null )
+            {
+                preferences = loadPreferences();
+            }
 
-	private void calculateUses() {
-		visit( new IModelWalker() {
-			public boolean visit(IModelElement element) {
-				if ( element instanceof IPackageExport ) {
-					IPackageExport pe = (IPackageExport) element;
-					try {
-						pe.setUses( Arrays.asList( JavaHelper.findUses(pe.getPackageName(), SigilProject.this ) ) );
-					} catch (CoreException e) {
-						SigilCore.error( "Failed to build uses list for " + pe, e );
-					}
-				}
-				return true;
-			} 
-		} );
-	}
+            return preferences;
+        }
+    }
 
-    public Collection<ISigilProjectModel> findDependentProjects(IProgressMonitor monitor) {
-		return SigilCore.getRoot().resolveDependentProjects(this, monitor);
-	}
 
-	public Version getVersion() {
-		ISigilBundle bundle = getBundle();
-		return bundle == null ? null : bundle.getBundleInfo() == null ? null :  bundle.getBundleInfo().getVersion();
-	}
+    /**
+     * @return
+     */
+    private synchronized IEclipsePreferences loadPreferences()
+    {
+        IScopeContext context = new ProjectScope( getProject() );
+        final IEclipsePreferences eclipsePreferences = context.getNode( SigilCore.PLUGIN_ID );
 
-    public String getSymbolicName() {
-		ISigilBundle bundle = getBundle();
-    	return bundle == null ? null : bundle.getBundleInfo() == null ? null : bundle.getBundleInfo().getSymbolicName();
-	}
+        // Listen to node removal from parent in order to reset cache
+        INodeChangeListener nodeListener = new IEclipsePreferences.INodeChangeListener()
+        {
+            public void added( IEclipsePreferences.NodeChangeEvent event )
+            {
+                // do nothing
+            }
 
-    public IProject getProject() {
+
+            public void removed( IEclipsePreferences.NodeChangeEvent event )
+            {
+                if ( event.getChild() == eclipsePreferences )
+                {
+                    synchronized ( SigilProject.this )
+                    {
+                        preferences = null;
+                    }
+                    ( ( IEclipsePreferences ) eclipsePreferences.parent() ).removeNodeChangeListener( this );
+                }
+            }
+        };
+
+        ( ( IEclipsePreferences ) eclipsePreferences.parent() ).addNodeChangeListener( nodeListener );
+
+        return eclipsePreferences;
+    }
+
+
+    public Collection<IClasspathEntry> findExternalClasspath( IProgressMonitor monitor ) throws CoreException
+    {
+        return JavaHelper.resolveClasspathEntrys( this, monitor );
+    }
+
+
+    private void calculateUses()
+    {
+        visit( new IModelWalker()
+        {
+            public boolean visit( IModelElement element )
+            {
+                if ( element instanceof IPackageExport )
+                {
+                    IPackageExport pe = ( IPackageExport ) element;
+                    try
+                    {
+                        pe.setUses( Arrays.asList( JavaHelper.findUses( pe.getPackageName(), SigilProject.this ) ) );
+                    }
+                    catch ( CoreException e )
+                    {
+                        SigilCore.error( "Failed to build uses list for " + pe, e );
+                    }
+                }
+                return true;
+            }
+        } );
+    }
+
+
+    public Collection<ISigilProjectModel> findDependentProjects( IProgressMonitor monitor )
+    {
+        return SigilCore.getRoot().resolveDependentProjects( this, monitor );
+    }
+
+
+    public Version getVersion()
+    {
+        ISigilBundle bundle = getBundle();
+        return bundle == null ? null : bundle.getBundleInfo() == null ? null : bundle.getBundleInfo().getVersion();
+    }
+
+
+    public String getSymbolicName()
+    {
+        ISigilBundle bundle = getBundle();
+        return bundle == null ? null : bundle.getBundleInfo() == null ? null : bundle.getBundleInfo().getSymbolicName();
+    }
+
+
+    public IProject getProject()
+    {
         return project;
     }
 
-	public ISigilBundle getBundle() {
-		if ( bundle == null && bldProjectFile != null ) {
-			synchronized( bldProjectFile ) {
-				try {
-			        if ( bldProjectFile.getLocation().toFile().exists() ) {
-			        	bundle = parseContents(bldProjectFile);
-			        }
-			        else {
-			        	bundle = setupDefaults();
-			        	NullProgressMonitor npm = new NullProgressMonitor();
-			        	bldProjectFile.create( buildContents(), true /* force */, npm);
-			        	project.refreshLocal( IResource.DEPTH_INFINITE, npm );
-			        }
-				} catch (CoreException e) {
-					SigilCore.error( "Failed to build bundle", e);
-				}
-			}
-		}
-		return bundle;
-	}
-	
-	public void setBundle(ISigilBundle bundle) {
-		this.bundle = bundle;
-	}
-	
-	public IJavaProject getJavaModel() {
-		return JavaCore.create( project );
-	}
 
-	@Override
-	public boolean equals(Object obj) {
-		if ( obj == null ) return false;
-		
-		if ( obj == this ) return true;
-		
-		try {
-			SigilProject p = (SigilProject) obj;
-			return getSymbolicName().equals( p.getSymbolicName() ) && (getVersion() == null ? p.getVersion() == null : getVersion().equals( p.getVersion() ));
-		}
-		catch (ClassCastException e) {
-			return false;
-		}
-	}
-
-	@Override
-	public int hashCode() {
-		// TODO Auto-generated method stub
-		return super.hashCode();
-	}
-
-	@Override
-	public String toString() {
-		return "SigilProject[" + getSymbolicName() + ":" + getVersion() + "]";
-	}
-
-	public void resetClasspath(IProgressMonitor monitor) throws CoreException {
-    	Path containerPath = new Path( SigilCore.CLASSPATH_CONTAINER_PATH );
-    	IJavaProject java = getJavaModel();
-		ClasspathContainerInitializer init = JavaCore.getClasspathContainerInitializer(SigilCore.CLASSPATH_CONTAINER_PATH);
-		ThreadProgressMonitor.setProgressMonitor(monitor);
-		try {
-			init.requestClasspathContainerUpdate(containerPath, java, null);
-		}
-		finally {
-			ThreadProgressMonitor.setProgressMonitor(null);
-		}
-	}
-
-	public IPath findBundleLocation() throws CoreException {
-		IPath p = getBundle().getLocation();
-		if ( p == null ) {
-			p = SigilCore.getDefault().findDefaultBundleLocation(this);
-		}
-		return p;
-	}
-
-    public IModelElement findImport(final String packageName, final IProgressMonitor monitor) {
-    	final IModelElement[] found = new IModelElement[1];
-    	
-    	visit( new IModelWalker() {
-			public boolean visit(IModelElement element) {
-				if ( element instanceof IPackageImport ) {
-					IPackageImport pi = (IPackageImport) element;
-					if ( pi.getPackageName().equals( packageName ) ) {
-						found[0] = pi;
-						return false;
-					}
-				}
-				else if ( element instanceof IRequiredBundle ) {
-					IRequiredBundle rb = (IRequiredBundle) element;
-					try {
-						IRepositoryManager manager = SigilCore.getRepositoryManager(SigilProject.this);
-						ResolutionConfig config = new ResolutionConfig(ResolutionConfig.IGNORE_ERRORS);
-						IResolution res = manager.getBundleResolver().resolve(rb, config, new ResolutionMonitorAdapter(monitor));
-						ISigilBundle b = res.getProvider(rb);
-						for ( IPackageExport pe : b.getBundleInfo().getExports() ) {
-							if ( pe.getPackageName().equals( packageName ) ) {
-								found[0] = rb;
-								return false;
-							}
-						}
-					} catch (ResolutionException e) {
-						SigilCore.error( "Failed to resolve " + rb, e );
-					}
-				}
-				return true;
-			}
-    		
-    	});
-    	
-    	return found[0];
-	}
-
-	public boolean isInClasspath(String packageName, IProgressMonitor monitor) throws CoreException {
-		if ( findImport(packageName, monitor) != null ) {
-			return true;
-		}
-		
-		for ( String path : getBundle().getClasspathEntrys() ) {
-			IClasspathEntry cp = getJavaModel().decodeClasspathEntry(path);
-			for ( IPackageFragmentRoot root : getJavaModel().findPackageFragmentRoots(cp) ) {
-				if ( findPackage( packageName, root ) ) {
-					return true;
-				}
-			}
-		}
-		return false;
-	}
-	
-	public boolean isInClasspath(ISigilBundle bundle) {
-		for ( String path : getBundle().getClasspathEntrys() ) {
-			IClasspathEntry cp = getJavaModel().decodeClasspathEntry(path);
-			switch ( cp.getEntryKind() ) {
-			case IClasspathEntry.CPE_PROJECT:
-				ISigilProjectModel p = bundle.getAncestor(ISigilProjectModel.class);
-				return p != null && cp.getPath().equals(p.getProject().getFullPath());
-			case IClasspathEntry.CPE_LIBRARY:
-				return cp.getPath().equals(bundle.getLocation());
-			}
-		}	
-		
-		return false;
-	}
-
-	private boolean findPackage(String packageName, IParent parent) throws JavaModelException {
-		for ( IJavaElement e : parent.getChildren() ) {
-			if ( e.getElementType() == IJavaElement.PACKAGE_FRAGMENT ) {
-				return e.getElementName().equals( packageName );
-			}
-			
-			if ( e instanceof IParent ) {
-				if ( findPackage(packageName, (IParent) e) ) {
-					return true;
-				}
-			}
-		}
-		
-		return false;
-	}
-
-	private ISigilBundle setupDefaults() {
-    	ISigilBundle bundle = ModelElementFactory.getInstance().newModelElement(ISigilBundle.class);
-    	IBundleModelElement info = ModelElementFactory.getInstance().newModelElement( IBundleModelElement.class );
-    	info.setSymbolicName(project.getName());
-    	bundle.setBundleInfo(info);
-    	bundle.setParent(this);
-    	return bundle;
+    public ISigilBundle getBundle()
+    {
+        if ( bundle == null && bldProjectFile != null )
+        {
+            synchronized ( bldProjectFile )
+            {
+                try
+                {
+                    if ( bldProjectFile.getLocation().toFile().exists() )
+                    {
+                        bundle = parseContents( bldProjectFile );
+                    }
+                    else
+                    {
+                        bundle = setupDefaults();
+                        NullProgressMonitor npm = new NullProgressMonitor();
+                        bldProjectFile.create( buildContents(), true /* force */, npm );
+                        project.refreshLocal( IResource.DEPTH_INFINITE, npm );
+                    }
+                }
+                catch ( CoreException e )
+                {
+                    SigilCore.error( "Failed to build bundle", e );
+                }
+            }
+        }
+        return bundle;
     }
 
-	
-	private ISigilBundle parseContents(IFile projectFile) throws CoreException {
-		/*if ( !projectFile.isSynchronized(IResource.DEPTH_ONE) ) {
-			projectFile.refreshLocal(IResource.DEPTH_ONE, new NullProgressMonitor());
-		}*/
-		
-		if ( projectFile.getName().equals( SigilCore.SIGIL_PROJECT_FILE) ) {
-			return parseBldContents(projectFile.getLocationURI());
-		}
-		else {
-			throw SigilCore.newCoreException("Unexpected project file: " + projectFile.getName(), null );
-		}
-	}
-	
-    private ISigilBundle parseBldContents(URI uri) throws CoreException {
-		try {
-			bldProject = BldFactory.getProject(uri, true);
-			ISigilBundle bundle = bldProject.getDefaultBundle();
-			bundle.setParent(this);
-			return bundle;
-		} catch (IOException e) {
-			throw SigilCore.newCoreException( "Failed to parse " + uri, e);
-		}
-	}
 
-	private InputStream buildContents() throws CoreException {
-    	ByteArrayOutputStream buf = new ByteArrayOutputStream();    	
-    	try {
-    		if (bldProject == null) {
-            	bldProject = BldFactory.newProject(bldProjectFile.getLocationURI(), null);
-    		}
-        	bldProject.setDefaultBundle(getBundle());
-			bldProject.saveTo(buf);
-		} catch (IOException e) {
-			throw SigilCore.newCoreException("Failed to save project file", e);
-		}
-    	return new ByteArrayInputStream(buf.toByteArray());
+    public void setBundle( ISigilBundle bundle )
+    {
+        this.bundle = bundle;
     }
-    
-//    private InputStream buildXMLContents() throws CoreException {
-//    	Serializer serializer = SigilCore.getDefault().getDescriptorSerializer();
-//    	
-//    	ByteArrayOutputStream buf = new ByteArrayOutputStream();
-//    	
-//    	try {
-//    		serializer.serialize(getBundle(), buf);
-//    	} catch (SerializingException e) {
-//			throw SigilCore.newCoreException("Failed to serialize " + this, e);
-//    	}
-//    	
-//        return new ByteArrayInputStream(buf.toByteArray());
-//    }
 
-	public String getName() {
-		return getProject().getName();
-	}
 
-	public IPath findOutputLocation() throws CoreException {
-		return getProject().getLocation().append(
-				getJavaModel().getOutputLocation()
-				.removeFirstSegments(1));
-	}
+    public IJavaProject getJavaModel()
+    {
+        return JavaCore.create( project );
+    }
 
-	public IBldProject getBldProject() throws CoreException {
-		try {
-			return BldFactory.getProject(project.getFile(IBldProject.PROJECT_FILE).getLocationURI());
-		} catch (IOException e) {
-			throw SigilCore.newCoreException("Failed to get project file: ",e);
-		}
-	}
 
-	public boolean isInBundleClasspath(IPackageFragmentRoot root) throws JavaModelException {
-		String enc = getJavaModel().encodeClasspathEntry(root.getRawClasspathEntry());
-		return getBundle().getClasspathEntrys().contains( enc.trim() );
-	}
+    @Override
+    public boolean equals( Object obj )
+    {
+        if ( obj == null )
+            return false;
+
+        if ( obj == this )
+            return true;
+
+        try
+        {
+            SigilProject p = ( SigilProject ) obj;
+            return getSymbolicName().equals( p.getSymbolicName() )
+                && ( getVersion() == null ? p.getVersion() == null : getVersion().equals( p.getVersion() ) );
+        }
+        catch ( ClassCastException e )
+        {
+            return false;
+        }
+    }
+
+
+    @Override
+    public int hashCode()
+    {
+        // TODO Auto-generated method stub
+        return super.hashCode();
+    }
+
+
+    @Override
+    public String toString()
+    {
+        return "SigilProject[" + getSymbolicName() + ":" + getVersion() + "]";
+    }
+
+
+    public void resetClasspath( IProgressMonitor monitor ) throws CoreException
+    {
+        Path containerPath = new Path( SigilCore.CLASSPATH_CONTAINER_PATH );
+        IJavaProject java = getJavaModel();
+        ClasspathContainerInitializer init = JavaCore
+            .getClasspathContainerInitializer( SigilCore.CLASSPATH_CONTAINER_PATH );
+        ThreadProgressMonitor.setProgressMonitor( monitor );
+        try
+        {
+            init.requestClasspathContainerUpdate( containerPath, java, null );
+        }
+        finally
+        {
+            ThreadProgressMonitor.setProgressMonitor( null );
+        }
+    }
+
+
+    public IPath findBundleLocation() throws CoreException
+    {
+        IPath p = getBundle().getLocation();
+        if ( p == null )
+        {
+            p = SigilCore.getDefault().findDefaultBundleLocation( this );
+        }
+        return p;
+    }
+
+
+    public IModelElement findImport( final String packageName, final IProgressMonitor monitor )
+    {
+        final IModelElement[] found = new IModelElement[1];
+
+        visit( new IModelWalker()
+        {
+            public boolean visit( IModelElement element )
+            {
+                if ( element instanceof IPackageImport )
+                {
+                    IPackageImport pi = ( IPackageImport ) element;
+                    if ( pi.getPackageName().equals( packageName ) )
+                    {
+                        found[0] = pi;
+                        return false;
+                    }
+                }
+                else if ( element instanceof IRequiredBundle )
+                {
+                    IRequiredBundle rb = ( IRequiredBundle ) element;
+                    try
+                    {
+                        IRepositoryManager manager = SigilCore.getRepositoryManager( SigilProject.this );
+                        ResolutionConfig config = new ResolutionConfig( ResolutionConfig.IGNORE_ERRORS );
+                        IResolution res = manager.getBundleResolver().resolve( rb, config,
+                            new ResolutionMonitorAdapter( monitor ) );
+                        ISigilBundle b = res.getProvider( rb );
+                        for ( IPackageExport pe : b.getBundleInfo().getExports() )
+                        {
+                            if ( pe.getPackageName().equals( packageName ) )
+                            {
+                                found[0] = rb;
+                                return false;
+                            }
+                        }
+                    }
+                    catch ( ResolutionException e )
+                    {
+                        SigilCore.error( "Failed to resolve " + rb, e );
+                    }
+                }
+                return true;
+            }
+
+        } );
+
+        return found[0];
+    }
+
+
+    public boolean isInClasspath( String packageName, IProgressMonitor monitor ) throws CoreException
+    {
+        if ( findImport( packageName, monitor ) != null )
+        {
+            return true;
+        }
+
+        for ( String path : getBundle().getClasspathEntrys() )
+        {
+            IClasspathEntry cp = getJavaModel().decodeClasspathEntry( path );
+            for ( IPackageFragmentRoot root : getJavaModel().findPackageFragmentRoots( cp ) )
+            {
+                if ( findPackage( packageName, root ) )
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+
+    public boolean isInClasspath( ISigilBundle bundle )
+    {
+        for ( String path : getBundle().getClasspathEntrys() )
+        {
+            IClasspathEntry cp = getJavaModel().decodeClasspathEntry( path );
+            switch ( cp.getEntryKind() )
+            {
+                case IClasspathEntry.CPE_PROJECT:
+                    ISigilProjectModel p = bundle.getAncestor( ISigilProjectModel.class );
+                    return p != null && cp.getPath().equals( p.getProject().getFullPath() );
+                case IClasspathEntry.CPE_LIBRARY:
+                    return cp.getPath().equals( bundle.getLocation() );
+            }
+        }
+
+        return false;
+    }
+
+
+    private boolean findPackage( String packageName, IParent parent ) throws JavaModelException
+    {
+        for ( IJavaElement e : parent.getChildren() )
+        {
+            if ( e.getElementType() == IJavaElement.PACKAGE_FRAGMENT )
+            {
+                return e.getElementName().equals( packageName );
+            }
+
+            if ( e instanceof IParent )
+            {
+                if ( findPackage( packageName, ( IParent ) e ) )
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+
+    private ISigilBundle setupDefaults()
+    {
+        ISigilBundle bundle = ModelElementFactory.getInstance().newModelElement( ISigilBundle.class );
+        IBundleModelElement info = ModelElementFactory.getInstance().newModelElement( IBundleModelElement.class );
+        info.setSymbolicName( project.getName() );
+        bundle.setBundleInfo( info );
+        bundle.setParent( this );
+        return bundle;
+    }
+
+
+    private ISigilBundle parseContents( IFile projectFile ) throws CoreException
+    {
+        /*if ( !projectFile.isSynchronized(IResource.DEPTH_ONE) ) {
+        	projectFile.refreshLocal(IResource.DEPTH_ONE, new NullProgressMonitor());
+        }*/
+
+        if ( projectFile.getName().equals( SigilCore.SIGIL_PROJECT_FILE ) )
+        {
+            return parseBldContents( projectFile.getLocationURI() );
+        }
+        else
+        {
+            throw SigilCore.newCoreException( "Unexpected project file: " + projectFile.getName(), null );
+        }
+    }
+
+
+    private ISigilBundle parseBldContents( URI uri ) throws CoreException
+    {
+        try
+        {
+            bldProject = BldFactory.getProject( uri, true );
+            ISigilBundle bundle = bldProject.getDefaultBundle();
+            bundle.setParent( this );
+            return bundle;
+        }
+        catch ( IOException e )
+        {
+            throw SigilCore.newCoreException( "Failed to parse " + uri, e );
+        }
+    }
+
+
+    private InputStream buildContents() throws CoreException
+    {
+        ByteArrayOutputStream buf = new ByteArrayOutputStream();
+        try
+        {
+            if ( bldProject == null )
+            {
+                bldProject = BldFactory.newProject( bldProjectFile.getLocationURI(), null );
+            }
+            bldProject.setDefaultBundle( getBundle() );
+            bldProject.saveTo( buf );
+        }
+        catch ( IOException e )
+        {
+            throw SigilCore.newCoreException( "Failed to save project file", e );
+        }
+        return new ByteArrayInputStream( buf.toByteArray() );
+    }
+
+
+    //    private InputStream buildXMLContents() throws CoreException {
+    //    	Serializer serializer = SigilCore.getDefault().getDescriptorSerializer();
+    //    	
+    //    	ByteArrayOutputStream buf = new ByteArrayOutputStream();
+    //    	
+    //    	try {
+    //    		serializer.serialize(getBundle(), buf);
+    //    	} catch (SerializingException e) {
+    //			throw SigilCore.newCoreException("Failed to serialize " + this, e);
+    //    	}
+    //    	
+    //        return new ByteArrayInputStream(buf.toByteArray());
+    //    }
+
+    public String getName()
+    {
+        return getProject().getName();
+    }
+
+
+    public IPath findOutputLocation() throws CoreException
+    {
+        return getProject().getLocation().append( getJavaModel().getOutputLocation().removeFirstSegments( 1 ) );
+    }
+
+
+    public IBldProject getBldProject() throws CoreException
+    {
+        try
+        {
+            return BldFactory.getProject( project.getFile( IBldProject.PROJECT_FILE ).getLocationURI() );
+        }
+        catch ( IOException e )
+        {
+            throw SigilCore.newCoreException( "Failed to get project file: ", e );
+        }
+    }
+
+
+    public boolean isInBundleClasspath( IPackageFragmentRoot root ) throws JavaModelException
+    {
+        String enc = getJavaModel().encodeClasspathEntry( root.getRawClasspathEntry() );
+        return getBundle().getClasspathEntrys().contains( enc.trim() );
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryConfiguration.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryConfiguration.java
index c0e93db..718da4e 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryConfiguration.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/model/repository/RepositoryConfiguration.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.internal.model.repository;
 
+
 import java.io.File;
 import java.io.IOException;
 import java.net.URL;
@@ -49,335 +50,430 @@
 import org.eclipse.swt.graphics.Image;
 import org.osgi.framework.Bundle;
 
-public class RepositoryConfiguration implements IRepositoryConfiguration {
-	
-	private static final String REPOSITORY = "repository.";
-	private static final String REPOSITORY_SET = REPOSITORY + "set.";
-	private static final String REPOSITORY_SETS = REPOSITORY + "sets";
-	private static final String REPOSITORY_TIMESTAMP = REPOSITORY + "timestamp";
-	private static final String INSTANCES = ".instances";
-	private static final String NAME = ".name";
-	private static final String LOC = ".loc";
-	private static final String TIMESTAMP = ".timestamp";
-	
-	public static final String REPOSITORY_DEFAULT_SET = REPOSITORY + "default.set";
 
-	public List<IRepositoryModel> loadRepositories() {
-		IPreferenceStore prefs = SigilCore.getDefault().getPreferenceStore();
-		
-		ArrayList<IRepositoryModel> repositories = new ArrayList<IRepositoryModel>();
+public class RepositoryConfiguration implements IRepositoryConfiguration
+{
 
-		for ( RepositoryType type : loadRepositoryTypes() ) {
-			String typeID = type.getId();
-			
-			if ( type.isDynamic() ) {	
-				String instances = prefs.getString( REPOSITORY + typeID + INSTANCES );
-				if ( instances.trim().length() > 0 ) {
-					for( String instance : instances.split(",") ) {
-						String key = REPOSITORY + typeID + "." + instance;
-						repositories.add( loadRepository(instance, key, type, prefs) );
-					}
-				}
-			}
-			else {
-				String key = REPOSITORY + typeID;
-				repositories.add( loadRepository(typeID, key, type, prefs) );
-			}
-			
-		}
-		
-		return repositories;
-	}
-	
-	public IRepositoryModel findRepository(String id) {
-		for (IRepositoryModel model : loadRepositories()) {
-			if ( model.getId().equals( id ) ) {
-				return model;
-			}
-		}
-		return null;
-	}
-	
-	public void saveRepositories(List<IRepositoryModel> repositories) throws CoreException {
-		IPreferenceStore prefs = getPreferences();
-		
-		HashMap<IRepositoryType, List<IRepositoryModel>> mapped = new HashMap<IRepositoryType, List<IRepositoryModel>>(repositories.size());
-		
-		saveRepositoryPreferences(repositories, mapped);
-		createNewEntries(mapped, prefs);
-		deleteOldEntries(repositories,prefs);
-		// time stamp is used as a signal to the manager
-		// to update its view of the stored repositories
-		timeStamp(prefs);
-	}
+    private static final String REPOSITORY = "repository.";
+    private static final String REPOSITORY_SET = REPOSITORY + "set.";
+    private static final String REPOSITORY_SETS = REPOSITORY + "sets";
+    private static final String REPOSITORY_TIMESTAMP = REPOSITORY + "timestamp";
+    private static final String INSTANCES = ".instances";
+    private static final String NAME = ".name";
+    private static final String LOC = ".loc";
+    private static final String TIMESTAMP = ".timestamp";
 
-	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");
-				Image image = (icon == null || icon.trim().length() == 0) ? null : loadImage(e, icon);
-				repositories.add( new RepositoryType(id, type, dynamic, image ) );
-			}
-		}
-		
-		return repositories;
-	}
+    public static final String REPOSITORY_DEFAULT_SET = REPOSITORY + "default.set";
 
-	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);
-		return element;
-	}
-	
-	public IRepositorySet getDefaultRepositorySet() {
-		//int level = findLevel( key + LEVEL, type, prefs );
-		ArrayList<IRepositoryModel> reps = new ArrayList<IRepositoryModel>();
-		for ( String s : PrefsUtils.stringToArray(getPreferences().getString( REPOSITORY_DEFAULT_SET)) ) {
-			reps.add( findRepository(s) );
-		}
-		return new RepositorySet( reps );
-	}
 
-	public IRepositorySet getRepositorySet(String name) {
-		String key = REPOSITORY_SET + name;
-		if ( getPreferences().contains(key) ) {
-			ArrayList<IRepositoryModel> reps = new ArrayList<IRepositoryModel>();
-			for ( String s : PrefsUtils.stringToArray(getPreferences().getString( key )) ) {
-				reps.add( findRepository(s) );
-			}
-			return new RepositorySet( reps );
-		}
-		else {
-			return null;
-		}
-	}
+    public List<IRepositoryModel> loadRepositories()
+    {
+        IPreferenceStore prefs = SigilCore.getDefault().getPreferenceStore();
 
-	public Map<String, IRepositorySet> loadRepositorySets() {
-		IPreferenceStore store = getPreferences();
-		
-		HashMap<String, IRepositorySet> sets = new HashMap<String, IRepositorySet>();
-		
-		for ( String name : PrefsUtils.stringToArray(store.getString(REPOSITORY_SETS))) {
-			String key = REPOSITORY_SET + name;
-			ArrayList<IRepositoryModel> reps = new ArrayList<IRepositoryModel>();
-			for ( String s : PrefsUtils.stringToArray(getPreferences().getString( key )) ) {
-				reps.add( findRepository(s) );
-			}
-			sets.put( name, new RepositorySet( reps ) );
-		}
-		
-		return sets;
-	}
+        ArrayList<IRepositoryModel> repositories = new ArrayList<IRepositoryModel>();
 
-	public void saveRepositorySets(Map<String, IRepositorySet> sets) {
-		IPreferenceStore store = getPreferences();
+        for ( RepositoryType type : loadRepositoryTypes() )
+        {
+            String typeID = type.getId();
 
-		ArrayList<String> names = new ArrayList<String>();
-		
-		for ( Map.Entry<String, IRepositorySet> set : sets.entrySet() ) {
-			String name = set.getKey();
-			String key = REPOSITORY_SET + name;
-			ArrayList<String> ids = new ArrayList<String>();
-			for ( IRepositoryModel m : set.getValue().getRepositories() ) {
-				ids.add( m.getId() );
-			}
-			store.setValue(key, PrefsUtils.listToString(ids) );
-			names.add( name );
-		}
-		
-		for ( String name : PrefsUtils.stringToArray(store.getString(REPOSITORY_SETS))) {
-			if ( !names.contains(name) ) {
-				String key = REPOSITORY_SET + name;
-				store.setToDefault(key);
-			}
-		}
-		
-		store.setValue(REPOSITORY_SETS, PrefsUtils.listToString(names) );
-		timeStamp(store);
-	}
-			
-	public void setDefaultRepositorySet(IRepositorySet defaultSet) {
-		ArrayList<String> ids = new ArrayList<String>();
-		for ( IRepositoryModel m : defaultSet.getRepositories() ) {
-			ids.add( m.getId() );
-		}
-		IPreferenceStore prefs = getPreferences();
-		prefs.setValue( REPOSITORY_DEFAULT_SET, PrefsUtils.listToString( ids ) );
-		timeStamp(prefs);
-	}
+            if ( type.isDynamic() )
+            {
+                String instances = prefs.getString( REPOSITORY + typeID + INSTANCES );
+                if ( instances.trim().length() > 0 )
+                {
+                    for ( String instance : instances.split( "," ) )
+                    {
+                        String key = REPOSITORY + typeID + "." + instance;
+                        repositories.add( loadRepository( instance, key, type, prefs ) );
+                    }
+                }
+            }
+            else
+            {
+                String key = REPOSITORY + typeID;
+                repositories.add( loadRepository( typeID, key, type, prefs ) );
+            }
 
-	private void timeStamp(IPreferenceStore prefs) {
-		prefs.setValue( REPOSITORY_TIMESTAMP, System.currentTimeMillis() );
-	}
+        }
 
-	private IPreferenceStore getPreferences() {
-		return SigilCore.getDefault().getPreferenceStore();
-	}
+        return repositories;
+    }
 
-	private void deleteOldEntries(List<IRepositoryModel> repositories, IPreferenceStore prefs) {
-		for ( IRepositoryModel e : loadRepositories() ) {
-			if ( !repositories.contains(e) ) {
-				new File( makeFileName(e) ).delete();
-				String key = makeKey(e);
-				prefs.setToDefault( key + LOC );
-				prefs.setToDefault( key + NAME );
-			}
-		}
-		
-		for ( IRepositoryType type : loadRepositoryTypes() ) {
-			boolean found = false;
-			for ( IRepositoryModel e : repositories ) {
-				if ( e.getType().equals( type ) ) {
-					found = true;
-					break;
-				}
-			}
-			
-			if ( !found ) {
-				prefs.setToDefault( REPOSITORY + type.getId() + INSTANCES );
-			}
-		}
-	}
 
-	private static void createNewEntries(HashMap<IRepositoryType, List<IRepositoryModel>> mapped, IPreferenceStore prefs) {
-		for ( Map.Entry<IRepositoryType, List<IRepositoryModel>> entry : mapped.entrySet() ) {
-			IRepositoryType type = entry.getKey();
-			if ( type.isDynamic() ) {
-				StringBuffer buf = new StringBuffer();
-				
-				for ( IRepositoryModel element : entry.getValue() ) {
-					if ( buf.length() > 0 ) {
-						buf.append( "," );
-					}
-					buf.append( element.getId() );
-					saveRepository(element, prefs);
-				}
-				
-				prefs.setValue( REPOSITORY + type.getId() + INSTANCES, buf.toString() );
-			}
-			else {
-				IRepositoryModel element = entry.getValue().get(0);
-				saveRepository(element, prefs);
-			}
-		}
-	}
+    public IRepositoryModel findRepository( String id )
+    {
+        for ( IRepositoryModel model : loadRepositories() )
+        {
+            if ( model.getId().equals( id ) )
+            {
+                return model;
+            }
+        }
+        return null;
+    }
 
-	private static void saveRepositoryPreferences(List<IRepositoryModel> repositories,
-			HashMap<IRepositoryType, List<IRepositoryModel>> mapped) throws CoreException {
-		for( IRepositoryModel rep : repositories ) {
-			try {
-				createDir( makeFileName(rep));
-				rep.getPreferences().save();
-				List<IRepositoryModel> list = mapped.get( rep.getType() );
-				if ( list == null ) {
-					list = new ArrayList<IRepositoryModel>(1);
-					mapped.put( rep.getType(), list );
-				}
-				list.add( rep );
-			} catch (IOException e) {
-				throw SigilCore.newCoreException("Failed to save repository preferences", e);
-			}
-		}
-	}
 
-	private static void createDir(String fileName) {
-		File file = new File( fileName );
-		file.getParentFile().mkdirs();
-	}
+    public void saveRepositories( List<IRepositoryModel> repositories ) throws CoreException
+    {
+        IPreferenceStore prefs = getPreferences();
 
-	private static void saveRepository(IRepositoryModel element, IPreferenceStore prefs) {
-		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() );
-	}
+        HashMap<IRepositoryType, List<IRepositoryModel>> mapped = new HashMap<IRepositoryType, List<IRepositoryModel>>(
+            repositories.size() );
 
-	private static long now() {
-		return System.currentTimeMillis();
-	}
+        saveRepositoryPreferences( repositories, mapped );
+        createNewEntries( mapped, prefs );
+        deleteOldEntries( repositories, prefs );
+        // time stamp is used as a signal to the manager
+        // to update its view of the stored repositories
+        timeStamp( prefs );
+    }
 
-	private static String makeKey(IRepositoryModel element) {
-		IRepositoryType type = element.getType();
-		
-		String key = REPOSITORY + type.getId(); 
-		if ( type.isDynamic() )
-			key = key + "." + element.getId();
-		
-		return key;
-	}
 
-	private static String makeFileName(IRepositoryModel element) {
-		IPath path = SigilCore.getDefault().getStateLocation();
-		path = path.append( "repository" );
-		path = path.append( element.getType().getId() );
-		path = path.append( element.getId() );
-		return path.toOSString();
-	}
+    public List<RepositoryType> loadRepositoryTypes()
+    {
+        List<RepositoryType> repositories = new ArrayList<RepositoryType>();
 
-	private static RepositoryModel loadRepository(String id, String key, RepositoryType 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 );
-		
-		String loc = prefs.getString( key + LOC );
-		
-		if ( loc == null || loc.trim().length() == 0 ) {
-			loc = makeFileName(element);
-		}
-		
-		repPrefs.setFilename(loc);
-		
-		if ( new File( loc ).exists() ) {
-			try {
-				repPrefs.load();
-			} catch (IOException e) {
-				SigilCore.error("Failed to load properties for repository " + key, e );
-			}
-		}
-		
-		repPrefs.setValue( "id", id );
-		
-		return element;
-	}
+        IExtensionRegistry registry = Platform.getExtensionRegistry();
 
-	@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;
-	}
+        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" );
+                Image image = ( icon == null || icon.trim().length() == 0 ) ? null : loadImage( e, icon );
+                repositories.add( new RepositoryType( id, 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 );
+        return element;
+    }
+
+
+    public IRepositorySet getDefaultRepositorySet()
+    {
+        //int level = findLevel( key + LEVEL, type, prefs );
+        ArrayList<IRepositoryModel> reps = new ArrayList<IRepositoryModel>();
+        for ( String s : PrefsUtils.stringToArray( getPreferences().getString( REPOSITORY_DEFAULT_SET ) ) )
+        {
+            reps.add( findRepository( s ) );
+        }
+        return new RepositorySet( reps );
+    }
+
+
+    public IRepositorySet getRepositorySet( String name )
+    {
+        String key = REPOSITORY_SET + name;
+        if ( getPreferences().contains( key ) )
+        {
+            ArrayList<IRepositoryModel> reps = new ArrayList<IRepositoryModel>();
+            for ( String s : PrefsUtils.stringToArray( getPreferences().getString( key ) ) )
+            {
+                reps.add( findRepository( s ) );
+            }
+            return new RepositorySet( reps );
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    public Map<String, IRepositorySet> loadRepositorySets()
+    {
+        IPreferenceStore store = getPreferences();
+
+        HashMap<String, IRepositorySet> sets = new HashMap<String, IRepositorySet>();
+
+        for ( String name : PrefsUtils.stringToArray( store.getString( REPOSITORY_SETS ) ) )
+        {
+            String key = REPOSITORY_SET + name;
+            ArrayList<IRepositoryModel> reps = new ArrayList<IRepositoryModel>();
+            for ( String s : PrefsUtils.stringToArray( getPreferences().getString( key ) ) )
+            {
+                reps.add( findRepository( s ) );
+            }
+            sets.put( name, new RepositorySet( reps ) );
+        }
+
+        return sets;
+    }
+
+
+    public void saveRepositorySets( Map<String, IRepositorySet> sets )
+    {
+        IPreferenceStore store = getPreferences();
+
+        ArrayList<String> names = new ArrayList<String>();
+
+        for ( Map.Entry<String, IRepositorySet> set : sets.entrySet() )
+        {
+            String name = set.getKey();
+            String key = REPOSITORY_SET + name;
+            ArrayList<String> ids = new ArrayList<String>();
+            for ( IRepositoryModel m : set.getValue().getRepositories() )
+            {
+                ids.add( m.getId() );
+            }
+            store.setValue( key, PrefsUtils.listToString( ids ) );
+            names.add( name );
+        }
+
+        for ( String name : PrefsUtils.stringToArray( store.getString( REPOSITORY_SETS ) ) )
+        {
+            if ( !names.contains( name ) )
+            {
+                String key = REPOSITORY_SET + name;
+                store.setToDefault( key );
+            }
+        }
+
+        store.setValue( REPOSITORY_SETS, PrefsUtils.listToString( names ) );
+        timeStamp( store );
+    }
+
+
+    public void setDefaultRepositorySet( IRepositorySet defaultSet )
+    {
+        ArrayList<String> ids = new ArrayList<String>();
+        for ( IRepositoryModel m : defaultSet.getRepositories() )
+        {
+            ids.add( m.getId() );
+        }
+        IPreferenceStore prefs = getPreferences();
+        prefs.setValue( REPOSITORY_DEFAULT_SET, PrefsUtils.listToString( ids ) );
+        timeStamp( prefs );
+    }
+
+
+    private void timeStamp( IPreferenceStore prefs )
+    {
+        prefs.setValue( REPOSITORY_TIMESTAMP, System.currentTimeMillis() );
+    }
+
+
+    private IPreferenceStore getPreferences()
+    {
+        return SigilCore.getDefault().getPreferenceStore();
+    }
+
+
+    private void deleteOldEntries( List<IRepositoryModel> repositories, IPreferenceStore prefs )
+    {
+        for ( IRepositoryModel e : loadRepositories() )
+        {
+            if ( !repositories.contains( e ) )
+            {
+                new File( makeFileName( e ) ).delete();
+                String key = makeKey( e );
+                prefs.setToDefault( key + LOC );
+                prefs.setToDefault( key + NAME );
+            }
+        }
+
+        for ( IRepositoryType type : loadRepositoryTypes() )
+        {
+            boolean found = false;
+            for ( IRepositoryModel e : repositories )
+            {
+                if ( e.getType().equals( type ) )
+                {
+                    found = true;
+                    break;
+                }
+            }
+
+            if ( !found )
+            {
+                prefs.setToDefault( REPOSITORY + type.getId() + INSTANCES );
+            }
+        }
+    }
+
+
+    private static void createNewEntries( HashMap<IRepositoryType, List<IRepositoryModel>> mapped,
+        IPreferenceStore prefs )
+    {
+        for ( Map.Entry<IRepositoryType, List<IRepositoryModel>> entry : mapped.entrySet() )
+        {
+            IRepositoryType type = entry.getKey();
+            if ( type.isDynamic() )
+            {
+                StringBuffer buf = new StringBuffer();
+
+                for ( IRepositoryModel element : entry.getValue() )
+                {
+                    if ( buf.length() > 0 )
+                    {
+                        buf.append( "," );
+                    }
+                    buf.append( element.getId() );
+                    saveRepository( element, prefs );
+                }
+
+                prefs.setValue( REPOSITORY + type.getId() + INSTANCES, buf.toString() );
+            }
+            else
+            {
+                IRepositoryModel element = entry.getValue().get( 0 );
+                saveRepository( element, prefs );
+            }
+        }
+    }
+
+
+    private static void saveRepositoryPreferences( List<IRepositoryModel> repositories,
+        HashMap<IRepositoryType, List<IRepositoryModel>> mapped ) throws CoreException
+    {
+        for ( IRepositoryModel rep : repositories )
+        {
+            try
+            {
+                createDir( makeFileName( rep ) );
+                rep.getPreferences().save();
+                List<IRepositoryModel> list = mapped.get( rep.getType() );
+                if ( list == null )
+                {
+                    list = new ArrayList<IRepositoryModel>( 1 );
+                    mapped.put( rep.getType(), list );
+                }
+                list.add( rep );
+            }
+            catch ( IOException e )
+            {
+                throw SigilCore.newCoreException( "Failed to save repository preferences", e );
+            }
+        }
+    }
+
+
+    private static void createDir( String fileName )
+    {
+        File file = new File( fileName );
+        file.getParentFile().mkdirs();
+    }
+
+
+    private static void saveRepository( IRepositoryModel element, IPreferenceStore prefs )
+    {
+        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() );
+    }
+
+
+    private static long now()
+    {
+        return System.currentTimeMillis();
+    }
+
+
+    private static String makeKey( IRepositoryModel element )
+    {
+        IRepositoryType type = element.getType();
+
+        String key = REPOSITORY + type.getId();
+        if ( type.isDynamic() )
+            key = key + "." + element.getId();
+
+        return key;
+    }
+
+
+    private static String makeFileName( IRepositoryModel element )
+    {
+        IPath path = SigilCore.getDefault().getStateLocation();
+        path = path.append( "repository" );
+        path = path.append( element.getType().getId() );
+        path = path.append( element.getId() );
+        return path.toOSString();
+    }
+
+
+    private static RepositoryModel loadRepository( String id, String key, RepositoryType 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 );
+
+        String loc = prefs.getString( key + LOC );
+
+        if ( loc == null || loc.trim().length() == 0 )
+        {
+            loc = makeFileName( element );
+        }
+
+        repPrefs.setFilename( loc );
+
+        if ( new File( loc ).exists() )
+        {
+            try
+            {
+                repPrefs.load();
+            }
+            catch ( IOException e )
+            {
+                SigilCore.error( "Failed to load properties for repository " + key, e );
+            }
+        }
+
+        repPrefs.setValue( "id", id );
+
+        return element;
+    }
+
+
+    @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 042e8a8..bdc7a6d 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,63 +19,86 @@
 
 package org.apache.felix.sigil.eclipse.internal.model.repository;
 
+
 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;
-	
-	private String name;
-	
-	private IRepositoryType type;
-	
-	private PreferenceStore preferences;
-		
-	public RepositoryModel(String id, String name, IRepositoryType type, PreferenceStore preferences) {
-		this.id = id;
-		this.name = name;
-		this.type = type;
-		this.preferences = preferences;
-	}
-	
-	public PreferenceStore getPreferences() {
-		return preferences;
-	}
 
-	public IRepositoryType getType() {
-		return type;
-	}
+public class RepositoryModel implements IRepositoryModel
+{
+    private String id;
 
-	public String getId() {
-		return id;
-	}
+    private String name;
 
-	public String getName() {
-		return name;
-	}
-	
-	public void setName(String name) {
-		this.name = name;
-	}
+    private IRepositoryType type;
 
-	@Override
-	public boolean equals(Object obj) {
-		try {
-			RepositoryModel e = (RepositoryModel) obj;
-			return id.equals(e.id);
-		}
-		catch (ClassCastException e) {
-			return false;
-		}
-	}
+    private PreferenceStore preferences;
 
-	@Override
-	public int hashCode() {
-		return id.hashCode();
-	}
-	
-	public String toString() {
-		return type.getId() + ":" + id + ":" + name;
-	}
+
+    public RepositoryModel( String id, String name, IRepositoryType type, PreferenceStore preferences )
+    {
+        this.id = id;
+        this.name = name;
+        this.type = type;
+        this.preferences = preferences;
+    }
+
+
+    public PreferenceStore getPreferences()
+    {
+        return preferences;
+    }
+
+
+    public IRepositoryType getType()
+    {
+        return type;
+    }
+
+
+    public String getId()
+    {
+        return id;
+    }
+
+
+    public String getName()
+    {
+        return name;
+    }
+
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        try
+        {
+            RepositoryModel e = ( RepositoryModel ) obj;
+            return id.equals( e.id );
+        }
+        catch ( ClassCastException e )
+        {
+            return false;
+        }
+    }
+
+
+    @Override
+    public int hashCode()
+    {
+        return id.hashCode();
+    }
+
+
+    public String toString()
+    {
+        return type.getId() + ":" + id + ":" + name;
+    }
 }
\ No newline at end of file
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 1675057..bb05fe0 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
@@ -19,57 +19,77 @@
 
 package org.apache.felix.sigil.eclipse.internal.model.repository;
 
+
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryType;
 import org.eclipse.swt.graphics.Image;
 
-public class RepositoryType implements IRepositoryType {
-	private String type;
-	private String id;
-	private Image icon;
-	private boolean dynamic;
-	
-	public RepositoryType(String id, String type, boolean dynamic,
-			Image icon) {
-		this.id = id;
-		this.type = type;
-		this.dynamic = dynamic;
-		this.icon = icon;
-	}
 
-	public String getType() {
-		return type;
-	}
+public class RepositoryType implements IRepositoryType
+{
+    private String type;
+    private String id;
+    private Image icon;
+    private boolean dynamic;
 
-	public String getId() {
-		return id;
-	}
 
-	public Image getIcon() {
-		return icon;
-	}
+    public RepositoryType( String id, String type, boolean dynamic, Image icon )
+    {
+        this.id = id;
+        this.type = type;
+        this.dynamic = dynamic;
+        this.icon = icon;
+    }
 
-	public boolean isDynamic() {
-		return dynamic;
-	}
 
-	@Override
-	public boolean equals(Object obj) {
-		try {
-			RepositoryType t = (RepositoryType) obj;
-			return t.id.equals( id );
-		}
-		catch (ClassCastException e) {
-			return false;
-		}
-	}
+    public String getType()
+    {
+        return type;
+    }
 
-	@Override
-	public int hashCode() {
-		return id.hashCode();
-	}
 
-	@Override
-	public String toString() {
-		return type;
-	}
+    public String getId()
+    {
+        return id;
+    }
+
+
+    public Image getIcon()
+    {
+        return icon;
+    }
+
+
+    public boolean isDynamic()
+    {
+        return dynamic;
+    }
+
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        try
+        {
+            RepositoryType t = ( RepositoryType ) obj;
+            return t.id.equals( id );
+        }
+        catch ( ClassCastException e )
+        {
+            return false;
+        }
+    }
+
+
+    @Override
+    public int hashCode()
+    {
+        return id.hashCode();
+    }
+
+
+    @Override
+    public String toString()
+    {
+        return type;
+    }
 }
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/eclipse/GlobalRepositoryManager.java
index 51bff92..25d84ef 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/eclipse/GlobalRepositoryManager.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.internal.repository.eclipse;
 
+
 import java.util.List;
 
 import org.apache.felix.sigil.eclipse.SigilCore;
@@ -26,17 +27,21 @@
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
 import org.apache.felix.sigil.repository.IRepositoryManager;
 
-public class GlobalRepositoryManager extends SigilRepositoryManager implements
-		IRepositoryManager {
 
-	public GlobalRepositoryManager() {
-		super(null);
-	}
+public class GlobalRepositoryManager extends SigilRepositoryManager implements IRepositoryManager
+{
 
-	@Override
-	protected IRepositoryModel[] findRepositories() {
-		List<IRepositoryModel> repos = SigilCore.getRepositoryConfiguration().loadRepositories();
-		return repos.toArray( new IRepositoryModel[repos.size()]);
-	}
+    public GlobalRepositoryManager()
+    {
+        super( null );
+    }
+
+
+    @Override
+    protected IRepositoryModel[] findRepositories()
+    {
+        List<IRepositoryModel> repos = SigilCore.getRepositoryConfiguration().loadRepositories();
+        return repos.toArray( new IRepositoryModel[repos.size()] );
+    }
 
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/OSGiInstallRepository.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/OSGiInstallRepository.java
index 7747dc9..8dc8461 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/OSGiInstallRepository.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/OSGiInstallRepository.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.internal.repository.eclipse;
 
+
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -40,96 +41,130 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
 
-public class OSGiInstallRepository extends AbstractBundleRepository {
-	
-	private Map<String,List<ISigilBundle>> bundles;
-	
-	public OSGiInstallRepository(String id) {
-		super(id);
-	}
-	
-	public void refresh() {
-		synchronized( this ) {
-			bundles = null;
-		}
-		
-		notifyChange();		
-	}
-	
-	@Override
-	public void accept(IRepositoryVisitor visitor, int options) {
-		IOSGiInstall install = SigilCore.getInstallManager().getDefaultInstall();
 
-		if ( install != null ) {
-			List<ISigilBundle> found = null;
+public class OSGiInstallRepository extends AbstractBundleRepository
+{
 
-			synchronized( this ) {
-				found = bundles == null ? null : bundles.get( install.getId() );
-			}
+    private Map<String, List<ISigilBundle>> bundles;
 
-			if ( found == null )  {
-				found = new ArrayList<ISigilBundle>();
-				IPath source = install.getType().getSourceLocation();
-				
-				for ( IPath p : install.getType().getDefaultBundleLocations() ) {
-					loadBundle( p, found, source );
-				}
 
-				synchronized( this ) {
-					bundles = new HashMap<String, List<ISigilBundle>>();
-					bundles.put( install.getId(), found );
-				}
-			}
+    public OSGiInstallRepository( String id )
+    {
+        super( id );
+    }
 
-			for ( ISigilBundle b : found ) {
-				if ( !visitor.visit(b) ) {
-					break;
-				}
-			}
-		}
-	}
 
-	private void loadBundle(IPath p, List<ISigilBundle> bundles, IPath source) {
-		File f = p.toFile();
-		JarFile jar = null;
-		try {
-			jar = new JarFile(f);
-			ISigilBundle bundle = buildBundle(jar.getManifest(), f );
-			if ( bundle != null ) {
-				bundle.setLocation(p);
-				bundle.setSourcePathLocation( source );
-				bundle.setSourceRootPath( new Path( "src" ) );
-				bundles.add( bundle );
-			}
-		} catch (IOException e) {
-			BldCore.error( "Failed to read jar file " + f, e );
-		} catch (ModelElementFactoryException e) {
-			BldCore.error( "Failed to build bundle " + f , e );
-		} catch (RuntimeException e) {
-			BldCore.error( "Failed to build bundle " + f , e );
-		}
-		finally {
-			if ( jar != null ) {
-				try {
-					jar.close();
-				} catch (IOException e) {
-					BldCore.error( "Failed to close jar file", e );
-				}
-			}
-		}
-	}
+    public void refresh()
+    {
+        synchronized ( this )
+        {
+            bundles = null;
+        }
 
-	private ISigilBundle buildBundle(Manifest manifest, File f) {
-		IBundleModelElement info = buildBundleModelElement( manifest );
+        notifyChange();
+    }
 
-		ISigilBundle bundle = null;
 
-		if ( info != null ) {
-			bundle = ModelElementFactory.getInstance().newModelElement( ISigilBundle.class );
-			bundle.addChild(info);
-			bundle.setLocation( new Path( f.getAbsolutePath() ) );
-		}
+    @Override
+    public void accept( IRepositoryVisitor visitor, int options )
+    {
+        IOSGiInstall install = SigilCore.getInstallManager().getDefaultInstall();
 
-		return bundle;
-	}
+        if ( install != null )
+        {
+            List<ISigilBundle> found = null;
+
+            synchronized ( this )
+            {
+                found = bundles == null ? null : bundles.get( install.getId() );
+            }
+
+            if ( found == null )
+            {
+                found = new ArrayList<ISigilBundle>();
+                IPath source = install.getType().getSourceLocation();
+
+                for ( IPath p : install.getType().getDefaultBundleLocations() )
+                {
+                    loadBundle( p, found, source );
+                }
+
+                synchronized ( this )
+                {
+                    bundles = new HashMap<String, List<ISigilBundle>>();
+                    bundles.put( install.getId(), found );
+                }
+            }
+
+            for ( ISigilBundle b : found )
+            {
+                if ( !visitor.visit( b ) )
+                {
+                    break;
+                }
+            }
+        }
+    }
+
+
+    private void loadBundle( IPath p, List<ISigilBundle> bundles, IPath source )
+    {
+        File f = p.toFile();
+        JarFile jar = null;
+        try
+        {
+            jar = new JarFile( f );
+            ISigilBundle bundle = buildBundle( jar.getManifest(), f );
+            if ( bundle != null )
+            {
+                bundle.setLocation( p );
+                bundle.setSourcePathLocation( source );
+                bundle.setSourceRootPath( new Path( "src" ) );
+                bundles.add( bundle );
+            }
+        }
+        catch ( IOException e )
+        {
+            BldCore.error( "Failed to read jar file " + f, e );
+        }
+        catch ( ModelElementFactoryException e )
+        {
+            BldCore.error( "Failed to build bundle " + f, e );
+        }
+        catch ( RuntimeException e )
+        {
+            BldCore.error( "Failed to build bundle " + f, e );
+        }
+        finally
+        {
+            if ( jar != null )
+            {
+                try
+                {
+                    jar.close();
+                }
+                catch ( IOException e )
+                {
+                    BldCore.error( "Failed to close jar file", e );
+                }
+            }
+        }
+    }
+
+
+    private ISigilBundle buildBundle( Manifest manifest, File f )
+    {
+        IBundleModelElement info = buildBundleModelElement( manifest );
+
+        ISigilBundle bundle = null;
+
+        if ( info != null )
+        {
+            bundle = ModelElementFactory.getInstance().newModelElement( ISigilBundle.class );
+            bundle.addChild( info );
+            bundle.setLocation( new Path( f.getAbsolutePath() ) );
+        }
+
+        return bundle;
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/OSGiInstallRepositoryProvider.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/OSGiInstallRepositoryProvider.java
index 0d76fe8..d33da0f 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/OSGiInstallRepositoryProvider.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/OSGiInstallRepositoryProvider.java
@@ -19,13 +19,17 @@
 
 package org.apache.felix.sigil.eclipse.internal.repository.eclipse;
 
+
 import java.util.Properties;
 
 import org.apache.felix.sigil.repository.IBundleRepository;
 import org.apache.felix.sigil.repository.IRepositoryProvider;
 
-public class OSGiInstallRepositoryProvider implements IRepositoryProvider {
-	public IBundleRepository createRepository(String id, Properties preferences) {
-		return new OSGiInstallRepository(id);
-	}
+
+public class OSGiInstallRepositoryProvider implements IRepositoryProvider
+{
+    public IBundleRepository createRepository( String id, Properties preferences )
+    {
+        return new OSGiInstallRepository( id );
+    }
 }
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
index 8bd1095..0ce36d1 100644
--- 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
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.internal.repository.eclipse;
 
+
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -47,146 +48,197 @@
 import org.eclipse.jface.util.IPropertyChangeListener;
 import org.eclipse.jface.util.PropertyChangeEvent;
 
-public class SigilRepositoryManager extends AbstractRepositoryManager implements IRepositoryManager, IPropertyChangeListener {
-	
-	private final String repositorySet;
-	
-	private HashMap<String, RepositoryCache> cachedRepositories = new HashMap<String, RepositoryCache>();
-	
-	class RepositoryCache {
-		private final Properties pref;
-		private final IBundleRepository repo;
 
-		RepositoryCache(Properties pref, IBundleRepository repo) {
-			this.pref = pref;
-			this.repo = repo;
-		}
-	}
-	
-	public SigilRepositoryManager(String repositorySet) {
-		this.repositorySet = repositorySet;
-	}
-	
-	@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>();
-		
-		for ( IRepositoryModel repo : findRepositories() ) {
-			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);
-			}
-		}
+public class SigilRepositoryManager extends AbstractRepositoryManager implements IRepositoryManager,
+    IPropertyChangeListener
+{
 
-		setRepositories(repos.toArray( new IBundleRepository[repos.size()] ) );
-		
-		for ( Iterator<String> i = cachedRepositories.keySet().iterator(); i.hasNext(); ) {
-			if ( !ids.contains(i.next()) ) {
-				i.remove();
-			}
-		}
-	}
+    private final String repositorySet;
 
-	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;
-				}
-			}
-		}
+    private HashMap<String, RepositoryCache> cachedRepositories = new HashMap<String, RepositoryCache>();
 
-		return null;
-	}
+    class RepositoryCache
+    {
+        private final Properties pref;
+        private final IBundleRepository repo;
 
-	protected IRepositoryModel[] findRepositories() {
-		if ( repositorySet == null ) {
-			return SigilCore.getRepositoryConfiguration().getDefaultRepositorySet().getRepositories();
-		}
-		else {
-			IRepositorySet set = SigilCore.getRepositoryConfiguration().getRepositorySet(repositorySet);
-			return set.getRepositories();
-		}	
-	}
 
-	private IBundleRepository loadRepository(String id, Properties pref, IRepositoryProvider provider) throws RepositoryException {
-		try {
-			if ( pref == null ) {
-				pref = new Properties();
-			}
+        RepositoryCache( Properties pref, IBundleRepository repo )
+        {
+            this.pref = pref;
+            this.repo = repo;
+        }
+    }
 
-			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();
-		}
-	}	
+    public SigilRepositoryManager( String repositorySet )
+    {
+        this.repositorySet = repositorySet;
+    }
+
+
+    @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>();
+
+        for ( IRepositoryModel repo : findRepositories() )
+        {
+            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()] ) );
+
+        for ( Iterator<String> i = cachedRepositories.keySet().iterator(); i.hasNext(); )
+        {
+            if ( !ids.contains( i.next() ) )
+            {
+                i.remove();
+            }
+        }
+    }
+
+
+    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 IRepositoryModel[] findRepositories()
+    {
+        if ( repositorySet == null )
+        {
+            return SigilCore.getRepositoryConfiguration().getDefaultRepositorySet().getRepositories();
+        }
+        else
+        {
+            IRepositorySet set = SigilCore.getRepositoryConfiguration().getRepositorySet( repositorySet );
+            return set.getRepositories();
+        }
+    }
+
+
+    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/eclipse/WorkspaceRepository.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/WorkspaceRepository.java
index 076261e..43218b0 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/WorkspaceRepository.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/WorkspaceRepository.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.internal.repository.eclipse;
 
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -36,91 +37,126 @@
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.runtime.CoreException;
 
-public class WorkspaceRepository extends AbstractBundleRepository implements IResourceChangeListener {
-	
-	private static final int UPDATE_MASK = IResourceDelta.CONTENT | IResourceDelta.DESCRIPTION | IResourceDelta.OPEN;
-	private ISigilBundle[] bundles;
-	
-	public WorkspaceRepository(String id) {
-		super(id);
-	}
 
-	@Override
-	public void accept(IRepositoryVisitor visitor, int options) {
-		synchronized( this ) {
-			if ( bundles == null ) {
-				List<ISigilProjectModel> models = SigilCore.getRoot().getProjects();
-				ArrayList<ISigilBundle> tmp = new ArrayList<ISigilBundle>(models.size());
-				for ( ISigilProjectModel n : models ) {
-					ISigilBundle b = n.getBundle();
-					tmp.add(b);
-				}
-				bundles = tmp.toArray( new ISigilBundle[tmp.size()] );
-			}
-		}
-		
-		for ( ISigilBundle b : bundles ) {
-			visitor.visit(b);
-		}
-	}
-	
-	public void refresh() {
-		synchronized(this) {
-			bundles = null;
-		}
-	}
-	
-	@Override
-	protected void notifyChange() {
-		refresh();
-		super.notifyChange();
-	}
+public class WorkspaceRepository extends AbstractBundleRepository implements IResourceChangeListener
+{
 
-	public void resourceChanged(IResourceChangeEvent event) {
-		try {
-			event.getDelta().accept( new IResourceDeltaVisitor() {
-				public boolean visit(IResourceDelta delta) throws CoreException {
-					boolean result;
-					
-					IResource resource = delta.getResource();
-					if(resource instanceof IWorkspaceRoot) {
-						result = true;
-					} else if(resource instanceof IProject) {
-						IProject project = (IProject) resource;
-						if ( SigilCore.isSigilProject(project) ) {
-							switch (delta.getKind()) {
-							case IResourceDelta.CHANGED: 
-								if ( (delta.getFlags() & UPDATE_MASK) == 0 ) {
-									break;
-								}
-								// else 
-								// fall through on purpose
-							case IResourceDelta.ADDED: // fall through on purpose
-							case IResourceDelta.REMOVED: // fall through on purpose
-								notifyChange();
-								break;
-							}
-							result = true;
-						} else {
-							result = false;
-						}
-					} else if(resource.getName().equals(SigilCore.SIGIL_PROJECT_FILE)) {
-						switch(delta.getKind()) {
-						case IResourceDelta.CHANGED:
-						case IResourceDelta.ADDED:
-						case IResourceDelta.REMOVED:
-							notifyChange();
-						}
-						result = false;
-					} else {
-						result = false;
-					}
- 					return result;
-				}
-			});
-		} catch (CoreException e) {
-			SigilCore.error( "Workspace repository update failed", e ); 
-		}
-	}
+    private static final int UPDATE_MASK = IResourceDelta.CONTENT | IResourceDelta.DESCRIPTION | IResourceDelta.OPEN;
+    private ISigilBundle[] bundles;
+
+
+    public WorkspaceRepository( String id )
+    {
+        super( id );
+    }
+
+
+    @Override
+    public void accept( IRepositoryVisitor visitor, int options )
+    {
+        synchronized ( this )
+        {
+            if ( bundles == null )
+            {
+                List<ISigilProjectModel> models = SigilCore.getRoot().getProjects();
+                ArrayList<ISigilBundle> tmp = new ArrayList<ISigilBundle>( models.size() );
+                for ( ISigilProjectModel n : models )
+                {
+                    ISigilBundle b = n.getBundle();
+                    tmp.add( b );
+                }
+                bundles = tmp.toArray( new ISigilBundle[tmp.size()] );
+            }
+        }
+
+        for ( ISigilBundle b : bundles )
+        {
+            visitor.visit( b );
+        }
+    }
+
+
+    public void refresh()
+    {
+        synchronized ( this )
+        {
+            bundles = null;
+        }
+    }
+
+
+    @Override
+    protected void notifyChange()
+    {
+        refresh();
+        super.notifyChange();
+    }
+
+
+    public void resourceChanged( IResourceChangeEvent event )
+    {
+        try
+        {
+            event.getDelta().accept( new IResourceDeltaVisitor()
+            {
+                public boolean visit( IResourceDelta delta ) throws CoreException
+                {
+                    boolean result;
+
+                    IResource resource = delta.getResource();
+                    if ( resource instanceof IWorkspaceRoot )
+                    {
+                        result = true;
+                    }
+                    else if ( resource instanceof IProject )
+                    {
+                        IProject project = ( IProject ) resource;
+                        if ( SigilCore.isSigilProject( project ) )
+                        {
+                            switch ( delta.getKind() )
+                            {
+                                case IResourceDelta.CHANGED:
+                                    if ( ( delta.getFlags() & UPDATE_MASK ) == 0 )
+                                    {
+                                        break;
+                                    }
+                                    // else 
+                                    // fall through on purpose
+                                case IResourceDelta.ADDED: // fall through on purpose
+                                case IResourceDelta.REMOVED: // fall through on purpose
+                                    notifyChange();
+                                    break;
+                            }
+                            result = true;
+                        }
+                        else
+                        {
+                            result = false;
+                        }
+                    }
+                    else if ( resource.getName().equals( SigilCore.SIGIL_PROJECT_FILE ) )
+                    {
+                        switch ( delta.getKind() )
+                        {
+                            case IResourceDelta.CHANGED:
+                            case IResourceDelta.ADDED:
+                            case IResourceDelta.REMOVED:
+                                notifyChange();
+                        }
+                        result = false;
+                    }
+                    else
+                    {
+                        result = false;
+                    }
+                    return result;
+                }
+            } );
+        }
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Workspace repository update failed", e );
+        }
+    }
 
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/WorkspaceRepositoryProvider.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/WorkspaceRepositoryProvider.java
index 3a2744c..d03bef4 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/WorkspaceRepositoryProvider.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/internal/repository/eclipse/WorkspaceRepositoryProvider.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.internal.repository.eclipse;
 
+
 import java.util.Properties;
 
 import org.apache.felix.sigil.repository.IBundleRepository;
@@ -26,18 +27,25 @@
 import org.eclipse.core.resources.IResourceChangeEvent;
 import org.eclipse.core.resources.ResourcesPlugin;
 
-public class WorkspaceRepositoryProvider implements IRepositoryProvider {
-	private static WorkspaceRepository repository;
-	
-	public static WorkspaceRepository getWorkspaceRepository() {
-		return repository;	
-	}
-	
-	public IBundleRepository createRepository(String id, Properties preferences) {
-		if ( repository == null ) {
-			repository = new WorkspaceRepository(id);
-			ResourcesPlugin.getWorkspace().addResourceChangeListener(repository, IResourceChangeEvent.POST_CHANGE);
-		}
-		return repository;
-	}
+
+public class WorkspaceRepositoryProvider implements IRepositoryProvider
+{
+    private static WorkspaceRepository repository;
+
+
+    public static WorkspaceRepository getWorkspaceRepository()
+    {
+        return repository;
+    }
+
+
+    public IBundleRepository createRepository( String id, Properties preferences )
+    {
+        if ( repository == null )
+        {
+            repository = new WorkspaceRepository( id );
+            ResourcesPlugin.getWorkspace().addResourceChangeListener( repository, IResourceChangeEvent.POST_CHANGE );
+        }
+        return repository;
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ResolveProjectsJob.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ResolveProjectsJob.java
index f2280e8..d1f869f 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ResolveProjectsJob.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ResolveProjectsJob.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.job;
 
+
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Set;
@@ -45,101 +46,134 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
 
-public class ResolveProjectsJob extends Job {
-	
-	private final IWorkspace workspace;
-	private final IProject project;
-	
-	public ResolveProjectsJob(IWorkspace workspace) {
-		super("Resolving Sigil projects");
-		this.workspace = workspace;
-		this.project = null;
-		setRule(ResourcesPlugin.getWorkspace().getRoot());
-	}
-	
-	public ResolveProjectsJob(IProject project) {
-		super("Resolving Sigil project");
-		this.workspace = null;
-		this.project = project;
-		setRule(project.getFile(SigilCore.SIGIL_PROJECT_FILE));
-	}
-	
-	@Override
-	protected IStatus run(IProgressMonitor monitor) {
-		MultiStatus status = new MultiStatus(SigilCore.PLUGIN_ID, 0, "Error resolving Sigil projects", null);
-		
-		Collection<ISigilProjectModel> sigilProjects = null;
-		
-		if(workspace != null) {
-			sigilProjects = SigilCore.getRoot().getProjects();
-		} else if(project != null) {
-			try {
-				ISigilProjectModel sigilProject = SigilCore.create(project);
-				sigilProjects = Collections.singleton(sigilProject);
-			} catch (CoreException e) {
-				status.add(e.getStatus());
-			}
-		}
 
-		if ( sigilProjects != null ) {
-			for (ISigilProjectModel sigilProject : sigilProjects) {
-				try {
-					// Delete existing dependency markers on project
-					sigilProject.getProject().deleteMarkers(SigilCore.MARKER_UNRESOLVED_DEPENDENCY, true, IResource.DEPTH_ONE);
-					
-					IRepositoryManager repository = SigilCore.getRepositoryManager(sigilProject);
-					ResolutionMonitorAdapter resolutionMonitor = new ResolutionMonitorAdapter(monitor);
-		
-					IBundleResolver resolver = repository.getBundleResolver();
-					ResolutionConfig config = new ResolutionConfig(ResolutionConfig.IGNORE_ERRORS);
-					
-					// Execute resolver
-					IResolution resolution = resolver.resolve(sigilProject, config, resolutionMonitor);
-					
-					// Find missing imports
-					Set<IPackageImport> imports = sigilProject.getBundle().getBundleInfo().getImports();
-					for (IPackageImport pkgImport : imports) {
-						if(resolution.getProvider(pkgImport) == null) {
-							markMissingImport(pkgImport, sigilProject.getProject());
-						}
-					}
-					
-					// Find missing required bundles
-					Set<IRequiredBundle> requiredBundles = sigilProject.getBundle().getBundleInfo().getRequiredBundles();
-					for (IRequiredBundle requiredBundle : requiredBundles) {
-						if(resolution.getProvider(requiredBundle) == null) {
-							markMissingRequiredBundle(requiredBundle, sigilProject.getProject());
-						}
-					}
-				} catch (ResolutionException e) {
-					status.add(new Status(IStatus.ERROR, SigilCore.PLUGIN_ID, 0, "Error resolving project " + sigilProject.getProject().getName(), e));
-				} catch (CoreException e) {
-					status.add(e.getStatus());
-				}
-			}
-		}
-		
-		return status;
-	}
-	
-	private static void markMissingImport(IPackageImport pkgImport, IProject project) throws CoreException {
-		IMarker marker = project.getProject().createMarker(SigilCore.MARKER_UNRESOLVED_IMPORT_PACKAGE);
-		marker.setAttribute("element", pkgImport.getPackageName());
-		marker.setAttribute("versionRange", pkgImport.getVersions().toString());
-		marker.setAttribute(IMarker.MESSAGE, "Cannot resolve imported package \"" + pkgImport.getPackageName() + "\" with version range " + pkgImport.getVersions());
-		marker.setAttribute(IMarker.SEVERITY, pkgImport.isOptional() ? IMarker.SEVERITY_WARNING : IMarker.SEVERITY_ERROR);
-		marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
-	}
-	
-	private static void markMissingRequiredBundle(IRequiredBundle req, IProject project) throws CoreException {
-		IMarker marker = project.getProject().createMarker(SigilCore.MARKER_UNRESOLVED_REQUIRE_BUNDLE);
-		marker.setAttribute("element", req.getSymbolicName());
-		marker.setAttribute("versionRange", req.getVersions().toString());
-		marker.setAttribute(IMarker.MESSAGE, "Cannot resolve required bundle \"" + req.getSymbolicName() + "\" with version range " + req.getVersions());
-		marker.setAttribute(IMarker.SEVERITY, req.isOptional() ? IMarker.SEVERITY_WARNING : IMarker.SEVERITY_ERROR);
-		marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
-	}
-	
-	
+public class ResolveProjectsJob extends Job
+{
+
+    private final IWorkspace workspace;
+    private final IProject project;
+
+
+    public ResolveProjectsJob( IWorkspace workspace )
+    {
+        super( "Resolving Sigil projects" );
+        this.workspace = workspace;
+        this.project = null;
+        setRule( ResourcesPlugin.getWorkspace().getRoot() );
+    }
+
+
+    public ResolveProjectsJob( IProject project )
+    {
+        super( "Resolving Sigil project" );
+        this.workspace = null;
+        this.project = project;
+        setRule( project.getFile( SigilCore.SIGIL_PROJECT_FILE ) );
+    }
+
+
+    @Override
+    protected IStatus run( IProgressMonitor monitor )
+    {
+        MultiStatus status = new MultiStatus( SigilCore.PLUGIN_ID, 0, "Error resolving Sigil projects", null );
+
+        Collection<ISigilProjectModel> sigilProjects = null;
+
+        if ( workspace != null )
+        {
+            sigilProjects = SigilCore.getRoot().getProjects();
+        }
+        else if ( project != null )
+        {
+            try
+            {
+                ISigilProjectModel sigilProject = SigilCore.create( project );
+                sigilProjects = Collections.singleton( sigilProject );
+            }
+            catch ( CoreException e )
+            {
+                status.add( e.getStatus() );
+            }
+        }
+
+        if ( sigilProjects != null )
+        {
+            for ( ISigilProjectModel sigilProject : sigilProjects )
+            {
+                try
+                {
+                    // Delete existing dependency markers on project
+                    sigilProject.getProject().deleteMarkers( SigilCore.MARKER_UNRESOLVED_DEPENDENCY, true,
+                        IResource.DEPTH_ONE );
+
+                    IRepositoryManager repository = SigilCore.getRepositoryManager( sigilProject );
+                    ResolutionMonitorAdapter resolutionMonitor = new ResolutionMonitorAdapter( monitor );
+
+                    IBundleResolver resolver = repository.getBundleResolver();
+                    ResolutionConfig config = new ResolutionConfig( ResolutionConfig.IGNORE_ERRORS );
+
+                    // Execute resolver
+                    IResolution resolution = resolver.resolve( sigilProject, config, resolutionMonitor );
+
+                    // Find missing imports
+                    Set<IPackageImport> imports = sigilProject.getBundle().getBundleInfo().getImports();
+                    for ( IPackageImport pkgImport : imports )
+                    {
+                        if ( resolution.getProvider( pkgImport ) == null )
+                        {
+                            markMissingImport( pkgImport, sigilProject.getProject() );
+                        }
+                    }
+
+                    // Find missing required bundles
+                    Set<IRequiredBundle> requiredBundles = sigilProject.getBundle().getBundleInfo()
+                        .getRequiredBundles();
+                    for ( IRequiredBundle requiredBundle : requiredBundles )
+                    {
+                        if ( resolution.getProvider( requiredBundle ) == null )
+                        {
+                            markMissingRequiredBundle( requiredBundle, sigilProject.getProject() );
+                        }
+                    }
+                }
+                catch ( ResolutionException e )
+                {
+                    status.add( new Status( IStatus.ERROR, SigilCore.PLUGIN_ID, 0, "Error resolving project "
+                        + sigilProject.getProject().getName(), e ) );
+                }
+                catch ( CoreException e )
+                {
+                    status.add( e.getStatus() );
+                }
+            }
+        }
+
+        return status;
+    }
+
+
+    private static void markMissingImport( IPackageImport pkgImport, IProject project ) throws CoreException
+    {
+        IMarker marker = project.getProject().createMarker( SigilCore.MARKER_UNRESOLVED_IMPORT_PACKAGE );
+        marker.setAttribute( "element", pkgImport.getPackageName() );
+        marker.setAttribute( "versionRange", pkgImport.getVersions().toString() );
+        marker.setAttribute( IMarker.MESSAGE, "Cannot resolve imported package \"" + pkgImport.getPackageName()
+            + "\" with version range " + pkgImport.getVersions() );
+        marker.setAttribute( IMarker.SEVERITY, pkgImport.isOptional() ? IMarker.SEVERITY_WARNING
+            : IMarker.SEVERITY_ERROR );
+        marker.setAttribute( IMarker.PRIORITY, IMarker.PRIORITY_HIGH );
+    }
+
+
+    private static void markMissingRequiredBundle( IRequiredBundle req, IProject project ) throws CoreException
+    {
+        IMarker marker = project.getProject().createMarker( SigilCore.MARKER_UNRESOLVED_REQUIRE_BUNDLE );
+        marker.setAttribute( "element", req.getSymbolicName() );
+        marker.setAttribute( "versionRange", req.getVersions().toString() );
+        marker.setAttribute( IMarker.MESSAGE, "Cannot resolve required bundle \"" + req.getSymbolicName()
+            + "\" with version range " + req.getVersions() );
+        marker.setAttribute( IMarker.SEVERITY, req.isOptional() ? IMarker.SEVERITY_WARNING : IMarker.SEVERITY_ERROR );
+        marker.setAttribute( IMarker.PRIORITY, IMarker.PRIORITY_HIGH );
+    }
 
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ThreadProgressMonitor.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ThreadProgressMonitor.java
index 6d6989d..e60be3f 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ThreadProgressMonitor.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/job/ThreadProgressMonitor.java
@@ -19,16 +19,23 @@
 
 package org.apache.felix.sigil.eclipse.job;
 
+
 import org.eclipse.core.runtime.IProgressMonitor;
 
-public class ThreadProgressMonitor {
-	private static ThreadLocal<IProgressMonitor> local = new ThreadLocal<IProgressMonitor>();
-	
-	public static void setProgressMonitor(IProgressMonitor monitor) {
-		local.set(monitor);
-	}
-	
-	public static IProgressMonitor getProgressMonitor() {
-		return local.get();
-	}
+
+public class ThreadProgressMonitor
+{
+    private static ThreadLocal<IProgressMonitor> local = new ThreadLocal<IProgressMonitor>();
+
+
+    public static void setProgressMonitor( IProgressMonitor monitor )
+    {
+        local.set( monitor );
+    }
+
+
+    public static IProgressMonitor getProgressMonitor()
+    {
+        return local.get();
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilModelRoot.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilModelRoot.java
index e6a9a9a..4b9ca00 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilModelRoot.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilModelRoot.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.model.project;
 
+
 import java.util.Collection;
 import java.util.List;
 
@@ -27,10 +28,15 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 
-public interface ISigilModelRoot {
-	List<ISigilProjectModel> getProjects();
-	
-	Collection<ISigilProjectModel> resolveDependentProjects(ISigilProjectModel sigil, IProgressMonitor monitor);
 
-	Collection<ISigilBundle> resolveBundles(ISigilProjectModel sigil, IModelElement element, boolean includeOptional, IProgressMonitor monitor) throws CoreException;
+public interface ISigilModelRoot
+{
+    List<ISigilProjectModel> getProjects();
+
+
+    Collection<ISigilProjectModel> resolveDependentProjects( ISigilProjectModel sigil, IProgressMonitor monitor );
+
+
+    Collection<ISigilBundle> resolveBundles( ISigilProjectModel sigil, IModelElement element, boolean includeOptional,
+        IProgressMonitor monitor ) throws CoreException;
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilProjectModel.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilProjectModel.java
index f1a2b0a..5379ac6 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilProjectModel.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/project/ISigilProjectModel.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.model.project;
 
+
 import java.util.Collection;
 
 import org.apache.felix.sigil.config.IBldProject;
@@ -37,6 +38,7 @@
 import org.osgi.framework.Version;
 import org.osgi.service.prefs.Preferences;
 
+
 /**
  * Represents a sigil project. To get a reference to a ISigilProjectModel you can use the 
  * helper method {@link BldCore#create(IProject)}.
@@ -44,62 +46,81 @@
  * @author dave
  *
  */
-public interface ISigilProjectModel extends ICompoundModelElement {
-    
+public interface ISigilProjectModel extends ICompoundModelElement
+{
+
     /**
      * @return
      */
     IProject getProject();
-	
-	// shortcut to getProject().getName()
-	String getName();
-	
-	Preferences getPreferences();
-    
+
+
+    // shortcut to getProject().getName()
+    String getName();
+
+
+    Preferences getPreferences();
+
+
     /**
-	 * 
-	 * @param monitor
-	 *            The progress monitor to use for reporting progress to the
-	 *            user. It is the caller's responsibility to call done() on the
-	 *            given monitor. Accepts null, indicating that no progress
-	 *            should be reported and that the operation cannot be cancelled
-	 * @throws CoreException
-	 */
-	void save(IProgressMonitor monitor) throws CoreException;
-    
-	/**
-	 * @return
-	 */
-	Version getVersion();
-	    
-	String getSymbolicName();
-	
-	ISigilBundle getBundle();
-	
-	void setBundle(ISigilBundle bundle);
-	
-	/**
-	 * @return
-	 */
-	IJavaProject getJavaModel();
-	
-	Collection<ISigilProjectModel> findDependentProjects(IProgressMonitor monitor);
+     * 
+     * @param monitor
+     *            The progress monitor to use for reporting progress to the
+     *            user. It is the caller's responsibility to call done() on the
+     *            given monitor. Accepts null, indicating that no progress
+     *            should be reported and that the operation cannot be cancelled
+     * @throws CoreException
+     */
+    void save( IProgressMonitor monitor ) throws CoreException;
 
-	void resetClasspath(IProgressMonitor monitor) throws CoreException;
-	
-	IPath findBundleLocation() throws CoreException;
 
-	IModelElement findImport(String packageName, IProgressMonitor monitor);
+    /**
+     * @return
+     */
+    Version getVersion();
 
-	boolean isInClasspath(String packageName, IProgressMonitor monitor) throws CoreException;
 
-	boolean isInClasspath(ISigilBundle bundle);
-	
-	boolean isInBundleClasspath(IPackageFragmentRoot root) throws JavaModelException;
-	
-	IPath findOutputLocation() throws CoreException;
+    String getSymbolicName();
 
-	IBldProject getBldProject() throws CoreException;
 
-	Collection<IClasspathEntry> findExternalClasspath(IProgressMonitor monitor) throws CoreException;
+    ISigilBundle getBundle();
+
+
+    void setBundle( ISigilBundle bundle );
+
+
+    /**
+     * @return
+     */
+    IJavaProject getJavaModel();
+
+
+    Collection<ISigilProjectModel> findDependentProjects( IProgressMonitor monitor );
+
+
+    void resetClasspath( IProgressMonitor monitor ) throws CoreException;
+
+
+    IPath findBundleLocation() throws CoreException;
+
+
+    IModelElement findImport( String packageName, IProgressMonitor monitor );
+
+
+    boolean isInClasspath( String packageName, IProgressMonitor monitor ) throws CoreException;
+
+
+    boolean isInClasspath( ISigilBundle bundle );
+
+
+    boolean isInBundleClasspath( IPackageFragmentRoot root ) throws JavaModelException;
+
+
+    IPath findOutputLocation() throws CoreException;
+
+
+    IBldProject getBldProject() throws CoreException;
+
+
+    Collection<IClasspathEntry> findExternalClasspath( IProgressMonitor monitor ) throws CoreException;
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryConfiguration.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryConfiguration.java
index 66487a4..bcba18b 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryConfiguration.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositoryConfiguration.java
@@ -19,31 +19,43 @@
 
 package org.apache.felix.sigil.eclipse.model.repository;
 
+
 import java.util.List;
 import java.util.Map;
 
 import org.apache.felix.sigil.eclipse.internal.model.repository.RepositoryType;
 import org.eclipse.core.runtime.CoreException;
 
-public interface IRepositoryConfiguration {
 
-	List<IRepositoryModel> loadRepositories();
-	
-	IRepositoryModel findRepository(String id);
+public interface IRepositoryConfiguration
+{
 
-	void saveRepositories(List<IRepositoryModel> repositories) throws CoreException;
+    List<IRepositoryModel> loadRepositories();
 
-	List<RepositoryType> loadRepositoryTypes();
 
-	IRepositoryModel newRepositoryElement(IRepositoryType type);
-	
-	IRepositorySet getDefaultRepositorySet();
+    IRepositoryModel findRepository( String id );
 
-	void setDefaultRepositorySet(IRepositorySet defaultSet);
-	
-	IRepositorySet getRepositorySet(String name);
-	
-	Map<String, IRepositorySet> loadRepositorySets();
-	
-	void saveRepositorySets(Map<String, IRepositorySet> sets);
+
+    void saveRepositories( List<IRepositoryModel> repositories ) throws CoreException;
+
+
+    List<RepositoryType> loadRepositoryTypes();
+
+
+    IRepositoryModel newRepositoryElement( IRepositoryType type );
+
+
+    IRepositorySet getDefaultRepositorySet();
+
+
+    void setDefaultRepositorySet( IRepositorySet defaultSet );
+
+
+    IRepositorySet getRepositorySet( String name );
+
+
+    Map<String, IRepositorySet> loadRepositorySets();
+
+
+    void saveRepositorySets( Map<String, IRepositorySet> sets );
 }
\ No newline at end of file
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 70fc90d..37f2649 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,17 +19,24 @@
 
 package org.apache.felix.sigil.eclipse.model.repository;
 
+
 import org.eclipse.jface.preference.PreferenceStore;
 
-public interface IRepositoryModel {
 
-	String getId();
+public interface IRepositoryModel
+{
 
-	void setName(String stringValue);
-	
-	String getName();
+    String getId();
 
-	PreferenceStore getPreferences();
 
-	IRepositoryType getType();
+    void setName( String stringValue );
+
+
+    String getName();
+
+
+    PreferenceStore getPreferences();
+
+
+    IRepositoryType getType();
 }
\ No newline at end of file
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositorySet.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositorySet.java
index acd6523..d28f5e2 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositorySet.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/IRepositorySet.java
@@ -19,9 +19,17 @@
 
 package org.apache.felix.sigil.eclipse.model.repository;
 
-public interface IRepositorySet {
-	void setRepository(IRepositoryModel id, int position);
-	void removeRepository(IRepositoryModel id);
-	IRepositoryModel[] getRepositories();
-	void setRepositories(IRepositoryModel[] repositories);
+
+public interface IRepositorySet
+{
+    void setRepository( IRepositoryModel id, int position );
+
+
+    void removeRepository( IRepositoryModel id );
+
+
+    IRepositoryModel[] getRepositories();
+
+
+    void setRepositories( IRepositoryModel[] repositories );
 }
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 ed673fb..f25f2d8 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
@@ -19,16 +19,22 @@
 
 package org.apache.felix.sigil.eclipse.model.repository;
 
+
 import org.eclipse.swt.graphics.Image;
 
-public interface IRepositoryType {
 
-	String getType();
+public interface IRepositoryType
+{
 
-	String getId();
+    String getType();
 
-	Image getIcon();
 
-	boolean isDynamic();
+    String getId();
+
+
+    Image getIcon();
+
+
+    boolean isDynamic();
 
 }
\ No newline at end of file
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/RepositorySet.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/RepositorySet.java
index 557cb77..c3cb1a6 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/RepositorySet.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/repository/RepositorySet.java
@@ -19,45 +19,62 @@
 
 package org.apache.felix.sigil.eclipse.model.repository;
 
+
 import java.util.ArrayList;
 import java.util.Collection;
 
-public class RepositorySet implements IRepositorySet {
 
-	private static final IRepositoryModel[] EMPTY = new IRepositoryModel[0];
-	
-	private IRepositoryModel[] reps;
+public class RepositorySet implements IRepositorySet
+{
 
-	public RepositorySet() {
-		this( EMPTY );
-	}
-	
-	public RepositorySet(Collection<IRepositoryModel> reps) {
-		this( reps.toArray( new IRepositoryModel[reps.size()] ) );
-	}
+    private static final IRepositoryModel[] EMPTY = new IRepositoryModel[0];
 
-	public RepositorySet(IRepositoryModel[] repositories) {
-		this.reps = repositories;
-	}
-	
-	public void setRepository(IRepositoryModel id, int position) {
-		ArrayList<IRepositoryModel> tmp = new ArrayList<IRepositoryModel>(reps.length + 1);
-		tmp.remove(id);
-		tmp.add(position, id);
-		reps = tmp.toArray( new IRepositoryModel[tmp.size()] );
-	}
+    private IRepositoryModel[] reps;
 
-	public IRepositoryModel[] getRepositories() {
-		return reps;
-	}
 
-	public void removeRepository(IRepositoryModel id) {
-		ArrayList<IRepositoryModel> tmp = new ArrayList<IRepositoryModel>(reps.length + 1);
-		tmp.remove(id);
-		reps = tmp.toArray( new IRepositoryModel[tmp.size()] );
-	}
+    public RepositorySet()
+    {
+        this( EMPTY );
+    }
 
-	public void setRepositories(IRepositoryModel[] repositories) {
-		reps = repositories == null ? EMPTY : repositories;
-	}
+
+    public RepositorySet( Collection<IRepositoryModel> reps )
+    {
+        this( reps.toArray( new IRepositoryModel[reps.size()] ) );
+    }
+
+
+    public RepositorySet( IRepositoryModel[] repositories )
+    {
+        this.reps = repositories;
+    }
+
+
+    public void setRepository( IRepositoryModel id, int position )
+    {
+        ArrayList<IRepositoryModel> tmp = new ArrayList<IRepositoryModel>( reps.length + 1 );
+        tmp.remove( id );
+        tmp.add( position, id );
+        reps = tmp.toArray( new IRepositoryModel[tmp.size()] );
+    }
+
+
+    public IRepositoryModel[] getRepositories()
+    {
+        return reps;
+    }
+
+
+    public void removeRepository( IRepositoryModel id )
+    {
+        ArrayList<IRepositoryModel> tmp = new ArrayList<IRepositoryModel>( reps.length + 1 );
+        tmp.remove( id );
+        reps = tmp.toArray( new IRepositoryModel[tmp.size()] );
+    }
+
+
+    public void setRepositories( IRepositoryModel[] repositories )
+    {
+        reps = repositories == null ? EMPTY : repositories;
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/Grep.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/Grep.java
index 009f2f1..036f06c 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/Grep.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/Grep.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.model.util;
 
+
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.nio.CharBuffer;
@@ -34,75 +35,92 @@
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.CoreException;
 
-public class Grep {
 
-	// Pattern used to parse lines
-	private static Pattern linePattern = Pattern.compile(".*\r?\n");
-	
-	// The input pattern that we're looking for
-	private Pattern pattern;
-	
-	private CharBuffer cb;
+public class Grep
+{
 
-	private FileChannel fc;
-	
-	private Grep(IFile f, Pattern pattern) throws IOException, CoreException {
-		this.pattern = pattern;
-		cb = openBuffer(f);			
-	}
-	
-	private CharBuffer openBuffer(IFile f) throws IOException, CoreException {
-		Charset charset = Charset.forName(f.getCharset());
-		CharsetDecoder decoder = charset.newDecoder();
-		// Open the file and then get a channel from the stream
-		FileInputStream fis = new FileInputStream(f.getLocation().toFile());
-		fc = fis.getChannel();
+    // Pattern used to parse lines
+    private static Pattern linePattern = Pattern.compile( ".*\r?\n" );
 
-		// Get the file's size and then map it into memory
-		int sz = (int) fc.size();
-		MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
+    // The input pattern that we're looking for
+    private Pattern pattern;
 
-		// Decode the file into a char buffer
-		return decoder.decode(bb);
-	}
+    private CharBuffer cb;
 
-	public static String[] grep(Pattern pattern, IFile...files) throws CoreException {
-		LinkedList<String> matches = new LinkedList<String>();
-		for ( IFile f : files ) {
-			try {
-				Grep g = new Grep( f, pattern );
-				g.grep(matches);
-				g.close();
-			} catch (IOException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-		}
-		return matches.toArray( new String[matches.size()]);
-	}
+    private FileChannel fc;
 
-	private void close() throws IOException {
-		fc.close();
-	}
 
-	// Use the linePattern to break the given CharBuffer into lines, applying
-	// the input pattern to each line to see if we have a match
-	//
-	private void grep(List<String> matches) {
-		Matcher lm = linePattern.matcher(cb); // Line matcher
-		Matcher pm = null; // Pattern matcher
-		int lines = 0;
-		while (lm.find()) {
-			lines++;
-			CharSequence cs = lm.group(); // The current line
-			if (pm == null)
-				pm = pattern.matcher(cs);
-			else
-				pm.reset(cs);
-			if (pm.find())
-				matches.add(pm.group());
-			if (lm.end() == cb.limit())
-				break;
-		}		
-	}
+    private Grep( IFile f, Pattern pattern ) throws IOException, CoreException
+    {
+        this.pattern = pattern;
+        cb = openBuffer( f );
+    }
+
+
+    private CharBuffer openBuffer( IFile f ) throws IOException, CoreException
+    {
+        Charset charset = Charset.forName( f.getCharset() );
+        CharsetDecoder decoder = charset.newDecoder();
+        // Open the file and then get a channel from the stream
+        FileInputStream fis = new FileInputStream( f.getLocation().toFile() );
+        fc = fis.getChannel();
+
+        // Get the file's size and then map it into memory
+        int sz = ( int ) fc.size();
+        MappedByteBuffer bb = fc.map( FileChannel.MapMode.READ_ONLY, 0, sz );
+
+        // Decode the file into a char buffer
+        return decoder.decode( bb );
+    }
+
+
+    public static String[] grep( Pattern pattern, IFile... files ) throws CoreException
+    {
+        LinkedList<String> matches = new LinkedList<String>();
+        for ( IFile f : files )
+        {
+            try
+            {
+                Grep g = new Grep( f, pattern );
+                g.grep( matches );
+                g.close();
+            }
+            catch ( IOException e )
+            {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+        return matches.toArray( new String[matches.size()] );
+    }
+
+
+    private void close() throws IOException
+    {
+        fc.close();
+    }
+
+
+    // Use the linePattern to break the given CharBuffer into lines, applying
+    // the input pattern to each line to see if we have a match
+    //
+    private void grep( List<String> matches )
+    {
+        Matcher lm = linePattern.matcher( cb ); // Line matcher
+        Matcher pm = null; // Pattern matcher
+        int lines = 0;
+        while ( lm.find() )
+        {
+            lines++;
+            CharSequence cs = lm.group(); // The current line
+            if ( pm == null )
+                pm = pattern.matcher( cs );
+            else
+                pm.reset( cs );
+            if ( pm.find() )
+                matches.add( pm.group() );
+            if ( lm.end() == cb.limit() )
+                break;
+        }
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/JavaHelper.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/JavaHelper.java
index 95a3274..2c15218 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/JavaHelper.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/JavaHelper.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.model.util;
 
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -93,935 +94,1211 @@
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.osgi.framework.Version;
 
+
 /**
  * @author dave
  *
  */
-public class JavaHelper {
-	
-	public static final IAccessRule DENY_RULE = JavaCore.newAccessRule(
-			new Path("**"), IAccessRule.K_NON_ACCESSIBLE
-					| IAccessRule.IGNORE_IF_BETTER);
+public class JavaHelper
+{
 
-	public static final IAccessRule ALLOW_ALL_RULE = JavaCore.newAccessRule(
-			new Path("**"), IAccessRule.K_ACCESSIBLE);
-	
-	private static Map<String, Collection<IClasspathEntry>> entryCache = new HashMap<String, Collection<IClasspathEntry>>();
-	
-	public static Collection<IClasspathEntry> findClasspathEntries(ISigilBundle bundle) {
-		LinkedList<IClasspathEntry> cp = new LinkedList<IClasspathEntry>();
-		
-		ISigilProjectModel sp = bundle.getAncestor(ISigilProjectModel.class);
-		
-		if ( sp != null ) {
-			IJavaProject p = sp.getJavaModel();
-			
-			for ( String enc : bundle.getClasspathEntrys() ) {
-				IClasspathEntry e = p.decodeClasspathEntry(enc);
-				if ( e != null ) {
-					cp.add( e );
-				}
-			}
-		}
-		
-		return cp;
-	}
-	
-	public static Collection<ICompilationUnit> findCompilationUnits(ISigilProjectModel project) throws JavaModelException {
-		LinkedList<ICompilationUnit> ret = new LinkedList<ICompilationUnit>();
-		
-		IJavaProject java = project.getJavaModel();
-		for ( IClasspathEntry cp : findClasspathEntries(project.getBundle()) ) {
-			IPackageFragmentRoot[] roots = java.findPackageFragmentRoots(cp);
-			for (IPackageFragmentRoot rt : roots ) {
-				for ( IJavaElement j : rt.getChildren() ) {
-					IPackageFragment p = (IPackageFragment) j;
-					ICompilationUnit[] units = p.getCompilationUnits();
-					for ( ICompilationUnit u : units ) {
-						ret.add( u );
-					}
-				}
-			}
-		}
-		
-		return ret;
-	}
-	
-	/**
-	 * @param project 
-	 * @param packageName
-	 * @return
-	 */
-	public static Collection<IPackageExport> findExportsForPackage(ISigilProjectModel project, final String packageName) {
-		final LinkedList<IPackageExport> results = new LinkedList<IPackageExport>();
-		
-		SigilCore.getRepositoryManager(project).visit(new IModelWalker() {
-			public boolean visit(IModelElement element) {
-				if ( element instanceof IPackageExport ) {
-					IPackageExport e = (IPackageExport) element;
-					if ( e.getPackageName().equals( packageName ) ) {
-						results.add( e );
-					}
-				}				
-				return true;
-			}
-		});
+    public static final IAccessRule DENY_RULE = JavaCore.newAccessRule( new Path( "**" ), IAccessRule.K_NON_ACCESSIBLE
+        | IAccessRule.IGNORE_IF_BETTER );
 
-		return results;
-	}
-	
-	public static String[] findUses(String packageName, ISigilProjectModel projectModel) throws CoreException {
-		ArrayList<String> uses = new ArrayList<String>();
-		
-		for ( final String dependency : findPackageDependencies( packageName, projectModel ) ) {
-			if ( !dependency.equals( packageName ) ) {
-				final boolean[] found = new boolean[1];
-				
-				projectModel.visit( new IModelWalker() {
-	
-					public boolean visit(IModelElement element) {
-						if ( element instanceof IPackageImport ) {
-							IPackageImport pi = (IPackageImport) element;
-							if ( pi.getPackageName().equals( dependency ) ) {
-								found[0] = true;
-							}
-						}
-						return !found[0];
-					}				
-				} );
-				
-				if ( found[0] ) {
-					uses.add( dependency );
-				}
-			}
-		}
-		
-		return uses.toArray( new String[uses.size()] );
-	}
-	
-	private static String[] findPackageDependencies(String packageName, ISigilProjectModel projectModel) throws CoreException {
-		HashSet<String> imports = new HashSet<String>();
+    public static final IAccessRule ALLOW_ALL_RULE = JavaCore
+        .newAccessRule( new Path( "**" ), IAccessRule.K_ACCESSIBLE );
 
-		IPackageFragment p = (IPackageFragment) projectModel.getJavaModel().findElement( new Path(packageName.replace('.', '/') ) );
+    private static Map<String, Collection<IClasspathEntry>> entryCache = new HashMap<String, Collection<IClasspathEntry>>();
 
-		if ( p == null ) {
-			throw SigilCore.newCoreException("Unknown package " + packageName, null);
-		}
-		for (ICompilationUnit cu : p.getCompilationUnits() ) {
-			scanImports(cu, imports);
-		}
-		for (IClassFile cf : p.getClassFiles() ) {
-			scanImports(cf, imports);
-		}
-		
-		return imports.toArray( new String[imports.size()] );		
-	}
 
-	/**
-	 * @param project
-	 * @param monitor
-	 * @return
-	 */
-	public static List<IPackageImport> findRequiredImports(ISigilProjectModel project, IProgressMonitor monitor) {
-		LinkedList<IPackageImport> imports = new LinkedList<IPackageImport>();
-		
-		for ( String packageName : findJavaImports(project, monitor)) {
-			if ( !ProfileManager.isBootDelegate(project, packageName) ) { // these must come from boot classloader
-				try {
-					if ( !project.isInClasspath(packageName, monitor) ) {
-						Collection<IPackageExport> exports = findExportsForPackage(project, packageName);
-						if ( !exports.isEmpty() ) {
-							imports.add( select( exports ) );
-						}
-					}
-				} catch (CoreException e) {
-					SigilCore.error( "Failed to check classpath", e );
-				}
-			}
-		}
-		
-		return imports;
-	}
-	
-	/**
-	 * @param project
-	 * @param monitor
-	 * @return
-	 */
-	public static Collection<IModelElement> findUnusedReferences(final ISigilProjectModel project, final IProgressMonitor monitor) {
-		final LinkedList<IModelElement> unused = new LinkedList<IModelElement>();
-		
-		final Set<String> packages = findJavaImports(project, monitor);
-		
-		project.visit( new IModelWalker() {
-			public boolean visit(IModelElement element) {
-				if ( element instanceof IPackageImport ) {
-					IPackageImport pi = (IPackageImport) element;
-					if ( !packages.contains( pi.getPackageName() ) ) {
-						unused.add( pi );
-					}
-				}
-				else if ( element instanceof IRequiredBundle ) {
-					IRequiredBundle rb = (IRequiredBundle) element;
-					IRepositoryManager manager = SigilCore.getRepositoryManager(project);
-					ResolutionConfig config = new ResolutionConfig(ResolutionConfig.INCLUDE_OPTIONAL | ResolutionConfig.IGNORE_ERRORS);
-					try {
-						IResolution r = manager.getBundleResolver().resolve(rb, config ,
-								new ResolutionMonitorAdapter(monitor) );
-						ISigilBundle bundle = r.getProvider(rb);
-						boolean found = false;
-						for ( IPackageExport pe : bundle.getBundleInfo().getExports() ) {
-							if ( packages.contains(pe.getPackageName() ) ) {
-								found = true;
-								break;
-							}
-						}
-						
-						if ( !found ) {
-							unused.add( rb );
-						}
-					} catch (ResolutionException e) {
-						SigilCore.error( "Failed to resolve " + rb, e );
-					}
-				}
-				return true;
-			}
-		});
-		
-		return unused;
-	}
-	
-	public static Collection<IClasspathEntry> resolveClasspathEntrys(ISigilProjectModel newton, IProgressMonitor monitor)
-	throws CoreException {
-		if ( monitor == null ) {
-			monitor = Job.getJobManager().createProgressGroup();
-			monitor.beginTask("Resolving classpath for "
-					+ newton.getSymbolicName(), 2);
-		}
+    public static Collection<IClasspathEntry> findClasspathEntries( ISigilBundle bundle )
+    {
+        LinkedList<IClasspathEntry> cp = new LinkedList<IClasspathEntry>();
+
+        ISigilProjectModel sp = bundle.getAncestor( ISigilProjectModel.class );
+
+        if ( sp != null )
+        {
+            IJavaProject p = sp.getJavaModel();
+
+            for ( String enc : bundle.getClasspathEntrys() )
+            {
+                IClasspathEntry e = p.decodeClasspathEntry( enc );
+                if ( e != null )
+                {
+                    cp.add( e );
+                }
+            }
+        }
+
+        return cp;
+    }
+
+
+    public static Collection<ICompilationUnit> findCompilationUnits( ISigilProjectModel project )
+        throws JavaModelException
+    {
+        LinkedList<ICompilationUnit> ret = new LinkedList<ICompilationUnit>();
+
+        IJavaProject java = project.getJavaModel();
+        for ( IClasspathEntry cp : findClasspathEntries( project.getBundle() ) )
+        {
+            IPackageFragmentRoot[] roots = java.findPackageFragmentRoots( cp );
+            for ( IPackageFragmentRoot rt : roots )
+            {
+                for ( IJavaElement j : rt.getChildren() )
+                {
+                    IPackageFragment p = ( IPackageFragment ) j;
+                    ICompilationUnit[] units = p.getCompilationUnits();
+                    for ( ICompilationUnit u : units )
+                    {
+                        ret.add( u );
+                    }
+                }
+            }
+        }
+
+        return ret;
+    }
+
+
+    /**
+     * @param project 
+     * @param packageName
+     * @return
+     */
+    public static Collection<IPackageExport> findExportsForPackage( ISigilProjectModel project, final String packageName )
+    {
+        final LinkedList<IPackageExport> results = new LinkedList<IPackageExport>();
+
+        SigilCore.getRepositoryManager( project ).visit( new IModelWalker()
+        {
+            public boolean visit( IModelElement element )
+            {
+                if ( element instanceof IPackageExport )
+                {
+                    IPackageExport e = ( IPackageExport ) element;
+                    if ( e.getPackageName().equals( packageName ) )
+                    {
+                        results.add( e );
+                    }
+                }
+                return true;
+            }
+        } );
+
+        return results;
+    }
+
+
+    public static String[] findUses( String packageName, ISigilProjectModel projectModel ) throws CoreException
+    {
+        ArrayList<String> uses = new ArrayList<String>();
+
+        for ( final String dependency : findPackageDependencies( packageName, projectModel ) )
+        {
+            if ( !dependency.equals( packageName ) )
+            {
+                final boolean[] found = new boolean[1];
+
+                projectModel.visit( new IModelWalker()
+                {
+
+                    public boolean visit( IModelElement element )
+                    {
+                        if ( element instanceof IPackageImport )
+                        {
+                            IPackageImport pi = ( IPackageImport ) element;
+                            if ( pi.getPackageName().equals( dependency ) )
+                            {
+                                found[0] = true;
+                            }
+                        }
+                        return !found[0];
+                    }
+                } );
+
+                if ( found[0] )
+                {
+                    uses.add( dependency );
+                }
+            }
+        }
+
+        return uses.toArray( new String[uses.size()] );
+    }
+
+
+    private static String[] findPackageDependencies( String packageName, ISigilProjectModel projectModel )
+        throws CoreException
+    {
+        HashSet<String> imports = new HashSet<String>();
+
+        IPackageFragment p = ( IPackageFragment ) projectModel.getJavaModel().findElement(
+            new Path( packageName.replace( '.', '/' ) ) );
+
+        if ( p == null )
+        {
+            throw SigilCore.newCoreException( "Unknown package " + packageName, null );
+        }
+        for ( ICompilationUnit cu : p.getCompilationUnits() )
+        {
+            scanImports( cu, imports );
+        }
+        for ( IClassFile cf : p.getClassFiles() )
+        {
+            scanImports( cf, imports );
+        }
+
+        return imports.toArray( new String[imports.size()] );
+    }
+
+
+    /**
+     * @param project
+     * @param monitor
+     * @return
+     */
+    public static List<IPackageImport> findRequiredImports( ISigilProjectModel project, IProgressMonitor monitor )
+    {
+        LinkedList<IPackageImport> imports = new LinkedList<IPackageImport>();
+
+        for ( String packageName : findJavaImports( project, monitor ) )
+        {
+            if ( !ProfileManager.isBootDelegate( project, packageName ) )
+            { // these must come from boot classloader
+                try
+                {
+                    if ( !project.isInClasspath( packageName, monitor ) )
+                    {
+                        Collection<IPackageExport> exports = findExportsForPackage( project, packageName );
+                        if ( !exports.isEmpty() )
+                        {
+                            imports.add( select( exports ) );
+                        }
+                    }
+                }
+                catch ( CoreException e )
+                {
+                    SigilCore.error( "Failed to check classpath", e );
+                }
+            }
+        }
+
+        return imports;
+    }
+
+
+    /**
+     * @param project
+     * @param monitor
+     * @return
+     */
+    public static Collection<IModelElement> findUnusedReferences( final ISigilProjectModel project,
+        final IProgressMonitor monitor )
+    {
+        final LinkedList<IModelElement> unused = new LinkedList<IModelElement>();
+
+        final Set<String> packages = findJavaImports( project, monitor );
+
+        project.visit( new IModelWalker()
+        {
+            public boolean visit( IModelElement element )
+            {
+                if ( element instanceof IPackageImport )
+                {
+                    IPackageImport pi = ( IPackageImport ) element;
+                    if ( !packages.contains( pi.getPackageName() ) )
+                    {
+                        unused.add( pi );
+                    }
+                }
+                else if ( element instanceof IRequiredBundle )
+                {
+                    IRequiredBundle rb = ( IRequiredBundle ) element;
+                    IRepositoryManager manager = SigilCore.getRepositoryManager( project );
+                    ResolutionConfig config = new ResolutionConfig( ResolutionConfig.INCLUDE_OPTIONAL
+                        | ResolutionConfig.IGNORE_ERRORS );
+                    try
+                    {
+                        IResolution r = manager.getBundleResolver().resolve( rb, config,
+                            new ResolutionMonitorAdapter( monitor ) );
+                        ISigilBundle bundle = r.getProvider( rb );
+                        boolean found = false;
+                        for ( IPackageExport pe : bundle.getBundleInfo().getExports() )
+                        {
+                            if ( packages.contains( pe.getPackageName() ) )
+                            {
+                                found = true;
+                                break;
+                            }
+                        }
+
+                        if ( !found )
+                        {
+                            unused.add( rb );
+                        }
+                    }
+                    catch ( ResolutionException e )
+                    {
+                        SigilCore.error( "Failed to resolve " + rb, e );
+                    }
+                }
+                return true;
+            }
+        } );
+
+        return unused;
+    }
+
+
+    public static Collection<IClasspathEntry> resolveClasspathEntrys( ISigilProjectModel newton,
+        IProgressMonitor monitor ) throws CoreException
+    {
+        if ( monitor == null )
+        {
+            monitor = Job.getJobManager().createProgressGroup();
+            monitor.beginTask( "Resolving classpath for " + newton.getSymbolicName(), 2 );
+        }
+
+        ArrayList<IClasspathEntry> entries = new ArrayList<IClasspathEntry>();
+
+        ResolutionConfig config = new ResolutionConfig( ResolutionConfig.INCLUDE_OPTIONAL
+            | ResolutionConfig.IGNORE_ERRORS | ResolutionConfig.INDEXED_ONLY | ResolutionConfig.LOCAL_ONLY );
+
+        IResolution resolution;
+        try
+        {
+            resolution = SigilCore.getRepositoryManager( newton ).getBundleResolver().resolve( newton, config,
+                new ResolutionMonitorAdapter( monitor ) );
+        }
+        catch ( ResolutionException e )
+        {
+            throw SigilCore.newCoreException( "Failed to resolve dependencies", e );
+        }
+
+        monitor.worked( 1 );
+
+        Set<ISigilBundle> bundles = resolution.getBundles();
+        for ( ISigilBundle bundle : bundles )
+        {
+            if ( !bundle.getBundleInfo().getSymbolicName().equals( newton.getSymbolicName() ) )
+            { // discard self reference...
+                List<IModelElement> matched = resolution.getMatchedRequirements( bundle );
+                for ( IClasspathEntry cpe : buildClassPathEntry( newton, bundle, bundles, matched, monitor ) )
+                {
+                    entries.add( cpe );
+                }
+            }
+        }
+
+        Collections.sort( entries, new Comparator<IClasspathEntry>()
+        {
+            public int compare( IClasspathEntry o1, IClasspathEntry o2 )
+            {
+                return o1.toString().compareTo( o2.toString() );
+            }
+        } );
+
+        monitor.worked( 1 );
+        monitor.done();
+
+        return entries;
+    }
+
+
+    private static Collection<IClasspathEntry> buildClassPathEntry( ISigilProjectModel project, ISigilBundle provider,
+        Set<ISigilBundle> all, List<IModelElement> requirements, IProgressMonitor monitor ) throws CoreException
+    {
+        IAccessRule[] rules = buildAccessRules( project, provider, all, requirements );
+
+        ISigilProjectModel other = provider.getAncestor( ISigilProjectModel.class );
+
+        try
+        {
+            if ( other == null )
+            {
+                provider.synchronize( monitor );
+                return newBundleEntry( provider, rules, null, false );
+            }
+            else
+            {
+                return newProjectEntry( other, rules, null, false );
+            }
+        }
+        catch ( IOException e )
+        {
+            throw SigilCore.newCoreException( "Failed to synchronize " + provider, e );
+        }
+    }
+
+
+    private static IAccessRule[] buildExportRules( ISigilBundle bundle, Set<ISigilBundle> all,
+        List<IModelElement> requirements )
+    {
+        Set<IPackageExport> ex = mergeExports( bundle, all, requirements );
+
+        IAccessRule[] rules = new IAccessRule[ex.size() + 1];
+
+        Iterator<IPackageExport> iter = ex.iterator();
+        for ( int i = 0; i < rules.length - 1; i++ )
+        {
+            IPackageExport p = iter.next();
+            rules[i] = JavaCore.newAccessRule( new Path( p.getPackageName().replace( '.', '/' ) ).append( "*" ),
+                IAccessRule.K_ACCESSIBLE );
+        }
+
+        rules[rules.length - 1] = DENY_RULE;
+
+        return rules;
+    }
+
+
+    private static Set<IPackageExport> mergeExports( ISigilBundle bundle, Set<ISigilBundle> all,
+        List<IModelElement> requirements )
+    {
+        IBundleModelElement headers = bundle.getBundleInfo();
+        // FIXME treeset as PackageExport does not implement equals/hashCode
+        TreeSet<IPackageExport> exports = new TreeSet<IPackageExport>( headers.getExports() );
+        IRequiredBundle host = headers.getFragmentHost();
+        if ( host != null )
+        {
+            for ( ISigilBundle b : all )
+            {
+                if ( host.accepts( b.getBundleInfo() ) )
+                {
+                    exports.addAll( b.getBundleInfo().getExports() );
+                    break;
+                }
+            }
+        }
+        return exports;
+    }
+
+
+    private static Collection<IClasspathEntry> newProjectEntry( ISigilProjectModel n, IAccessRule[] rules,
+        IClasspathAttribute[] attributes, boolean export ) throws CoreException
+    {
+        //		if (rules == null) {
+        //			rules = JavaHelper.buildExportRules(n.getBundle());
+        //		}
+
+        if ( attributes == null )
+        {
+            attributes = new IClasspathAttribute[]
+                {};
+        }
+
+        ArrayList<IClasspathEntry> entries = new ArrayList<IClasspathEntry>();
+        entries.add( JavaCore.newProjectEntry( n.getProject().getFullPath(), rules, false, attributes, export ) );
+        for ( IClasspathEntry e : n.getJavaModel().getRawClasspath() )
+        {
+            switch ( e.getEntryKind() )
+            {
+                case IClasspathEntry.CPE_LIBRARY:
+                    entries.add( JavaCore.newLibraryEntry( e.getPath(), e.getSourceAttachmentPath(), e
+                        .getSourceAttachmentRootPath(), rules, attributes, export ) );
+                    break;
+                case IClasspathEntry.CPE_VARIABLE:
+                    IPath path = JavaCore.getResolvedVariablePath( e.getPath() );
+                    if ( path != null )
+                    {
+                        entries.add( JavaCore.newLibraryEntry( path, e.getSourceAttachmentPath(), e
+                            .getSourceAttachmentRootPath(), rules, attributes, export ) );
+                    }
+                    break;
+            }
+        }
+
+        return entries;
+    }
+
+
+    private static Collection<IClasspathEntry> newBundleEntry( ISigilBundle bundle, IAccessRule[] rules,
+        IClasspathAttribute[] attributes, boolean exported ) throws CoreException
+    {
+        String name = bundle.getBundleInfo().getSymbolicName();
+
+        //		if (rules == null) {
+        //			rules = JavaHelper.buildExportRules(bundle);
+        //		}
+
+        if ( attributes == null )
+        {
+            attributes = new IClasspathAttribute[]
+                {};
+        }
+
+        if ( bundle.getBundleInfo().getVersion() != null )
+        {
+            name += "_version_" + bundle.getBundleInfo().getVersion();
+        }
+
+        String cacheName = name + rules.toString();
+
+        Collection<IClasspathEntry> entries = null;
+
+        synchronized ( entryCache )
+        {
+            entries = entryCache.get( cacheName );
+
+            if ( entries == null )
+            {
+                IPath path = bundle.getLocation();
+
+                if ( path == null )
+                {
+                    SigilCore.error( "Found null path for " + bundle.getBundleInfo().getSymbolicName() );
+                    entries = Collections.emptyList();
+                }
+                else
+                {
+                    entries = buildEntries( path, name, bundle, rules, attributes, exported );
+                }
+
+                entryCache.put( cacheName, entries );
+            }
+        }
+
+        return entries;
+    }
+
+    private static IPath bundleCache = SigilCore.getDefault().getStateLocation().append( "bundle-cache" );
+
+
+    public static boolean isCachedBundle( String bp )
+    {
+        return bp.startsWith( bundleCache.toOSString() );
+    }
+
+
+    private static Collection<IClasspathEntry> buildEntries( IPath path, String name, ISigilBundle bundle,
+        IAccessRule[] rules, IClasspathAttribute[] attributes, boolean exported ) throws CoreException
+    {
+        if ( path.toFile().isDirectory() )
+        {
+            throw SigilCore.newCoreException( "Bundle location cannot be a directory", null );
+        }
+        else
+        {
+            // ok it's a jar could contain libs etc
+            try
+            {
+                IPath cache = bundleCache.append( name );
+                Collection<String> classpath = bundle.getBundleInfo().getClasspaths();
+                ArrayList<IClasspathEntry> entries = new ArrayList<IClasspathEntry>( classpath.size() );
+                IPath source = bundle.getSourcePathLocation();
+
+                if ( source != null && !source.toFile().exists() )
+                {
+                    source = null;
+                }
+
+                if ( !classpath.isEmpty() )
+                {
+                    unpack( cache, bundle, classpath );
+                    for ( String cp : classpath )
+                    {
+                        IPath p = ".".equals( cp ) ? path : cache.append( cp );
+                        if ( p.toFile().exists() )
+                        {
+                            IClasspathEntry e = JavaCore.newLibraryEntry( p, source, bundle.getSourceRootPath(), rules,
+                                attributes, exported );
+                            entries.add( e );
+                        }
+                    }
+                }
+                else
+                { // default classpath is .
+                    IClasspathEntry e = JavaCore.newLibraryEntry( path, source, bundle.getSourceRootPath(), rules,
+                        attributes, exported );
+                    entries.add( e );
+                }
+                return entries;
+            }
+            catch ( IOException e )
+            {
+                throw SigilCore.newCoreException( "Failed to unpack bundle", e );
+            }
+        }
+    }
+
+    private static HashMap<IPath, Collection<String>> unpacked = new HashMap<IPath, Collection<String>>();
+
+
+    private static synchronized void unpack( IPath cache, ISigilBundle bundle, Collection<String> classpath )
+        throws IOException
+    {
+        Collection<String> check = unpacked.get( cache );
+
+        if ( check == null || !check.equals( classpath ) )
+        {
+            if ( classpath.size() == 1 && classpath.contains( "." ) )
+            {
+                unpacked.put( cache, classpath );
+            }
+            else
+            {
+                // trim . from path to avoid check later in inClasspath
+                check = new HashSet<String>( classpath );
+                check.remove( "." );
+
+                File dir = createEmptyDir( cache );
+                FileInputStream fin = null;
+                try
+                {
+                    fin = new FileInputStream( bundle.getLocation().toFile() );
+                    JarInputStream in = new JarInputStream( fin );
+                    JarEntry entry;
+                    while ( ( entry = in.getNextJarEntry() ) != null )
+                    {
+                        if ( inClasspath( check, entry ) )
+                        {
+                            File f = new File( dir, entry.getName() );
+                            if ( entry.isDirectory() )
+                            {
+                                createDir( f );
+                            }
+                            else
+                            {
+                                try
+                                {
+                                    File p = f.getParentFile();
+                                    createDir( p );
+                                    streamTo( in, f );
+                                }
+                                catch ( RuntimeException e )
+                                {
+                                    SigilCore.error( "Failed to unpack " + entry, e );
+                                }
+                            }
+                        }
+                    }
+                    unpacked.put( cache, classpath );
+                }
+                finally
+                {
+                    if ( fin != null )
+                    {
+                        fin.close();
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * @param classpath
+     * @param entry
+     * @return
+     */
+    private static boolean inClasspath( Collection<String> classpath, JarEntry entry )
+    {
+        for ( String s : classpath )
+        {
+            if ( entry.getName().startsWith( s ) )
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    private static void createDir( File p ) throws IOException
+    {
+        if ( !p.exists() )
+        {
+            if ( !p.mkdirs() )
+                throw new IOException( "Failed to create directory " + p );
+        }
+    }
+
+
+    private static void streamTo( InputStream in, File f ) throws IOException
+    {
+        FileOutputStream fos = new FileOutputStream( f );
+        try
+        {
+            byte[] buf = new byte[1024];
+            for ( ;; )
+            {
+                int r = in.read( buf );
+
+                if ( r == -1 )
+                    break;
+
+                fos.write( buf, 0, r );
+            }
+
+            fos.flush();
+        }
+        finally
+        {
+            try
+            {
+                fos.close();
+            }
+            catch ( IOException e )
+            {
+                SigilCore.error( "Failed to close stream", e );
+            }
+        }
+    }
+
+
+    private static File createEmptyDir( IPath cache )
+    {
+        File dir = cache.toFile();
+        if ( dir.exists() )
+        {
+            deleteAll( dir );
+        }
+
+        dir.mkdirs();
+        return dir;
+    }
+
+
+    private static void deleteAll( File file )
+    {
+        File[] sub = file.listFiles();
+        if ( sub != null )
+        {
+            for ( File f : sub )
+            {
+                deleteAll( f );
+            }
+        }
+        file.delete();
+    }
+
+
+    private static IAccessRule[] buildAccessRules( ISigilProjectModel project, ISigilBundle bundle,
+        Set<ISigilBundle> all, List<IModelElement> requirements ) throws JavaModelException
+    {
+        ArrayList<IAccessRule> rules = new ArrayList<IAccessRule>();
+
+        for ( IModelElement e : requirements )
+        {
+            if ( e instanceof IRequiredBundle )
+            {
+                IRequiredBundle host = project.getBundle().getBundleInfo().getFragmentHost();
+                if ( host != null )
+                {
+                    if ( host.equals( e ) )
+                    {
+                        return new IAccessRule[]
+                            { ALLOW_ALL_RULE };
+                    }
+                    else
+                    {
+                        return buildExportRules( bundle, all, requirements );
+                    }
+                }
+                else
+                {
+                    return buildExportRules( bundle, all, requirements );
+                }
+            }
+            else if ( e instanceof IPackageImport )
+            {
+                IPackageImport pi = ( IPackageImport ) e;
+                String pckg = pi.getPackageName();
+                HashSet<String> pckgs = new HashSet<String>();
+                pckgs.add( pckg );
+                //findIndirectReferences(pckgs, pckg, project.getJavaModel(), project.getJavaModel());
+
+                for ( String p : pckgs )
+                {
+                    rules.add( newPackageAccess( p ) );
+                }
+            }
+        }
+
+        rules.add( DENY_RULE );
+
+        return rules.toArray( new IAccessRule[rules.size()] );
+    }
+
+
+    /*
+     * Searches for C (and D, E, etc) in case:
+     * A extends B extends C where A, B and C are in different packages and A is in this bundle
+     * and B and C are in one or more external bundles
+     */
+    private static void findIndirectReferences( Set<String> indirect, String pckg, IParent parent, IJavaProject p )
+        throws JavaModelException
+    {
+        for ( IJavaElement e : parent.getChildren() )
+        {
+            boolean skip = false;
+            switch ( e.getElementType() )
+            {
+                case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+                    IPackageFragmentRoot rt = ( IPackageFragmentRoot ) e;
+                    IClasspathEntry ce = rt.getRawClasspathEntry();
+                    IPath path = ce.getPath();
+                    skip = "org.eclipse.jdt.launching.JRE_CONTAINER".equals( path.toString() );
+                    break;
+                case IJavaElement.CLASS_FILE:
+                    IClassFile cf = ( IClassFile ) e;
+                    if ( cf.getElementName().startsWith( pckg ) )
+                    {
+                        findIndirectReferences( indirect, findPackage( cf.getType().getSuperclassName() ), p, p );
+                    }
+                    break;
+                case IJavaElement.COMPILATION_UNIT:
+                    ICompilationUnit cu = ( ICompilationUnit ) e;
+                    break;
+            }
+
+            if ( !skip && e instanceof IParent )
+            {
+                IParent newParent = ( IParent ) e;
+                findIndirectReferences( indirect, pckg, newParent, p );
+            }
+        }
+    }
+
+
+    private static IAccessRule newPackageAccess( String packageName )
+    {
+        return JavaCore.newAccessRule( new Path( packageName.replace( '.', '/' ) ).append( "*" ),
+            IAccessRule.K_ACCESSIBLE );
+    }
+
+
+    private static Set<String> findJavaImports( ISigilProjectModel project, IProgressMonitor monitor )
+    {
+        Set<String> imports = new HashSet<String>();
+
+        findJavaModelImports( project, imports, monitor );
+        findSCAImports( project, imports, monitor );
+        findTextImports( project, imports, monitor );
+
+        return imports;
+    }
+
+
+    private static void findSCAImports( ISigilProjectModel project, Set<String> imports, IProgressMonitor monitor )
+    {
+        for ( ISCAComposite sca : project.getBundle().getComposites() )
+        {
+            IFile f = project.getProject().getFile( sca.getLocation() );
+            if ( f.exists() )
+            {
+                try
+                {
+                    // TODO for now just treats sca as text files - should build in richer model that is able to detect java elements
+                    parseText( f, imports );
+                }
+                catch ( CoreException e )
+                {
+                    SigilCore.error( "Failed to parse sca file " + f, e );
+                }
+            }
+        }
+    }
+
+
+    private static void findTextImports( ISigilProjectModel project, Set<String> imports, IProgressMonitor monitor )
+    {
+        IContentTypeManager contentTypeManager = Platform.getContentTypeManager();
+        IContentType txt = contentTypeManager.getContentType( "org.eclipse.core.runtime.text" );
+        for ( IPath p : project.getBundle().getSourcePaths() )
+        {
+            IFile f = project.getProject().getFile( p );
+            if ( f.exists() )
+            {
+                try
+                {
+                    IContentDescription desc = f.getContentDescription();
+                    if ( desc != null )
+                    {
+                        IContentType type = desc.getContentType();
+                        if ( type != null )
+                        {
+                            if ( type.isKindOf( txt ) )
+                            {
+                                parseText( f, imports );
+                            }
+                        }
+                    }
+                }
+                catch ( CoreException e )
+                {
+                    SigilCore.error( "Failed to parse text file " + f, e );
+                }
+            }
+        }
+    }
+
+
+    private static void findJavaModelImports( ISigilProjectModel project, Set<String> imports, IProgressMonitor monitor )
+    {
+        try
+        {
+            for ( IPackageFragment root : project.getJavaModel().getPackageFragments() )
+            {
+                IPackageFragmentRoot rt = ( IPackageFragmentRoot ) root
+                    .getAncestor( IJavaElement.PACKAGE_FRAGMENT_ROOT );
+
+                if ( isInClassPath( project, rt ) )
+                {
+                    for ( ICompilationUnit cu : root.getCompilationUnits() )
+                    {
+                        scanImports( cu, imports );
+                    }
 
-		ArrayList<IClasspathEntry> entries = new ArrayList<IClasspathEntry>();
+                    for ( IClassFile cf : root.getClassFiles() )
+                    {
+                        scanImports( cf, imports );
+                    }
+                }
+            }
+        }
+        catch ( JavaModelException e )
+        {
+            SigilCore.error( "Failed to parse java model", e );
+        }
+    }
 
-		ResolutionConfig config = new ResolutionConfig(ResolutionConfig.INCLUDE_OPTIONAL | ResolutionConfig.IGNORE_ERRORS | ResolutionConfig.INDEXED_ONLY | ResolutionConfig.LOCAL_ONLY);
+    // matches word.word.word.word.Word
+    private static final Pattern JAVA_CLASS_PATTERN = Pattern.compile( "((\\w*\\.\\w*)+?)\\.[A-Z]\\w*" );
 
-		IResolution resolution;
-		try {
-			resolution = SigilCore.getRepositoryManager(newton).getBundleResolver().resolve(newton, config, new ResolutionMonitorAdapter(monitor));
-		} catch (ResolutionException e) {
-			throw SigilCore.newCoreException("Failed to resolve dependencies", e);
-		}
 
-		monitor.worked(1);
+    private static void parseText( IFile f, Set<String> imports ) throws CoreException
+    {
+        for ( String result : Grep.grep( JAVA_CLASS_PATTERN, f ) )
+        {
+            findImport( result, imports );
+        }
+    }
 
-		Set<ISigilBundle> bundles = resolution.getBundles();
-		for (ISigilBundle bundle : bundles) {
-			if (!bundle.getBundleInfo().getSymbolicName().equals(newton.getSymbolicName())) { // discard self reference...
-				List<IModelElement> matched = resolution.getMatchedRequirements(bundle);
-				for (IClasspathEntry cpe : buildClassPathEntry(newton, bundle, bundles, matched, monitor)) {
-					entries.add(cpe);
-				}
-			}
-		}
 
-		Collections.sort(entries, new Comparator<IClasspathEntry>() {
-			public int compare(IClasspathEntry o1, IClasspathEntry o2) {
-				return o1.toString().compareTo(o2.toString());
-			}
-		});
-		
-		monitor.worked(1);
-		monitor.done();
+    private static boolean isInClassPath( ISigilProjectModel project, IPackageFragmentRoot rt )
+        throws JavaModelException
+    {
+        String path = encode( project, rt.getRawClasspathEntry() );
+        return project.getBundle().getClasspathEntrys().contains( path );
+    }
 
-		return entries;
-	}
 
-	private static Collection<IClasspathEntry> buildClassPathEntry(ISigilProjectModel project, ISigilBundle provider, Set<ISigilBundle> all, List<IModelElement> requirements, IProgressMonitor monitor) throws CoreException {
-		IAccessRule[] rules = buildAccessRules(project, provider, all, requirements);
+    private static String encode( ISigilProjectModel project, IClasspathEntry cp )
+    {
+        return project.getJavaModel().encodeClasspathEntry( cp ).trim();
+    }
 
-		ISigilProjectModel other = provider.getAncestor(ISigilProjectModel.class);
 
-		try {
-			if (other == null) {
-				provider.synchronize(monitor);
-				return newBundleEntry(provider, rules, null, false);
-			} else {
-				return newProjectEntry(other, rules, null, false);
-			}
-		} catch (IOException e) {
-			throw SigilCore.newCoreException("Failed to synchronize " + provider, e);
-		}
-	}
+    private static void scanImports( IParent parent, Set<String> imports ) throws JavaModelException
+    {
+        for ( IJavaElement e : parent.getChildren() )
+        {
+            switch ( e.getElementType() )
+            {
+                case IJavaElement.TYPE:
+                    handleType( ( IType ) e, imports );
+                    break;
+                case IJavaElement.IMPORT_DECLARATION:
+                    handleImport( ( IImportDeclaration ) e, imports );
+                    break;
+                case IJavaElement.FIELD:
+                    handleField( ( IField ) e, imports );
+                    break;
+                case IJavaElement.LOCAL_VARIABLE:
+                    handleLocalVariable( ( ILocalVariable ) e, imports );
+                    break;
+                case IJavaElement.ANNOTATION:
+                    handleAnnotation( ( IAnnotation ) e, imports );
+                    break;
+                case IJavaElement.METHOD:
+                    handleMethod( ( IMethod ) e, imports );
+                    break;
+                default:
+                    // no action
+                    break;
+            }
 
-	private static IAccessRule[] buildExportRules(ISigilBundle bundle, Set<ISigilBundle> all, List<IModelElement> requirements) {
-		Set<IPackageExport> ex = mergeExports( bundle, all, requirements );
-		
-		IAccessRule[] rules = new IAccessRule[ex.size() + 1];
+            if ( e instanceof IParent )
+            {
+                scanImports( ( IParent ) e, imports );
+            }
+        }
+    }
 
-		Iterator<IPackageExport> iter = ex.iterator();
-		for (int i = 0; i < rules.length - 1; i++) {
-			IPackageExport p = iter.next();
-			rules[i] = JavaCore.newAccessRule(new Path(p.getPackageName()
-					.replace('.', '/')).append("*"), IAccessRule.K_ACCESSIBLE);
-		}
 
-		rules[rules.length - 1] = DENY_RULE;
+    private static void handleType( IType e, Set<String> imports ) throws JavaModelException
+    {
+        findImportFromType( e.getSuperclassTypeSignature(), imports );
+        for ( String sig : e.getSuperInterfaceTypeSignatures() )
+        {
+            findImportFromType( sig, imports );
+        }
+        //findImportsForSuperTypes(e, imports);
+    }
 
-		return rules;
-	}
 
-	private static Set<IPackageExport> mergeExports(ISigilBundle bundle, Set<ISigilBundle> all, List<IModelElement> requirements) {
-		IBundleModelElement headers = bundle.getBundleInfo();
-		// FIXME treeset as PackageExport does not implement equals/hashCode
-		TreeSet<IPackageExport> exports = new TreeSet<IPackageExport>(headers.getExports());
-		IRequiredBundle host = headers.getFragmentHost();
-		if ( host != null ) {
-			for ( ISigilBundle b : all ) {
-				if ( host.accepts(b.getBundleInfo()) ) {
-					exports.addAll( b.getBundleInfo().getExports() );
-					break;
-				}
-			}
-		}
-		return exports;
-	}
+    /*private static void findImportsForSuperTypes(IType e, Set<String> imports) throws JavaModelException {
+    	IJavaProject project = (IJavaProject) e.getAncestor(IJavaModel.JAVA_PROJECT);
+    	LinkedList<String> types = new LinkedList<String>();
+    	types.add( decodeSignature(e.getSuperclassTypeSignature()) );
+    	for ( String sig : e.getSuperInterfaceTypeSignatures() ) {
+    		types.add( decodeSignature(sig) );
+    	}
+    	
+    	for ( IPackageFragmentRoot root : project.getPackageFragmentRoots() ) {
+    		// only need to search binary files for inheritance as source will automatically be searched
+    		if ( root.getKind() == IPackageFragmentRoot.K_BINARY ) {
+    			for ( String t : types ) {
+    				String pac = findPackage(t);
+    				if ( pac != null ) {
+    					IPackageFragment fragment = root.getPackageFragment(pac);
+    					if ( fragment != null ) {
+    						IClassFile c = fragment.getClassFile(findClass(t));
+    						if ( c != null ) {
+    							findImportsForSuperTypes(c.getType(), imports);
+    						}
+    					}
+    				}
+    			}
+    		}
+    	}
+    } */
 
-	private static Collection<IClasspathEntry> newProjectEntry(
-			ISigilProjectModel n, IAccessRule[] rules,
-			IClasspathAttribute[] attributes, boolean export)
-			throws CoreException {
-//		if (rules == null) {
-//			rules = JavaHelper.buildExportRules(n.getBundle());
-//		}
+    private static void handleMethod( IMethod e, Set<String> imports ) throws JavaModelException
+    {
+        findImportFromType( e.getReturnType(), imports );
 
-		if (attributes == null) {
-			attributes = new IClasspathAttribute[] {};
-		}
+        for ( String param : e.getParameterTypes() )
+        {
+            findImportFromType( param, imports );
+        }
 
-		ArrayList<IClasspathEntry> entries = new ArrayList<IClasspathEntry>();
-		entries.add(JavaCore.newProjectEntry(n.getProject().getFullPath(),
-				rules, false, attributes, export));
-		for (IClasspathEntry e : n.getJavaModel().getRawClasspath()) {
-			switch (e.getEntryKind()) {
-			case IClasspathEntry.CPE_LIBRARY:
-				entries.add(JavaCore.newLibraryEntry(e.getPath(), e
-						.getSourceAttachmentPath(), e
-						.getSourceAttachmentRootPath(), rules, attributes,
-						export));
-				break;
-			case IClasspathEntry.CPE_VARIABLE:
-				IPath path = JavaCore.getResolvedVariablePath(e.getPath());
-				if (path != null) {
-					entries.add(JavaCore.newLibraryEntry(path, e
-							.getSourceAttachmentPath(), e
-							.getSourceAttachmentRootPath(), rules, attributes,
-							export));
-				}
-				break;
-			}
-		}
+        for ( String ex : e.getExceptionTypes() )
+        {
+            findImportFromType( ex, imports );
+        }
+    }
 
-		return entries;
-	}
 
-	private static Collection<IClasspathEntry> newBundleEntry(
-			ISigilBundle bundle, IAccessRule[] rules,
-			IClasspathAttribute[] attributes, boolean exported)
-			throws CoreException {
-		String name = bundle.getBundleInfo().getSymbolicName();
+    private static void handleAnnotation( IAnnotation e, Set<String> imports )
+    {
+        findImport( e.getElementName(), imports );
+    }
 
-//		if (rules == null) {
-//			rules = JavaHelper.buildExportRules(bundle);
-//		}
 
-		if (attributes == null) {
-			attributes = new IClasspathAttribute[] {};
-		}
+    private static void handleLocalVariable( ILocalVariable e, Set<String> imports )
+    {
+        findImportFromType( e.getTypeSignature(), imports );
+    }
 
-		if (bundle.getBundleInfo().getVersion() != null) {
-			name += "_version_" + bundle.getBundleInfo().getVersion();
-		}
 
-		String cacheName = name + rules.toString();
+    private static void handleField( IField e, Set<String> imports ) throws IllegalArgumentException,
+        JavaModelException
+    {
+        findImportFromType( Signature.getElementType( e.getTypeSignature() ), imports );
+    }
 
-		Collection<IClasspathEntry> entries = null;
-		
-		synchronized( entryCache ) {
-			entries = entryCache.get(cacheName);
-	
-			if (entries == null) {
-				IPath path = bundle.getLocation();
-	
-				if (path == null) {
-					SigilCore.error("Found null path for "
-							+ bundle.getBundleInfo().getSymbolicName());
-					entries = Collections.emptyList();
-				} else {
-					entries = buildEntries(path, name, bundle, rules, attributes,
-							exported);
-				}
-	
-				entryCache.put(cacheName, entries);
-			}
-		}
-		
-		return entries;
-	}
 
-	private static IPath bundleCache = SigilCore.getDefault().getStateLocation().append(
-			"bundle-cache");
-	
-	public static boolean isCachedBundle(String bp) {
-		return bp.startsWith(bundleCache.toOSString());
-	}
+    private static void handleImport( IImportDeclaration id, Set<String> imports )
+    {
+        findImport( id.getElementName(), imports );
+    }
 
-	private static Collection<IClasspathEntry> buildEntries(IPath path,
-			String name, ISigilBundle bundle, IAccessRule[] rules,
-			IClasspathAttribute[] attributes, boolean exported)
-			throws CoreException {
-		if (path.toFile().isDirectory()) {
-			throw SigilCore.newCoreException("Bundle location cannot be a directory",
-					null);
-		} else {
-			// ok it's a jar could contain libs etc
-			try {
-				IPath cache = bundleCache.append(name);
-				Collection<String> classpath = bundle.getBundleInfo().getClasspaths();
-				ArrayList<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(classpath.size());
-				IPath source = bundle.getSourcePathLocation();
-				
-				if (source != null && !source.toFile().exists()) {
-					source = null;
-				}
 
-				if ( !classpath.isEmpty() ) {
-					unpack(cache, bundle, classpath);
-					for (String cp : classpath) {
-						IPath p = ".".equals(cp) ? path : cache.append(cp);
-						if ( p.toFile().exists() ) {
-							IClasspathEntry e = JavaCore.newLibraryEntry(p, source,
-									bundle.getSourceRootPath(), rules, attributes,
-									exported);
-							entries.add(e);
-						}
-					}
-				}
-				else { // default classpath is .
-					IClasspathEntry e = JavaCore.newLibraryEntry(path, source,
-							bundle.getSourceRootPath(), rules, attributes,
-							exported);
-					entries.add(e);
-				}
-				return entries;
-			} catch (IOException e) {
-				throw SigilCore.newCoreException("Failed to unpack bundle", e);
-			}
-		}
-	}
+    private static void findImportFromType( String type, Set<String> imports )
+    {
+        String element = decodeSignature( type );
+        findImport( element, imports );
+    }
 
-	private static HashMap<IPath, Collection<String>> unpacked = new HashMap<IPath, Collection<String>>();
-	
-	private static synchronized void unpack(IPath cache, ISigilBundle bundle, Collection<String> classpath) throws IOException {
-		Collection<String> check = unpacked.get(cache);
 
-		if ( check == null || !check.equals(classpath) ) {
-			if ( classpath.size() == 1 && classpath.contains(".") ) {
-				unpacked.put(cache, classpath);
-			}
-			else {
-				// trim . from path to avoid check later in inClasspath
-				check = new HashSet<String>(classpath);
-				check.remove( "." );
-				
-				File dir = createEmptyDir(cache);
-				FileInputStream fin = null;
-				try {
-					fin = new FileInputStream(bundle.getLocation().toFile());
-					JarInputStream in = new JarInputStream(fin);
-					JarEntry entry;
-					while ((entry = in.getNextJarEntry()) != null) {
-						if ( inClasspath(check, entry) ) {
-							File f = new File(dir, entry.getName());
-							if (entry.isDirectory()) {
-								createDir(f);
-							} else {
-								try {
-									File p = f.getParentFile();
-									createDir(p);
-									streamTo(in, f);
-								}
-								catch (RuntimeException e) {
-									SigilCore.error("Failed to unpack " + entry, e);
-								}
-							}
-						}
-					}
-					unpacked.put(cache, classpath);
-				}
-				finally {
-					if ( fin != null ) {
-						fin.close();
-					}
-				}
-			}
-		}
-	}
+    private static String decodeSignature( String type )
+    {
+        return decodeSignature( type, false );
+    }
 
-	/**
-	 * @param classpath
-	 * @param entry
-	 * @return
-	 */
-	private static boolean inClasspath(Collection<String> classpath, JarEntry entry) {
-		for ( String s : classpath ) {
-			if ( entry.getName().startsWith(s) ) {
-				return true;
-			}
-		}
-		return false;
-	}
 
-	private static void createDir(File p) throws IOException {
-		if (!p.exists()) {
-			if (!p.mkdirs())
-				throw new IOException("Failed to create directory " + p);
-		}
-	}
+    private static String decodeSignature( String type, boolean resolve )
+    {
+        if ( type == null )
+        {
+            return null;
+        }
 
-	private static void streamTo(InputStream in, File f) throws IOException {
-		FileOutputStream fos = new FileOutputStream(f);
-		try {
-			byte[] buf = new byte[1024];
-			for (;;) {
-				int r = in.read(buf);
+        if ( type.length() > 0 )
+        {
+            switch ( type.charAt( 0 ) )
+            {
+                case Signature.C_ARRAY:
+                    return decodeSignature( type.substring( 1 ) );
+                case Signature.C_UNRESOLVED:
+                    return resolve ? resolve( type.substring( 1, type.length() - 1 ) ) : null;
+                case Signature.C_RESOLVED:
+                    return type.substring( 1 );
+            }
+        }
+        return type;
+    }
 
-				if (r == -1)
-					break;
 
-				fos.write(buf, 0, r);
-			}
+    private static String resolve( String substring )
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
 
-			fos.flush();
-		} finally {
-			try {
-				fos.close();
-			} catch (IOException e) {
-				SigilCore.error("Failed to close stream", e);
-			}
-		}
-	}
 
-	private static File createEmptyDir(IPath cache) {
-		File dir = cache.toFile();
-		if (dir.exists()) {
-			deleteAll(dir);
-		}
+    private static void findImport( String clazz, Set<String> imports )
+    {
+        String packageName = findPackage( clazz );
+        if ( packageName != null )
+        {
+            imports.add( packageName );
+        }
+    }
 
-		dir.mkdirs();
-		return dir;
-	}
 
-	private static void deleteAll(File file) {
-		File[] sub = file.listFiles();
-		if (sub != null) {
-			for (File f : sub) {
-				deleteAll(f);
-			}
-		}
-		file.delete();
-	}
+    private static String findPackage( String clazz )
+    {
+        if ( clazz == null )
+            return null;
+        int pos = clazz.lastIndexOf( '.' );
+        return pos == -1 ? null : clazz.substring( 0, pos );
+    }
 
-	private static IAccessRule[] buildAccessRules(ISigilProjectModel project, ISigilBundle bundle, Set<ISigilBundle> all, List<IModelElement> requirements) throws JavaModelException {
-		ArrayList<IAccessRule> rules = new ArrayList<IAccessRule>();
 
-		for (IModelElement e : requirements) {
-			if (e instanceof IRequiredBundle) {
-				IRequiredBundle host = project.getBundle().getBundleInfo().getFragmentHost();
-				if ( host != null ) {
-					if ( host.equals(e) ) {
-						return new IAccessRule[] { ALLOW_ALL_RULE };
-					}
-					else {
-						return buildExportRules(bundle, all, requirements);
-					}
-				}
-				else {
-					return buildExportRules(bundle, all, requirements);
-				}
-			} else if (e instanceof IPackageImport) {
-				IPackageImport pi = (IPackageImport) e;
-				String pckg = pi.getPackageName();
-				HashSet<String> pckgs = new HashSet<String>();
-				pckgs.add(pckg);
-				//findIndirectReferences(pckgs, pckg, project.getJavaModel(), project.getJavaModel());
-				
-				for ( String p : pckgs ) {
-					rules.add(newPackageAccess(p));
-				}
-			}
-		}
+    private static String findClass( String clazz )
+    {
+        if ( clazz == null )
+            return null;
+        int pos = clazz.lastIndexOf( '.' );
+        return pos == -1 ? null : clazz.substring( pos + 1 );
+    }
 
-		rules.add(DENY_RULE);
 
-		return rules.toArray(new IAccessRule[rules.size()]);
-	}
+    private static IPackageImport select( Collection<IPackageExport> proposals )
+    {
+        IPackageExport pe = null;
 
-	/*
-	 * Searches for C (and D, E, etc) in case:
-	 * A extends B extends C where A, B and C are in different packages and A is in this bundle
-	 * and B and C are in one or more external bundles
-	 */
-	private static void findIndirectReferences(Set<String> indirect, String pckg, IParent parent, IJavaProject p) throws JavaModelException {
-		for  ( IJavaElement e : parent.getChildren() ) {
-			boolean skip = false;
-			switch ( e.getElementType() ) {
-			case IJavaElement.PACKAGE_FRAGMENT_ROOT:
-				IPackageFragmentRoot rt = (IPackageFragmentRoot) e;
-				IClasspathEntry ce = rt.getRawClasspathEntry();
-				IPath path = ce.getPath();
-				skip = "org.eclipse.jdt.launching.JRE_CONTAINER".equals(path.toString());
-				break;
-			case IJavaElement.CLASS_FILE:
-				IClassFile cf = (IClassFile) e;
-				if ( cf.getElementName().startsWith(pckg) ) {
-					findIndirectReferences(indirect, findPackage(cf.getType().getSuperclassName()), p, p);
-				}
-				break;
-			case IJavaElement.COMPILATION_UNIT:
-				ICompilationUnit cu = (ICompilationUnit) e;
-				break;
-			}
-			
-			if ( !skip && e instanceof IParent ) {
-				IParent newParent = (IParent) e;
-				findIndirectReferences(indirect, pckg, newParent, p);
-			}
-		}
-	}
-	
-	private static IAccessRule newPackageAccess(String packageName) {
-		return JavaCore.newAccessRule(new Path(packageName.replace('.', '/'))
-				.append("*"), IAccessRule.K_ACCESSIBLE);
-	}
+        for ( IPackageExport check : proposals )
+        {
+            if ( pe == null || check.getVersion().compareTo( pe.getVersion() ) > 0 )
+            {
+                pe = check;
+            }
+        }
 
-	private static Set<String> findJavaImports(ISigilProjectModel project, IProgressMonitor monitor) {
-		Set<String> imports = new HashSet<String>();
-		
-		findJavaModelImports(project, imports, monitor);
-		findSCAImports(project, imports, monitor);
-		findTextImports(project, imports, monitor);
-		
-		return imports;
-	}
-	
-	private static void findSCAImports(ISigilProjectModel project, Set<String> imports, IProgressMonitor monitor) {
-		for ( ISCAComposite sca : project.getBundle().getComposites() ) {
-			IFile f = project.getProject().getFile(sca.getLocation());
-			if ( f.exists() ) {
-				try {
-					// TODO for now just treats sca as text files - should build in richer model that is able to detect java elements
-					parseText( f, imports );
-				} catch (CoreException e) {
-					SigilCore.error( "Failed to parse sca file " + f, e );
-				}
-			}
-		}
-	}
+        String packageName = pe.getPackageName();
 
-	private static void findTextImports(ISigilProjectModel project, Set<String> imports, IProgressMonitor monitor) {
-		IContentTypeManager contentTypeManager = Platform.getContentTypeManager();
-		IContentType txt = contentTypeManager.getContentType("org.eclipse.core.runtime.text");
-		for ( IPath p : project.getBundle().getSourcePaths() ) {
-			IFile f = project.getProject().getFile(p);
-			if ( f.exists() ) {
-				try {
-					IContentDescription desc = f.getContentDescription();
-					if ( desc != null ) {
-						IContentType type = desc.getContentType();
-						if ( type != null ) {
-							if ( type.isKindOf( txt ) ) {
-								parseText( f, imports );
-							}
-						}
-					}
-				} catch (CoreException e) {
-					SigilCore.error( "Failed to parse text file " + f, e );
-				}
-			}
-		}
-	}
+        IPreferenceStore store = SigilCore.getDefault().getPreferenceStore();
+        VersionRangeBoundingRule lowerBoundRule = VersionRangeBoundingRule.valueOf( store
+            .getString( SigilCore.DEFAULT_VERSION_LOWER_BOUND ) );
+        VersionRangeBoundingRule upperBoundRule = VersionRangeBoundingRule.valueOf( store
+            .getString( SigilCore.DEFAULT_VERSION_UPPER_BOUND ) );
 
-	private static void findJavaModelImports(ISigilProjectModel project, Set<String> imports, IProgressMonitor monitor) {
-		try {
-			for ( IPackageFragment root : project.getJavaModel().getPackageFragments() ) {
-				IPackageFragmentRoot rt = (IPackageFragmentRoot) root.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
-				
-				if ( isInClassPath( project, rt ) ) {
-					for ( ICompilationUnit cu : root.getCompilationUnits() ) {
-						scanImports( cu, imports );
-					}
-					
-					for ( IClassFile cf : root.getClassFiles() ) {
-						scanImports( cf, imports );
-					}
-				}
-			}
-		} catch (JavaModelException e) {
-			SigilCore.error( "Failed to parse java model", e );
-		}
-	}
+        Version version = pe.getVersion();
+        VersionRange versions = VersionRange.newInstance( version, lowerBoundRule, upperBoundRule );
 
-	// matches word.word.word.word.Word
-	private static final Pattern JAVA_CLASS_PATTERN = Pattern.compile("((\\w*\\.\\w*)+?)\\.[A-Z]\\w*");
-	
-	private static void parseText(IFile f, Set<String> imports) throws CoreException {
-		for ( String result : Grep.grep( JAVA_CLASS_PATTERN, f) ) {
-			findImport(result, imports);
-		}
-	}
+        IPackageImport pi = ModelElementFactory.getInstance().newModelElement( IPackageImport.class );
+        pi.setPackageName( packageName );
+        pi.setVersions( versions );
 
-	private static boolean isInClassPath(ISigilProjectModel project, IPackageFragmentRoot rt) throws JavaModelException {
-		String path = encode( project, rt.getRawClasspathEntry() );
-		return project.getBundle().getClasspathEntrys().contains( path );
-	}
+        return pi;
+    }
 
-	private static String encode(ISigilProjectModel project, IClasspathEntry cp) {
-		return project.getJavaModel().encodeClasspathEntry(cp).trim();
-	}
-	
-	private static void scanImports(IParent parent, Set<String> imports) throws JavaModelException {
-		for ( IJavaElement e : parent.getChildren() ) {
-			switch ( e.getElementType() ) {
-			case IJavaElement.TYPE:
-				handleType( (IType) e, imports );
-				break;
-			case IJavaElement.IMPORT_DECLARATION:
-				handleImport( (IImportDeclaration) e, imports );
-				break;
-			case IJavaElement.FIELD:
-				handleField( (IField) e, imports );
-				break;
-			case IJavaElement.LOCAL_VARIABLE:
-				handleLocalVariable( (ILocalVariable) e, imports );
-				break;
-			case IJavaElement.ANNOTATION:
-				handleAnnotation( (IAnnotation) e, imports );
-				break;
-			case IJavaElement.METHOD:
-				handleMethod( (IMethod) e, imports );
-				break;
-			default:
-				// no action
-				break;
-			}
-			
-			if ( e instanceof IParent ) {
-				scanImports((IParent) e, imports);
-			}
-		}
-	}
 
-	private static void handleType(IType e, Set<String> imports) throws JavaModelException {
-		findImportFromType(e.getSuperclassTypeSignature(), imports);
-		for ( String sig : e.getSuperInterfaceTypeSignatures() ) {
-			findImportFromType(sig, imports);
-		}
-		//findImportsForSuperTypes(e, imports);
-	}
-	
-	/*private static void findImportsForSuperTypes(IType e, Set<String> imports) throws JavaModelException {
-		IJavaProject project = (IJavaProject) e.getAncestor(IJavaModel.JAVA_PROJECT);
-		LinkedList<String> types = new LinkedList<String>();
-		types.add( decodeSignature(e.getSuperclassTypeSignature()) );
-		for ( String sig : e.getSuperInterfaceTypeSignatures() ) {
-			types.add( decodeSignature(sig) );
-		}
-		
-		for ( IPackageFragmentRoot root : project.getPackageFragmentRoots() ) {
-			// only need to search binary files for inheritance as source will automatically be searched
-			if ( root.getKind() == IPackageFragmentRoot.K_BINARY ) {
-				for ( String t : types ) {
-					String pac = findPackage(t);
-					if ( pac != null ) {
-						IPackageFragment fragment = root.getPackageFragment(pac);
-						if ( fragment != null ) {
-							IClassFile c = fragment.getClassFile(findClass(t));
-							if ( c != null ) {
-								findImportsForSuperTypes(c.getType(), imports);
-							}
-						}
-					}
-				}
-			}
-		}
-	} */
-	
-	private static void handleMethod(IMethod e, Set<String> imports) throws JavaModelException {
-		findImportFromType(e.getReturnType(), imports);
-		
-		for ( String param : e.getParameterTypes() ) {
-			findImportFromType(param, imports);
-		}
-		
-		for ( String ex : e.getExceptionTypes() ) {
-			findImportFromType( ex, imports );
-		}
-	}
+    public static Iterable<IJavaElement> findTypes( IParent parent, int... type ) throws JavaModelException
+    {
+        LinkedList<IJavaElement> found = new LinkedList<IJavaElement>();
+        scanForElement( parent, type, found, false );
+        return found;
+    }
 
-	private static void handleAnnotation(IAnnotation e, Set<String> imports) {
-		findImport(e.getElementName(), imports);
-	}
 
-	private static void handleLocalVariable(ILocalVariable e, Set<String> imports) {
-		findImportFromType(e.getTypeSignature(), imports);
-	}
+    public static IJavaElement findType( IParent parent, int... type ) throws JavaModelException
+    {
+        LinkedList<IJavaElement> found = new LinkedList<IJavaElement>();
+        scanForElement( parent, type, found, true );
+        return found.isEmpty() ? null : found.getFirst();
+    }
 
-	private static void handleField(IField e, Set<String> imports) throws IllegalArgumentException, JavaModelException {
-		findImportFromType(Signature.getElementType(e.getTypeSignature()), imports);
-	}
 
-	private static void handleImport(IImportDeclaration id, Set<String> imports) {
-		findImport( id.getElementName(), imports);
-	}
+    private static void scanForElement( IParent parent, int[] type, List<IJavaElement> roots, boolean thereCanBeOnlyOne )
+        throws JavaModelException
+    {
+        for ( IJavaElement e : parent.getChildren() )
+        {
+            if ( isType( type, e ) )
+            {
+                roots.add( e );
+                if ( thereCanBeOnlyOne )
+                {
+                    break;
+                }
+            }
+            else if ( e instanceof IParent )
+            {
+                scanForElement( ( IParent ) e, type, roots, thereCanBeOnlyOne );
+            }
+        }
+    }
 
-	private static void findImportFromType(String type, Set<String> imports) {
-		String element = decodeSignature(type);
-		findImport(element, imports);
-	}
 
-	private static String decodeSignature(String type) {
-		return decodeSignature(type, false);
-	}
-	
-	private static String decodeSignature(String type, boolean resolve) {
-		if ( type == null ) {
-			return null;
-		}
-		
-		if ( type.length() > 0 ) {
-			switch ( type.charAt(0) ) {
-			case Signature.C_ARRAY:
-				return decodeSignature(type.substring(1) );
-			case Signature.C_UNRESOLVED:
-				return resolve ? resolve( type.substring(1, type.length() - 1) ) : null;
-			case Signature.C_RESOLVED:
-				return type.substring(1);
-			}
-		}
-		return type;
-	}
+    private static boolean isType( int[] type, IJavaElement e )
+    {
+        for ( int i : type )
+        {
+            if ( i == e.getElementType() )
+            {
+                return true;
+            }
+        }
+        return false;
+    }
 
-	private static String resolve(String substring) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-	
-	private static void findImport(String clazz, Set<String> imports) {
-		String packageName = findPackage(clazz);
-		if ( packageName != null ) {
-			imports.add(packageName);
-		}
-	}
-	
-	private static String findPackage(String clazz) {
-		if ( clazz == null ) return null;
-		int pos = clazz.lastIndexOf( '.' );
-		return pos == -1 ? null : clazz.substring(0, pos);
-	}
 
-	private static String findClass(String clazz) {
-		if ( clazz == null ) return null;
-		int pos = clazz.lastIndexOf( '.' );
-		return pos == -1 ? null : clazz.substring(pos + 1);
-	}
-	
-	private static IPackageImport select(Collection<IPackageExport> proposals) {
-		IPackageExport pe = null;
-		
-		for ( IPackageExport check : proposals ) {
-			if ( pe == null || check.getVersion().compareTo( pe.getVersion() ) > 0 ) {
-				pe = check;
-			}
-		}
-		
-		String packageName = pe.getPackageName();
-		
-		IPreferenceStore store = SigilCore.getDefault().getPreferenceStore();
-		VersionRangeBoundingRule lowerBoundRule = VersionRangeBoundingRule.valueOf(store.getString(SigilCore.DEFAULT_VERSION_LOWER_BOUND));
-		VersionRangeBoundingRule upperBoundRule = VersionRangeBoundingRule.valueOf(store.getString(SigilCore.DEFAULT_VERSION_UPPER_BOUND));
+    public static boolean isAssignableTo( String ifaceOrParentClass, IType type ) throws JavaModelException
+    {
+        if ( ifaceOrParentClass == null )
+            return true;
 
-		Version version = pe.getVersion();
-		VersionRange versions = VersionRange.newInstance(version, lowerBoundRule, upperBoundRule);
-		
-		IPackageImport pi = ModelElementFactory.getInstance().newModelElement(IPackageImport.class);
-		pi.setPackageName(packageName);
-		pi.setVersions(versions);
-		
-		return pi;
-	}
+        ITypeHierarchy h = type.newSupertypeHierarchy( null );
 
-	public static Iterable<IJavaElement> findTypes(IParent parent, int... type) throws JavaModelException {
-		LinkedList<IJavaElement> found = new LinkedList<IJavaElement>();
-		scanForElement(parent, type, found, false);
-		return found;
-	}
-	
-	public static IJavaElement findType(IParent parent, int... type) throws JavaModelException {
-		LinkedList<IJavaElement> found = new LinkedList<IJavaElement>();
-		scanForElement(parent, type, found, true);
-		return found.isEmpty() ? null : found.getFirst();
-	}
+        for ( IType superType : h.getAllClasses() )
+        {
+            String name = superType.getFullyQualifiedName();
+            if ( name.equals( ifaceOrParentClass ) )
+            {
+                return true;
+            }
+        }
+        for ( IType ifaceType : h.getAllInterfaces() )
+        {
+            String name = ifaceType.getFullyQualifiedName();
+            if ( name.equals( ifaceOrParentClass ) )
+            {
+                return true;
+            }
+        }
 
-	private static void scanForElement(IParent parent, int[] type, List<IJavaElement> roots, boolean thereCanBeOnlyOne) throws JavaModelException {
-		for ( IJavaElement e : parent.getChildren() ) {
-			if ( isType(type, e) ) {
-				roots.add( e );
-				if ( thereCanBeOnlyOne ) {
-					break;
-				}
-			}
-			else if ( e instanceof IParent ) {
-				scanForElement( (IParent) e, type, roots, thereCanBeOnlyOne );
-			}
-		}
-	}
+        return false;
+    }
 
-	private static boolean isType(int[] type, IJavaElement e) {
-		for ( int i : type ) {
-			if ( i == e.getElementType() ) {
-				return true;
-			}
-		}
-		return false;
-	}
 
-	public static boolean isAssignableTo(String ifaceOrParentClass, IType type) throws JavaModelException {
-		if ( ifaceOrParentClass == null ) return true;
-		
-		ITypeHierarchy h = type.newSupertypeHierarchy(null);
-		
-		for ( IType superType : h.getAllClasses() ) {
-			String name = superType.getFullyQualifiedName();
-			if ( name.equals( ifaceOrParentClass ) ) {
-				return true;
-			}
-		}
-		for ( IType ifaceType : h.getAllInterfaces() ) {
-			String name = ifaceType.getFullyQualifiedName();
-			if ( name.equals( ifaceOrParentClass ) ) {
-				return true;
-			}
-		}
-		
-		return false;
-	}
+    private static IType findType( ITypeRoot root ) throws JavaModelException
+    {
+        // TODO Auto-generated method stub
+        for ( IJavaElement child : root.getChildren() )
+        {
+            if ( child.getElementType() == IJavaElement.TYPE )
+            {
+                return ( IType ) child;
+            }
+        }
 
-	private static IType findType(ITypeRoot root) throws JavaModelException {
-		// TODO Auto-generated method stub
-		for ( IJavaElement child : root.getChildren() ) {
-			if ( child.getElementType() == IJavaElement.TYPE ) {
-				return (IType) child;
-			}
-		}
-		
-		throw new JavaModelException( new IllegalStateException( "Missing type for " + root) , IStatus.ERROR );
-	}
+        throw new JavaModelException( new IllegalStateException( "Missing type for " + root ), IStatus.ERROR );
+    }
 }
\ No newline at end of file
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/ModelHelper.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/ModelHelper.java
index 690fc8a..bea3a14 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/ModelHelper.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/ModelHelper.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.model.util;
 
+
 import java.util.LinkedList;
 import java.util.List;
 
@@ -31,56 +32,73 @@
 import org.apache.felix.sigil.model.osgi.IPackageImport;
 import org.apache.felix.sigil.model.osgi.IRequiredBundle;
 
-public class ModelHelper {
-	public static List<IModelElement> findUsers(IModelElement e) {
-		LinkedList<IModelElement> users = new LinkedList<IModelElement>();
-		
-		findUsers(e, users);
-		
-		return users;
-	}
 
-	private static void findUsers(IModelElement e, final LinkedList<IModelElement> users) {
-		if ( e instanceof IPackageExport ) {
-			final IPackageExport pe = (IPackageExport) e;
-			SigilCore.getGlobalRepositoryManager().visit( new IModelWalker() {
-				public boolean visit(IModelElement element) {
-					if ( element instanceof IPackageImport ) {
-						IPackageImport pi = (IPackageImport) element;
-						if ( pi.accepts( pe ) ) {
-							users.add( pi );
-						}
-						return false;
-					}
-					
-					return true;
-				} 
-			} );
-		}
-		else if ( e instanceof IBundleModelElement ) {
-			final IBundleModelElement bndl = (IBundleModelElement) e;
-			
-			SigilCore.getGlobalRepositoryManager().visit( new IModelWalker() {
-				public boolean visit(IModelElement element) {
-					if ( element instanceof IRequiredBundle ) {
-						IRequiredBundle req = (IRequiredBundle) element;
-						if ( req.accepts( bndl ) ) {
-							users.add( req );
-						}
-						return false;
-					}
-					return true;
-				} 
-			} );
-		}
-		
-		if ( e instanceof ICompoundModelElement ) {
-			ICompoundModelElement c = (ICompoundModelElement) e;
-			IModelElement[] ch = c.children();
-			for ( IModelElement ee : ch ) {
-				findUsers( ee, users );
-			}
-		}
-	}
+public class ModelHelper
+{
+    public static List<IModelElement> findUsers( IModelElement e )
+    {
+        LinkedList<IModelElement> users = new LinkedList<IModelElement>();
+
+        findUsers( e, users );
+
+        return users;
+    }
+
+
+    private static void findUsers( IModelElement e, final LinkedList<IModelElement> users )
+    {
+        if ( e instanceof IPackageExport )
+        {
+            final IPackageExport pe = ( IPackageExport ) e;
+            SigilCore.getGlobalRepositoryManager().visit( new IModelWalker()
+            {
+                public boolean visit( IModelElement element )
+                {
+                    if ( element instanceof IPackageImport )
+                    {
+                        IPackageImport pi = ( IPackageImport ) element;
+                        if ( pi.accepts( pe ) )
+                        {
+                            users.add( pi );
+                        }
+                        return false;
+                    }
+
+                    return true;
+                }
+            } );
+        }
+        else if ( e instanceof IBundleModelElement )
+        {
+            final IBundleModelElement bndl = ( IBundleModelElement ) e;
+
+            SigilCore.getGlobalRepositoryManager().visit( new IModelWalker()
+            {
+                public boolean visit( IModelElement element )
+                {
+                    if ( element instanceof IRequiredBundle )
+                    {
+                        IRequiredBundle req = ( IRequiredBundle ) element;
+                        if ( req.accepts( bndl ) )
+                        {
+                            users.add( req );
+                        }
+                        return false;
+                    }
+                    return true;
+                }
+            } );
+        }
+
+        if ( e instanceof ICompoundModelElement )
+        {
+            ICompoundModelElement c = ( ICompoundModelElement ) e;
+            IModelElement[] ch = c.children();
+            for ( IModelElement ee : ch )
+            {
+                findUsers( ee, users );
+            }
+        }
+    }
 
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/ProfileManager.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/ProfileManager.java
index 751a0bb..23d67c1 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/ProfileManager.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/model/util/ProfileManager.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.model.util;
 
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
@@ -34,128 +35,162 @@
 import org.eclipse.core.runtime.Platform;
 import org.osgi.framework.Bundle;
 
-public class ProfileManager {
-	private static final Pattern[] BOOT_DELEGATION_PATTERNS = new Pattern[] {
-		GlobCompiler.compile("org.ietf.jgss"),
-		GlobCompiler.compile("org.omg.*"),
-		GlobCompiler.compile("org.w3c.*"),
-		GlobCompiler.compile("org.xml.*"),
-		GlobCompiler.compile("sun.*"),
-		GlobCompiler.compile("com.sun.*"),
-	};
-	
-	private static HashMap<String, Properties> profiles;
 
-	public static boolean isBootDelegate(ISigilProjectModel project, String packageName) {
-		if ( packageName.startsWith( "java." ) ) {
-			return true;
-		}
-		
-		for ( Pattern p : BOOT_DELEGATION_PATTERNS ) {
-			if ( p.matcher(packageName).matches()) {
-				return true;
-			}
-		}
-		return false;
-	}
-	
-	public static Properties findProfileForVersion(String javaVersion) {
-		Map<String, Properties> profiles = loadProfiles();
-		
-		if ( "1.5.0".equals( javaVersion ) ) {
-			return profiles.get( "J2SE-1.5" );
-		}
-		else if ( "1.6.0".equals( javaVersion ) ) {
-			return profiles.get( "J2SE-1.6" );
-		}
-		
-		return null;
-	}
-	
-	private synchronized static Map<String, Properties> loadProfiles() {
-		if ( profiles == null ) {
-			profiles = new HashMap<String, Properties>();
-			
-			Bundle b = Platform.getBundle("org.eclipse.osgi");
-			
-			for ( String profile : loadProfiles( b )) {
-				if ( profile.trim().length() > 0 ) {
-					URL url = findURL(profile, b);
-					if ( url != null ) {
-						try {
-							Properties p = loadProperties(url);
-							String name = p.getProperty("osgi.java.profile.name");
-							if ( name != null ) {
-								profiles.put(name, p);
-							}
-							else {
-								SigilCore.error( "Invalid profile definition, no name specified: " + url);
-							}
-						} catch (IOException e) {
-							SigilCore.error( "Failed to load java profile", e );
-						}
-					}
-					else {
-						SigilCore.error( "Unknown profile **" + profile + "**" );
-					}
-				}
-				// else ignore empty values
-			}
-		}
-		return profiles;
-	}
+public class ProfileManager
+{
+    private static final Pattern[] BOOT_DELEGATION_PATTERNS = new Pattern[]
+        { GlobCompiler.compile( "org.ietf.jgss" ), GlobCompiler.compile( "org.omg.*" ),
+            GlobCompiler.compile( "org.w3c.*" ), GlobCompiler.compile( "org.xml.*" ), GlobCompiler.compile( "sun.*" ),
+            GlobCompiler.compile( "com.sun.*" ), };
 
-	private static String[] loadProfiles(Bundle b) {
-		URL url = findURL("profile.list", b);
-
-		if ( url != null ) {
-			try {
-				Properties p = loadProperties(url);
-				String s = p.getProperty("java.profiles");
-				return s == null ? new String[] {} : s.split(",");
-			} catch (IOException e) {
-				SigilCore.error( "Failed to load java profile list", e );
-			}
-		}
-		else {
-			SigilCore.error( "Failed to find java profile list" );
-		}
-		
-		// fine no properties found
-		return new String[] {};
-	}
-
-	@SuppressWarnings("unchecked")
-	private static URL findURL(String file, Bundle b) {
-		Enumeration e = b.findEntries("/", file, false);
-		return e == null ? null : (URL) (e.hasMoreElements() ? e.nextElement() : null);
-	}
+    private static HashMap<String, Properties> profiles;
 
 
-	private static Properties loadProperties(URL url) throws IOException {
-		Properties p = new Properties();
-		
-		InputStream in = null;
-		
-		try {
-			in = url.openStream();
-			p.load(in);
-		}
-		finally {
-			if ( in != null ) {
-				try {
-					in.close();
-				} catch (IOException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-			}
-		}
-		
-		return p;
-	}
+    public static boolean isBootDelegate( ISigilProjectModel project, String packageName )
+    {
+        if ( packageName.startsWith( "java." ) )
+        {
+            return true;
+        }
+
+        for ( Pattern p : BOOT_DELEGATION_PATTERNS )
+        {
+            if ( p.matcher( packageName ).matches() )
+            {
+                return true;
+            }
+        }
+        return false;
+    }
 
 
+    public static Properties findProfileForVersion( String javaVersion )
+    {
+        Map<String, Properties> profiles = loadProfiles();
 
+        if ( "1.5.0".equals( javaVersion ) )
+        {
+            return profiles.get( "J2SE-1.5" );
+        }
+        else if ( "1.6.0".equals( javaVersion ) )
+        {
+            return profiles.get( "J2SE-1.6" );
+        }
+
+        return null;
+    }
+
+
+    private synchronized static Map<String, Properties> loadProfiles()
+    {
+        if ( profiles == null )
+        {
+            profiles = new HashMap<String, Properties>();
+
+            Bundle b = Platform.getBundle( "org.eclipse.osgi" );
+
+            for ( String profile : loadProfiles( b ) )
+            {
+                if ( profile.trim().length() > 0 )
+                {
+                    URL url = findURL( profile, b );
+                    if ( url != null )
+                    {
+                        try
+                        {
+                            Properties p = loadProperties( url );
+                            String name = p.getProperty( "osgi.java.profile.name" );
+                            if ( name != null )
+                            {
+                                profiles.put( name, p );
+                            }
+                            else
+                            {
+                                SigilCore.error( "Invalid profile definition, no name specified: " + url );
+                            }
+                        }
+                        catch ( IOException e )
+                        {
+                            SigilCore.error( "Failed to load java profile", e );
+                        }
+                    }
+                    else
+                    {
+                        SigilCore.error( "Unknown profile **" + profile + "**" );
+                    }
+                }
+                // else ignore empty values
+            }
+        }
+        return profiles;
+    }
+
+
+    private static String[] loadProfiles( Bundle b )
+    {
+        URL url = findURL( "profile.list", b );
+
+        if ( url != null )
+        {
+            try
+            {
+                Properties p = loadProperties( url );
+                String s = p.getProperty( "java.profiles" );
+                return s == null ? new String[]
+                    {} : s.split( "," );
+            }
+            catch ( IOException e )
+            {
+                SigilCore.error( "Failed to load java profile list", e );
+            }
+        }
+        else
+        {
+            SigilCore.error( "Failed to find java profile list" );
+        }
+
+        // fine no properties found
+        return new String[]
+            {};
+    }
+
+
+    @SuppressWarnings("unchecked")
+    private static URL findURL( String file, Bundle b )
+    {
+        Enumeration e = b.findEntries( "/", file, false );
+        return e == null ? null : ( URL ) ( e.hasMoreElements() ? e.nextElement() : null );
+    }
+
+
+    private static Properties loadProperties( URL url ) throws IOException
+    {
+        Properties p = new Properties();
+
+        InputStream in = null;
+
+        try
+        {
+            in = url.openStream();
+            p.load( in );
+        }
+        finally
+        {
+            if ( in != null )
+            {
+                try
+                {
+                    in.close();
+                }
+                catch ( IOException e )
+                {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return p;
+    }
 
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/nature/SigilProjectNature.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/nature/SigilProjectNature.java
index 7908789..603e61e 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/nature/SigilProjectNature.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/nature/SigilProjectNature.java
@@ -19,27 +19,38 @@
 
 package org.apache.felix.sigil.eclipse.nature;
 
+
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IProjectNature;
 import org.eclipse.core.runtime.CoreException;
 
-public class SigilProjectNature implements IProjectNature {
+
+public class SigilProjectNature implements IProjectNature
+{
 
     private IProject project;
-    
-    public void configure() throws CoreException {
+
+
+    public void configure() throws CoreException
+    {
         // TODO configure project builder
 
     }
 
-    public void deconfigure() throws CoreException {
+
+    public void deconfigure() throws CoreException
+    {
     }
 
-    public IProject getProject() {
+
+    public IProject getProject()
+    {
         return project;
     }
 
-    public void setProject(IProject project) {
+
+    public void setProject( IProject project )
+    {
         this.project = project;
     }
 
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/preferences/PrefsUtils.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/preferences/PrefsUtils.java
index 8e17fd8..e525c41 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/preferences/PrefsUtils.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/preferences/PrefsUtils.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.preferences;
 
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -26,39 +27,52 @@
 import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.lang.text.StrTokenizer;
 
-public class PrefsUtils {
 
-	private PrefsUtils() {
-	}
+public class PrefsUtils
+{
 
-	public static final String arrayToString(String[] array) {
-		StringBuilder builder = new StringBuilder();
+    private PrefsUtils()
+    {
+    }
 
-		for (int i = 0; i < array.length; i++) {
-			if (i > 0)
-				builder.append(',');
-			builder.append(StringEscapeUtils.escapeCsv(array[i]));
-		}
 
-		return builder.toString();
-	}
+    public static final String arrayToString( String[] array )
+    {
+        StringBuilder builder = new StringBuilder();
 
-	public static final String[] stringToArray(String string) {
-		StrTokenizer tokenizer = new StrTokenizer(string, ',', '"');
-		String[] array = new String[tokenizer.size()];
+        for ( int i = 0; i < array.length; i++ )
+        {
+            if ( i > 0 )
+                builder.append( ',' );
+            builder.append( StringEscapeUtils.escapeCsv( array[i] ) );
+        }
 
-		for (int i = 0; i < array.length; i++) {
-			array[i] = tokenizer.nextToken();
-		}
+        return builder.toString();
+    }
 
-		return array;
-	}
 
-	public static String listToString(List<String> names) {
-		return arrayToString(names.toArray( new String[names.size()]));
-	}
+    public static final String[] stringToArray( String string )
+    {
+        StrTokenizer tokenizer = new StrTokenizer( string, ',', '"' );
+        String[] array = new String[tokenizer.size()];
 
-	public static List<String> stringToList(String string) {
-		return new ArrayList<String>(Arrays.asList(stringToArray(string)));
-	}
+        for ( int i = 0; i < array.length; i++ )
+        {
+            array[i] = tokenizer.nextToken();
+        }
+
+        return array;
+    }
+
+
+    public static String listToString( List<String> names )
+    {
+        return arrayToString( names.toArray( new String[names.size()] ) );
+    }
+
+
+    public static List<String> stringToList( String string )
+    {
+        return new ArrayList<String>( Arrays.asList( stringToArray( string ) ) );
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/preferences/PromptablePreference.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/preferences/PromptablePreference.java
index 235f626..4235c54 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/preferences/PromptablePreference.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/preferences/PromptablePreference.java
@@ -19,6 +19,8 @@
 
 package org.apache.felix.sigil.eclipse.preferences;
 
-public enum PromptablePreference {
-	Always, Prompt, Never
+
+public enum PromptablePreference
+{
+    Always, Prompt, Never
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/preferences/SigilPreferencesInitializer.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/preferences/SigilPreferencesInitializer.java
index 5f81c12..c464092 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/preferences/SigilPreferencesInitializer.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/preferences/SigilPreferencesInitializer.java
@@ -26,29 +26,32 @@
 import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
 import org.eclipse.jface.preference.IPreferenceStore;
 
-public class SigilPreferencesInitializer extends AbstractPreferenceInitializer {
-	
-	public static final String[] EXCLUDED_RESOURCES = new String[] {
-		".project", ".classpath", ".settings"
-	};
-	
-	@Override
-	public void initializeDefaultPreferences() {
-		IPreferenceStore store = SigilCore.getDefault().getPreferenceStore();
 
-		store.setDefault(SigilCore.OSGI_INSTALL_CHECK_PREFERENCE, true);
+public class SigilPreferencesInitializer extends AbstractPreferenceInitializer
+{
 
-		store.setDefault(SigilCore.DEFAULT_VERSION_LOWER_BOUND, VersionRangeBoundingRule.Micro.name());
-		store.setDefault(SigilCore.DEFAULT_VERSION_UPPER_BOUND, VersionRangeBoundingRule.Any.name());
+    public static final String[] EXCLUDED_RESOURCES = new String[]
+        { ".project", ".classpath", ".settings" };
 
-		store.setDefault(SigilCore.DEFAULT_EXCLUDED_RESOURCES, PrefsUtils.arrayToString(EXCLUDED_RESOURCES));
-		
-		store.setDefault(SigilCore.PREFERENCES_NOASK_OSGI_INSTALL, false);
-		
-		store.setDefault(SigilCore.PREFERENCES_ADD_IMPORT_FOR_EXPORT, PromptablePreference.Prompt.name());
-		
-		store.setDefault(SigilCore.PREFERENCES_REBUILD_PROJECTS, PromptablePreference.Prompt.name() );
-		
-		store.setDefault(RepositoryConfiguration.REPOSITORY_DEFAULT_SET, "org.cauldron.sigil.core.workspaceprovider" );
-	}
+
+    @Override
+    public void initializeDefaultPreferences()
+    {
+        IPreferenceStore store = SigilCore.getDefault().getPreferenceStore();
+
+        store.setDefault( SigilCore.OSGI_INSTALL_CHECK_PREFERENCE, true );
+
+        store.setDefault( SigilCore.DEFAULT_VERSION_LOWER_BOUND, VersionRangeBoundingRule.Micro.name() );
+        store.setDefault( SigilCore.DEFAULT_VERSION_UPPER_BOUND, VersionRangeBoundingRule.Any.name() );
+
+        store.setDefault( SigilCore.DEFAULT_EXCLUDED_RESOURCES, PrefsUtils.arrayToString( EXCLUDED_RESOURCES ) );
+
+        store.setDefault( SigilCore.PREFERENCES_NOASK_OSGI_INSTALL, false );
+
+        store.setDefault( SigilCore.PREFERENCES_ADD_IMPORT_FOR_EXPORT, PromptablePreference.Prompt.name() );
+
+        store.setDefault( SigilCore.PREFERENCES_REBUILD_PROJECTS, PromptablePreference.Prompt.name() );
+
+        store.setDefault( RepositoryConfiguration.REPOSITORY_DEFAULT_SET, "org.cauldron.sigil.core.workspaceprovider" );
+    }
 }
diff --git a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/property/SigilPropertyTester.java b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/property/SigilPropertyTester.java
index 34f3adf..97f8baf 100644
--- a/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/property/SigilPropertyTester.java
+++ b/sigil/eclipse/core/src/org/apache/felix/sigil/eclipse/property/SigilPropertyTester.java
@@ -19,36 +19,47 @@
 
 package org.apache.felix.sigil.eclipse.property;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.eclipse.core.expressions.PropertyTester;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 
-public class SigilPropertyTester extends PropertyTester {
 
-	public SigilPropertyTester() {
-	}
+public class SigilPropertyTester extends PropertyTester
+{
 
-	public boolean test( Object receiver, String property, Object[] args, Object expectedValue ) {
-		IResource resource = (IResource) receiver;
-		if ( "isSigilProject".equals( property ) ) {
-			return expectedValue.equals( isSigilProjectLikeResource( resource ) );
-		}
-		return false;
-	}
+    public SigilPropertyTester()
+    {
+    }
 
-	/**
-	 * @param resource
-	 * @return
-	 */
-	private static boolean isSigilProjectLikeResource(IResource resource) {
-		if ( resource instanceof IProject ) {
-			IProject p = (IProject) resource;
-			return SigilCore.isSigilProject(p);
-		}
-		else {
-			return resource.getName().equals( SigilCore.SIGIL_PROJECT_FILE );
-		}
-	}
+
+    public boolean test( Object receiver, String property, Object[] args, Object expectedValue )
+    {
+        IResource resource = ( IResource ) receiver;
+        if ( "isSigilProject".equals( property ) )
+        {
+            return expectedValue.equals( isSigilProjectLikeResource( resource ) );
+        }
+        return false;
+    }
+
+
+    /**
+     * @param resource
+     * @return
+     */
+    private static boolean isSigilProjectLikeResource( IResource resource )
+    {
+        if ( resource instanceof IProject )
+        {
+            IProject p = ( IProject ) resource;
+            return SigilCore.isSigilProject( p );
+        }
+        else
+        {
+            return resource.getName().equals( SigilCore.SIGIL_PROJECT_FILE );
+        }
+    }
 
 }
diff --git a/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/AbstractNewWizardAction.java b/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/AbstractNewWizardAction.java
index 3632348..be13319 100644
--- a/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/AbstractNewWizardAction.java
+++ b/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/AbstractNewWizardAction.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.cheatsheets.actions;
 
+
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.viewers.ISelection;
@@ -31,36 +32,45 @@
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PlatformUI;
 
-public abstract class AbstractNewWizardAction extends Action {
 
-	@Override
-	public void run() {
-		Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
-		
-		try {
-			INewWizard wizard = createWizard();
-			wizard.init(PlatformUI.getWorkbench(), getSelection());
-			WizardDialog dialog = new WizardDialog(shell, wizard);
-			int res = dialog.open();
-			notifyResult(res == Window.OK);
-		} catch (CoreException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}		
-	}
-	
-	protected abstract INewWizard createWizard() throws CoreException;
+public abstract class AbstractNewWizardAction extends Action
+{
 
-	private IStructuredSelection getSelection() {
-		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
-		if (window != null)
-		{
-			ISelection selection = window.getSelectionService().getSelection();
-			if (selection instanceof IStructuredSelection)
-			{
-				return (IStructuredSelection)selection;
-			}
-		}
-		return StructuredSelection.EMPTY;
-	}
+    @Override
+    public void run()
+    {
+        Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+
+        try
+        {
+            INewWizard wizard = createWizard();
+            wizard.init( PlatformUI.getWorkbench(), getSelection() );
+            WizardDialog dialog = new WizardDialog( shell, wizard );
+            int res = dialog.open();
+            notifyResult( res == Window.OK );
+        }
+        catch ( CoreException e )
+        {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+
+    protected abstract INewWizard createWizard() throws CoreException;
+
+
+    private IStructuredSelection getSelection()
+    {
+        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+        if ( window != null )
+        {
+            ISelection selection = window.getSelectionService().getSelection();
+            if ( selection instanceof IStructuredSelection )
+            {
+                return ( IStructuredSelection ) selection;
+            }
+        }
+        return StructuredSelection.EMPTY;
+    }
 }
\ No newline at end of file
diff --git a/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/CopyResourceFromPlugin.java b/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/CopyResourceFromPlugin.java
index 7713798..6be47b2 100644
--- a/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/CopyResourceFromPlugin.java
+++ b/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/CopyResourceFromPlugin.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.cheatsheets.actions;
 
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.InvocationTargetException;
@@ -46,71 +47,92 @@
 import org.eclipse.ui.part.FileEditorInput;
 import org.osgi.framework.Bundle;
 
-public class CopyResourceFromPlugin extends Action implements ICheatSheetAction {
 
-	private String targetProject;
-	private String targetFolder;
-	private String sourceBundle;
-	private String sourcePath;
-	private String editorID;
-	
-	public void run(String[] params, ICheatSheetManager manager) {
-		if ( params != null && params.length > 4 )  {
-			targetProject = params[0];
-			targetFolder = params[1];
-			sourceBundle= params[2];
-			sourcePath = params[3];
-			editorID = params[4];
-		}
-		
-		WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
-			@Override
-			protected void execute(IProgressMonitor monitor) throws CoreException {
-				try {
-					Bundle b = Platform.getBundle(sourceBundle);
-					
-				    IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
-				    IProject project = workspaceRoot.getProject(targetProject);
-				    IPath path = new Path( targetFolder ).append( sourcePath.substring( sourcePath.lastIndexOf( '/' ) ) );
-					IFile file = project.getFile( path );
-					
-					if ( !file.exists() ) {
-						mkdirs( (IFolder) file.getParent(), monitor );
-						
-						InputStream in = FileLocator.openStream(b, new Path(sourcePath), false);
-						file.create(in, true, monitor);
-					}
-					
-					IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
-					FileEditorInput input = new FileEditorInput(file); 
-					window.getActivePage().openEditor(input, editorID);
-				} catch (IOException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-			}
-		};
-		
-		try {
-			new ProgressMonitorDialog(Display.getCurrent().getActiveShell()).run(false, false, op);
-		} catch (InvocationTargetException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (InterruptedException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}
+public class CopyResourceFromPlugin extends Action implements ICheatSheetAction
+{
 
-	private void mkdirs(IFolder folder, IProgressMonitor monitor) throws CoreException {
-		IContainer parent = folder.getParent();
-		if ( !parent.exists() ) {
-			mkdirs((IFolder) parent, monitor);			
-		}
-		
-		if ( !folder.exists() ) {
-			folder.create(true, true, monitor);
-		}
-		
-	}		
+    private String targetProject;
+    private String targetFolder;
+    private String sourceBundle;
+    private String sourcePath;
+    private String editorID;
+
+
+    public void run( String[] params, ICheatSheetManager manager )
+    {
+        if ( params != null && params.length > 4 )
+        {
+            targetProject = params[0];
+            targetFolder = params[1];
+            sourceBundle = params[2];
+            sourcePath = params[3];
+            editorID = params[4];
+        }
+
+        WorkspaceModifyOperation op = new WorkspaceModifyOperation()
+        {
+            @Override
+            protected void execute( IProgressMonitor monitor ) throws CoreException
+            {
+                try
+                {
+                    Bundle b = Platform.getBundle( sourceBundle );
+
+                    IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+                    IProject project = workspaceRoot.getProject( targetProject );
+                    IPath path = new Path( targetFolder )
+                        .append( sourcePath.substring( sourcePath.lastIndexOf( '/' ) ) );
+                    IFile file = project.getFile( path );
+
+                    if ( !file.exists() )
+                    {
+                        mkdirs( ( IFolder ) file.getParent(), monitor );
+
+                        InputStream in = FileLocator.openStream( b, new Path( sourcePath ), false );
+                        file.create( in, true, monitor );
+                    }
+
+                    IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+                    FileEditorInput input = new FileEditorInput( file );
+                    window.getActivePage().openEditor( input, editorID );
+                }
+                catch ( IOException e )
+                {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+        };
+
+        try
+        {
+            new ProgressMonitorDialog( Display.getCurrent().getActiveShell() ).run( false, false, op );
+        }
+        catch ( InvocationTargetException e )
+        {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        catch ( InterruptedException e )
+        {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+
+    private void mkdirs( IFolder folder, IProgressMonitor monitor ) throws CoreException
+    {
+        IContainer parent = folder.getParent();
+        if ( !parent.exists() )
+        {
+            mkdirs( ( IFolder ) parent, monitor );
+        }
+
+        if ( !folder.exists() )
+        {
+            folder.create( true, true, monitor );
+        }
+
+    }
 }
diff --git a/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/OpenEmptySigilProjectWizardAction.java b/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/OpenEmptySigilProjectWizardAction.java
index 76678c5..e1a3463 100644
--- a/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/OpenEmptySigilProjectWizardAction.java
+++ b/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/OpenEmptySigilProjectWizardAction.java
@@ -19,28 +19,36 @@
 
 package org.apache.felix.sigil.eclipse.cheatsheets.actions;
 
+
 import org.apache.felix.sigil.ui.eclipse.ui.wizard.project.SigilProjectWizard;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.ui.INewWizard;
 import org.eclipse.ui.cheatsheets.ICheatSheetAction;
 import org.eclipse.ui.cheatsheets.ICheatSheetManager;
 
-public class OpenEmptySigilProjectWizardAction extends AbstractNewWizardAction implements ICheatSheetAction {
 
-	private String name;
-	
-	public void run(String[] params, ICheatSheetManager manager) {
-		if ( params != null && params.length > 0 )  {
-			name = params[0];
-		}
-		
-		run();
-	}
+public class OpenEmptySigilProjectWizardAction extends AbstractNewWizardAction implements ICheatSheetAction
+{
 
-	@Override
-	protected INewWizard createWizard() throws CoreException {
-		SigilProjectWizard wizard = new SigilProjectWizard();
-		wizard.setName(name);
-		return wizard;
-	}
+    private String name;
+
+
+    public void run( String[] params, ICheatSheetManager manager )
+    {
+        if ( params != null && params.length > 0 )
+        {
+            name = params[0];
+        }
+
+        run();
+    }
+
+
+    @Override
+    protected INewWizard createWizard() throws CoreException
+    {
+        SigilProjectWizard wizard = new SigilProjectWizard();
+        wizard.setName( name );
+        return wizard;
+    }
 }
diff --git a/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/ResolveProjectDependencies.java b/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/ResolveProjectDependencies.java
index 0648eda..2abd95e 100644
--- a/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/ResolveProjectDependencies.java
+++ b/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/ResolveProjectDependencies.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.cheatsheets.actions;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.apache.felix.sigil.ui.eclipse.actions.ResolveProjectDependenciesAction;
@@ -30,24 +31,32 @@
 import org.eclipse.ui.cheatsheets.ICheatSheetAction;
 import org.eclipse.ui.cheatsheets.ICheatSheetManager;
 
-public class ResolveProjectDependencies extends Action implements ICheatSheetAction {
 
-	private String targetProject;
-	
-	public void run(String[] params, ICheatSheetManager manager) {
-		if ( params != null && params.length > 3 )  {
-			targetProject = params[0];
-		}
+public class ResolveProjectDependencies extends Action implements ICheatSheetAction
+{
 
-	    IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
-	    IProject project = workspaceRoot.getProject(targetProject);
-	    
-	    try {
-			ISigilProjectModel sigil = SigilCore.create(project);
-			new ResolveProjectDependenciesAction(sigil, false).run();
-		} catch (CoreException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}
+    private String targetProject;
+
+
+    public void run( String[] params, ICheatSheetManager manager )
+    {
+        if ( params != null && params.length > 3 )
+        {
+            targetProject = params[0];
+        }
+
+        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+        IProject project = workspaceRoot.getProject( targetProject );
+
+        try
+        {
+            ISigilProjectModel sigil = SigilCore.create( project );
+            new ResolveProjectDependenciesAction( sigil, false ).run();
+        }
+        catch ( CoreException e )
+        {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
 }
diff --git a/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/ShowViewAction.java b/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/ShowViewAction.java
index 261ea91..57ebfff 100644
--- a/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/ShowViewAction.java
+++ b/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/cheatsheets/actions/ShowViewAction.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.eclipse.cheatsheets.actions;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.eclipse.jface.action.Action;
 import org.eclipse.ui.IWorkbenchPage;
@@ -28,18 +29,25 @@
 import org.eclipse.ui.cheatsheets.ICheatSheetAction;
 import org.eclipse.ui.cheatsheets.ICheatSheetManager;
 
-public class ShowViewAction extends Action implements ICheatSheetAction {
 
-	public void run(String[] params, ICheatSheetManager manager) {
-		if ( params != null && params.length > 0 )  {
-			IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
-			IWorkbenchPage page = window.getActivePage();
-			try {
-				page.showView(params[0]);
-			} catch (PartInitException e) {
-				SigilCore.error( "Failed to show view", e);
-			}
-		}
+public class ShowViewAction extends Action implements ICheatSheetAction
+{
 
-	}
+    public void run( String[] params, ICheatSheetManager manager )
+    {
+        if ( params != null && params.length > 0 )
+        {
+            IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+            IWorkbenchPage page = window.getActivePage();
+            try
+            {
+                page.showView( params[0] );
+            }
+            catch ( PartInitException e )
+            {
+                SigilCore.error( "Failed to show view", e );
+            }
+        }
+
+    }
 }
diff --git a/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/help/Activator.java b/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/help/Activator.java
index 1dc98e3..4fe71c2 100644
--- a/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/help/Activator.java
+++ b/sigil/eclipse/help/src/org/apache/felix/sigil/eclipse/help/Activator.java
@@ -19,51 +19,62 @@
 
 package org.apache.felix.sigil.eclipse.help;
 
+
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.osgi.framework.BundleContext;
 
+
 /**
  * The activator class controls the plug-in life cycle
  */
-public class Activator extends AbstractUIPlugin {
+public class Activator extends AbstractUIPlugin
+{
 
-	// The plug-in ID
-	public static final String PLUGIN_ID = "org.cauldron.sigil.help";
+    // The plug-in ID
+    public static final String PLUGIN_ID = "org.cauldron.sigil.help";
 
-	// The shared instance
-	private static Activator plugin;
-	
-	/**
-	 * The constructor
-	 */
-	public Activator() {
-	}
+    // The shared instance
+    private static Activator plugin;
 
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
-	 */
-	public void start(BundleContext context) throws Exception {
-		super.start(context);
-		plugin = this;
-	}
 
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
-	 */
-	public void stop(BundleContext context) throws Exception {
-		plugin = null;
-		super.stop(context);
-	}
+    /**
+     * The constructor
+     */
+    public Activator()
+    {
+    }
 
-	/**
-	 * Returns the shared instance
-	 *
-	 * @return the shared instance
-	 */
-	public static Activator getDefault() {
-		return plugin;
-	}
+
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+     */
+    public void start( BundleContext context ) throws Exception
+    {
+        super.start( context );
+        plugin = this;
+    }
+
+
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+     */
+    public void stop( BundleContext context ) throws Exception
+    {
+        plugin = null;
+        super.stop( context );
+    }
+
+
+    /**
+     * Returns the shared instance
+     *
+     * @return the shared instance
+     */
+    public static Activator getDefault()
+    {
+        return plugin;
+    }
 
 }
diff --git a/sigil/eclipse/obr/src/org/apache/felix/sigil/obr/eclipse/Activator.java b/sigil/eclipse/obr/src/org/apache/felix/sigil/obr/eclipse/Activator.java
index 45683c8..3de91c3 100644
--- a/sigil/eclipse/obr/src/org/apache/felix/sigil/obr/eclipse/Activator.java
+++ b/sigil/eclipse/obr/src/org/apache/felix/sigil/obr/eclipse/Activator.java
@@ -19,51 +19,62 @@
 
 package org.apache.felix.sigil.obr.eclipse;
 
+
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.osgi.framework.BundleContext;
 
+
 /**
  * The activator class controls the plug-in life cycle
  */
-public class Activator extends AbstractUIPlugin {
+public class Activator extends AbstractUIPlugin
+{
 
-	// The plug-in ID
-	public static final String PLUGIN_ID = "org.cauldron.sigil.obr";
+    // The plug-in ID
+    public static final String PLUGIN_ID = "org.cauldron.sigil.obr";
 
-	// The shared instance
-	private static Activator plugin;
-	
-	/**
-	 * The constructor
-	 */
-	public Activator() {
-	}
+    // The shared instance
+    private static Activator plugin;
 
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
-	 */
-	public void start(BundleContext context) throws Exception {
-		super.start(context);
-		plugin = this;
-	}
 
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
-	 */
-	public void stop(BundleContext context) throws Exception {
-		plugin = null;
-		super.stop(context);
-	}
+    /**
+     * The constructor
+     */
+    public Activator()
+    {
+    }
 
-	/**
-	 * Returns the shared instance
-	 *
-	 * @return the shared instance
-	 */
-	public static Activator getDefault() {
-		return plugin;
-	}
+
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+     */
+    public void start( BundleContext context ) throws Exception
+    {
+        super.start( context );
+        plugin = this;
+    }
+
+
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+     */
+    public void stop( BundleContext context ) throws Exception
+    {
+        plugin = null;
+        super.stop( context );
+    }
+
+
+    /**
+     * Returns the shared instance
+     *
+     * @return the shared instance
+     */
+    public static Activator getDefault()
+    {
+        return plugin;
+    }
 
 }
diff --git a/sigil/eclipse/obr/src/org/apache/felix/sigil/obr/eclipse/OBRRepositoryWizard.java b/sigil/eclipse/obr/src/org/apache/felix/sigil/obr/eclipse/OBRRepositoryWizard.java
index 8f06603..f461957 100644
--- a/sigil/eclipse/obr/src/org/apache/felix/sigil/obr/eclipse/OBRRepositoryWizard.java
+++ b/sigil/eclipse/obr/src/org/apache/felix/sigil/obr/eclipse/OBRRepositoryWizard.java
@@ -19,12 +19,16 @@
 
 package org.apache.felix.sigil.obr.eclipse;
 
+
 import org.apache.felix.sigil.ui.eclipse.ui.wizard.repository.RepositoryWizard;
 
-public class OBRRepositoryWizard extends RepositoryWizard {
-	
-	@Override
-	public void addPages() {
-		addPage( new OBRRepositoryWizardPage(this) );
-	}
+
+public class OBRRepositoryWizard extends RepositoryWizard
+{
+
+    @Override
+    public void addPages()
+    {
+        addPage( new OBRRepositoryWizardPage( this ) );
+    }
 }
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 babb384..0f9b4b6 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
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.obr.eclipse;
 
+
 import java.io.File;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -33,79 +34,105 @@
 import org.eclipse.swt.events.ModifyEvent;
 import org.eclipse.swt.events.ModifyListener;
 
-public class OBRRepositoryWizardPage extends RepositoryWizardPage implements IWizardPage {
 
-	private StringFieldEditor urlEditor;
-	private StringFieldEditor cacheEditor;
+public class OBRRepositoryWizardPage extends RepositoryWizardPage implements IWizardPage
+{
 
-	protected OBRRepositoryWizardPage(RepositoryWizard parent) {
-		super("OSGi Bundle Repository", parent);
-	}
+    private StringFieldEditor urlEditor;
+    private StringFieldEditor cacheEditor;
 
-	@Override
-	public void createFieldEditors() {
-		createField( urlEditor = new StringFieldEditor("url", "URL:", getFieldEditorParent()) );
-		createField( cacheEditor = new DirectoryFieldEditor("cache", "Cache:", getFieldEditorParent()) );
-		addField( new BooleanFieldEditor( "inmemory", "In Memory:", getFieldEditorParent() ));
-	}
 
-	private void createField(StringFieldEditor editor) {
-		editor.getTextControl(getFieldEditorParent()).addModifyListener( new ModifyListener() {
-			public void modifyText(ModifyEvent e) {
-				checkPageComplete();
-			}
-		});
-		addField(editor);
-	}
+    protected OBRRepositoryWizardPage( RepositoryWizard parent )
+    {
+        super( "OSGi Bundle Repository", parent );
+    }
 
-	@Override
-	protected void checkPageComplete() {
-		super.checkPageComplete();
-		if ( isPageComplete() && checkURLComplete() ) {
-			checkCacheComplete();
-		}
-	}
 
-	private boolean checkCacheComplete() {
-		setPageComplete(cacheEditor.getStringValue().length() > 0);
-		
-		if ( isPageComplete() ) {
-			if ( new File( cacheEditor.getStringValue() ).isDirectory() ) {
-				setErrorMessage(null);				
-			}
-			else {
-				setErrorMessage("Invalid cache directory");
-				setPageComplete(false);
-			}
-		}
-		
-		return isPageComplete();
-	}
+    @Override
+    public void createFieldEditors()
+    {
+        createField( urlEditor = new StringFieldEditor( "url", "URL:", getFieldEditorParent() ) );
+        createField( cacheEditor = new DirectoryFieldEditor( "cache", "Cache:", getFieldEditorParent() ) );
+        addField( new BooleanFieldEditor( "inmemory", "In Memory:", getFieldEditorParent() ) );
+    }
 
-	private boolean checkURLComplete() {
-		setPageComplete(urlEditor.getStringValue().length() > 0);
-		
-		if ( isPageComplete() ) {
-			try {
-				new URL(urlEditor.getStringValue());
-				setErrorMessage(null);
-			}
-			catch (MalformedURLException e) {
-				if ( !new File(urlEditor.getStringValue()).isFile() ) {
-					setErrorMessage("Invalid repository url: " + e.getMessage());
-					setPageComplete(false);
-				}
-			}
-		}
-		
-		return isPageComplete();
-	}
 
-	@Override
-	public void storeFields() {
-		super.storeFields();
-		IPath dir = Activator.getDefault().getStateLocation();
-		getModel().getPreferences().setValue( "index", dir.append( getModel().getId() + ".obr" ).toOSString() );
-	}
-	
+    private void createField( StringFieldEditor editor )
+    {
+        editor.getTextControl( getFieldEditorParent() ).addModifyListener( new ModifyListener()
+        {
+            public void modifyText( ModifyEvent e )
+            {
+                checkPageComplete();
+            }
+        } );
+        addField( editor );
+    }
+
+
+    @Override
+    protected void checkPageComplete()
+    {
+        super.checkPageComplete();
+        if ( isPageComplete() && checkURLComplete() )
+        {
+            checkCacheComplete();
+        }
+    }
+
+
+    private boolean checkCacheComplete()
+    {
+        setPageComplete( cacheEditor.getStringValue().length() > 0 );
+
+        if ( isPageComplete() )
+        {
+            if ( new File( cacheEditor.getStringValue() ).isDirectory() )
+            {
+                setErrorMessage( null );
+            }
+            else
+            {
+                setErrorMessage( "Invalid cache directory" );
+                setPageComplete( false );
+            }
+        }
+
+        return isPageComplete();
+    }
+
+
+    private boolean checkURLComplete()
+    {
+        setPageComplete( urlEditor.getStringValue().length() > 0 );
+
+        if ( isPageComplete() )
+        {
+            try
+            {
+                new URL( urlEditor.getStringValue() );
+                setErrorMessage( null );
+            }
+            catch ( MalformedURLException e )
+            {
+                if ( !new File( urlEditor.getStringValue() ).isFile() )
+                {
+                    setErrorMessage( "Invalid repository url: " + e.getMessage() );
+                    setPageComplete( false );
+                }
+            }
+        }
+
+        return isPageComplete();
+    }
+
+
+    @Override
+    public void storeFields()
+    {
+        super.storeFields();
+        IPath dir = Activator.getDefault().getStateLocation();
+        getModel().getPreferences().setValue( "index", dir.append( getModel().getId() + ".obr" ).toOSString() );
+    }
+
 }
diff --git a/sigil/eclipse/search/src/org/apache/felix/sigil/search/ISearchResult.java b/sigil/eclipse/search/src/org/apache/felix/sigil/search/ISearchResult.java
index 9a04a25..bf4ea67 100644
--- a/sigil/eclipse/search/src/org/apache/felix/sigil/search/ISearchResult.java
+++ b/sigil/eclipse/search/src/org/apache/felix/sigil/search/ISearchResult.java
@@ -19,12 +19,21 @@
 
 package org.apache.felix.sigil.search;
 
+
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
 import org.apache.felix.sigil.model.osgi.IPackageExport;
 
-public interface ISearchResult {
-	ISigilBundle getProvider();
-	IPackageExport getExport();
-	String getPackageName();
-	String getClassName();
+
+public interface ISearchResult
+{
+    ISigilBundle getProvider();
+
+
+    IPackageExport getExport();
+
+
+    String getPackageName();
+
+
+    String getClassName();
 }
diff --git a/sigil/eclipse/search/src/org/apache/felix/sigil/search/SigilSearch.java b/sigil/eclipse/search/src/org/apache/felix/sigil/search/SigilSearch.java
index 709b015..f0c5d9e 100644
--- a/sigil/eclipse/search/src/org/apache/felix/sigil/search/SigilSearch.java
+++ b/sigil/eclipse/search/src/org/apache/felix/sigil/search/SigilSearch.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.search;
 
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Arrays;
@@ -51,193 +52,259 @@
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.osgi.framework.BundleContext;
 
+
 /**
  * The activator class controls the plug-in life cycle
  */
-public class SigilSearch extends AbstractUIPlugin {
+public class SigilSearch extends AbstractUIPlugin
+{
 
-	// The plug-in ID
-	public static final String PLUGIN_ID = "org.cauldron.sigil.search";
+    // The plug-in ID
+    public static final String PLUGIN_ID = "org.cauldron.sigil.search";
 
-	private static final String CLASS_EXTENSION = ".class";
+    private static final String CLASS_EXTENSION = ".class";
 
-	// The shared instance
-	private static SigilSearch plugin;
-	private static Index index;
+    // The shared instance
+    private static SigilSearch plugin;
+    private static Index index;
 
-	/**
-	 * The constructor
-	 */
-	public SigilSearch() {
-	}
-	
-	public static List<ISearchResult> findProviders(String fullyQualifiedName, ISigilProjectModel sigil, IProgressMonitor monitor) {
-		listen(sigil);
-		return index.findProviders(fullyQualifiedName, monitor);
-	}
-	
-	public static List<ISearchResult> findProviders(Pattern namePattern, ISigilProjectModel sigil, IProgressMonitor monitor) {
-		listen(sigil);
-		return index.findProviders(namePattern, monitor);
-	}
-	
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
-	 */
-	public void start(BundleContext context) throws Exception {
-		super.start(context);
-		plugin = this;
-	}
 
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
-	 */
-	public void stop(BundleContext context) throws Exception {
-		plugin = null;
-		super.stop(context);
-	}
+    /**
+     * The constructor
+     */
+    public SigilSearch()
+    {
+    }
 
-	/**
-	 * Returns the shared instance
-	 *
-	 * @return the shared instance
-	 */
-	public static SigilSearch getDefault() {
-		return plugin;
-	}
-	
-	private static void listen(ISigilProjectModel sigil) {
-		synchronized(plugin) {
-			if ( index == null ) {
-				index = new Index();
-				for ( IBundleRepository rep : SigilCore.getRepositoryManager(sigil).getRepositories() ) {
-					index(index, rep);
-				}
-				
-				SigilCore.getRepositoryManager(sigil).addRepositoryChangeListener( new IRepositoryChangeListener() {
-					public void repositoryChanged(RepositoryChangeEvent event) {
-						index(index, event.getRepository());
-					}					
-				});
-			}
-		}
-	}
 
-	private static void index(final Index index, final IBundleRepository rep) {
-		index.delete(rep);
-		rep.accept( new IRepositoryVisitor() {
-			public boolean visit(ISigilBundle bundle) {
-				ISigilProjectModel p = bundle.getAncestor(ISigilProjectModel.class);
-				if ( p == null ) {
-					if ( bundle.isSynchronized() ) {
-						IPath loc = bundle.getLocation();
-						if ( loc.isAbsolute() ) {
-							indexJar(rep, bundle, loc);
-						}
-					}
-				}
-				else {
-					indexProject(rep, p);
-				}
-				return true;
-			}					
-		});
-	}
-	
-	private static void indexProject(IBundleRepository rep, ISigilProjectModel sigil) {
-		try {
-			for (ICompilationUnit unit : JavaHelper.findCompilationUnits(sigil) ) {
-				IPackageFragment p = (IPackageFragment) unit.getParent();
-				ISigilBundle b = sigil.getBundle();
-				IPackageExport export = b.findExport(p.getElementName());
-				index.addEntry(unit, rep, b, export != null);
-			}
-		} catch (JavaModelException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}
+    public static List<ISearchResult> findProviders( String fullyQualifiedName, ISigilProjectModel sigil,
+        IProgressMonitor monitor )
+    {
+        listen( sigil );
+        return index.findProviders( fullyQualifiedName, monitor );
+    }
 
-	private static void indexJar(IBundleRepository rep, ISigilBundle bundle, IPath loc) {
-		JarFile jar = null;
-		try {
-			jar = new JarFile(loc.toOSString());
-			for (Map.Entry<JarEntry, IPackageExport> export : findExportedClasses(bundle, jar).entrySet() ) {
-				JarEntry entry = export.getKey();
-				InputStream in = null;
-				try {
-					in = jar.getInputStream(entry);
-					ClassParser parser = new ClassParser(in, entry.getName());
-					JavaClass c = parser.parse();
-					index.addEntry(c, rep, bundle, true);
-				}
-				finally {
-					if ( in != null ) {
-						in.close();
-					}
-				}
-			}
-		}
-		catch (IOException e) {
-			SigilCore.error( "Failed to read jar " + loc, e );
-		}
-		finally {
-			if ( jar != null ) {
-				try {
-					jar.close();
-				} catch (IOException e) {
-					SigilCore.error( "Failed to close jar " + loc, e );
-				}
-			}
-		}
-	}
 
-	private static Map<JarEntry, IPackageExport> findExportedClasses(ISigilBundle bundle, JarFile jar) {
-		HashMap<JarEntry, IPackageExport> found = new HashMap<JarEntry, IPackageExport>();
-		
-		IPackageExport[] exports = bundle.getBundleInfo().childrenOfType(IPackageExport.class);
-		if ( exports.length > 0 ) {
-			Arrays.sort(exports, new Comparator<IPackageExport> () {
-				public int compare(IPackageExport o1, IPackageExport o2) {
-					return -1 * o1.compareTo(o2);
-				}				
-			});
-			for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements();) {
-				JarEntry entry = e.nextElement();
-				String className = toClassName(entry);
-				if ( className != null ) {
-					IPackageExport ex = findExport(className, exports);
-					
-					if ( found != null ) {
-						found.put( entry, ex );
-					}
-				}
-			}
-		}
-		
-		return found;
-	}
+    public static List<ISearchResult> findProviders( Pattern namePattern, ISigilProjectModel sigil,
+        IProgressMonitor monitor )
+    {
+        listen( sigil );
+        return index.findProviders( namePattern, monitor );
+    }
 
-	private static IPackageExport findExport(String className, IPackageExport[] exports) {
-		for ( IPackageExport e : exports ) {
-			if ( className.startsWith(e.getPackageName())) {
-				return e;
-			}
-		}
-		return null;
-	}
 
-	private static String toClassName(JarEntry entry) {
-		String name = entry.getName();
-		if ( name.endsWith(CLASS_EXTENSION) ) {
-			name = name.substring(0, name.length() - CLASS_EXTENSION.length());
-			name = name.replace('/', '.');
-			return name;
-		}
-		else {
-			return null;
-		}
-	}
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+     */
+    public void start( BundleContext context ) throws Exception
+    {
+        super.start( context );
+        plugin = this;
+    }
+
+
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+     */
+    public void stop( BundleContext context ) throws Exception
+    {
+        plugin = null;
+        super.stop( context );
+    }
+
+
+    /**
+     * Returns the shared instance
+     *
+     * @return the shared instance
+     */
+    public static SigilSearch getDefault()
+    {
+        return plugin;
+    }
+
+
+    private static void listen( ISigilProjectModel sigil )
+    {
+        synchronized ( plugin )
+        {
+            if ( index == null )
+            {
+                index = new Index();
+                for ( IBundleRepository rep : SigilCore.getRepositoryManager( sigil ).getRepositories() )
+                {
+                    index( index, rep );
+                }
+
+                SigilCore.getRepositoryManager( sigil ).addRepositoryChangeListener( new IRepositoryChangeListener()
+                {
+                    public void repositoryChanged( RepositoryChangeEvent event )
+                    {
+                        index( index, event.getRepository() );
+                    }
+                } );
+            }
+        }
+    }
+
+
+    private static void index( final Index index, final IBundleRepository rep )
+    {
+        index.delete( rep );
+        rep.accept( new IRepositoryVisitor()
+        {
+            public boolean visit( ISigilBundle bundle )
+            {
+                ISigilProjectModel p = bundle.getAncestor( ISigilProjectModel.class );
+                if ( p == null )
+                {
+                    if ( bundle.isSynchronized() )
+                    {
+                        IPath loc = bundle.getLocation();
+                        if ( loc.isAbsolute() )
+                        {
+                            indexJar( rep, bundle, loc );
+                        }
+                    }
+                }
+                else
+                {
+                    indexProject( rep, p );
+                }
+                return true;
+            }
+        } );
+    }
+
+
+    private static void indexProject( IBundleRepository rep, ISigilProjectModel sigil )
+    {
+        try
+        {
+            for ( ICompilationUnit unit : JavaHelper.findCompilationUnits( sigil ) )
+            {
+                IPackageFragment p = ( IPackageFragment ) unit.getParent();
+                ISigilBundle b = sigil.getBundle();
+                IPackageExport export = b.findExport( p.getElementName() );
+                index.addEntry( unit, rep, b, export != null );
+            }
+        }
+        catch ( JavaModelException e )
+        {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+
+    private static void indexJar( IBundleRepository rep, ISigilBundle bundle, IPath loc )
+    {
+        JarFile jar = null;
+        try
+        {
+            jar = new JarFile( loc.toOSString() );
+            for ( Map.Entry<JarEntry, IPackageExport> export : findExportedClasses( bundle, jar ).entrySet() )
+            {
+                JarEntry entry = export.getKey();
+                InputStream in = null;
+                try
+                {
+                    in = jar.getInputStream( entry );
+                    ClassParser parser = new ClassParser( in, entry.getName() );
+                    JavaClass c = parser.parse();
+                    index.addEntry( c, rep, bundle, true );
+                }
+                finally
+                {
+                    if ( in != null )
+                    {
+                        in.close();
+                    }
+                }
+            }
+        }
+        catch ( IOException e )
+        {
+            SigilCore.error( "Failed to read jar " + loc, e );
+        }
+        finally
+        {
+            if ( jar != null )
+            {
+                try
+                {
+                    jar.close();
+                }
+                catch ( IOException e )
+                {
+                    SigilCore.error( "Failed to close jar " + loc, e );
+                }
+            }
+        }
+    }
+
+
+    private static Map<JarEntry, IPackageExport> findExportedClasses( ISigilBundle bundle, JarFile jar )
+    {
+        HashMap<JarEntry, IPackageExport> found = new HashMap<JarEntry, IPackageExport>();
+
+        IPackageExport[] exports = bundle.getBundleInfo().childrenOfType( IPackageExport.class );
+        if ( exports.length > 0 )
+        {
+            Arrays.sort( exports, new Comparator<IPackageExport>()
+            {
+                public int compare( IPackageExport o1, IPackageExport o2 )
+                {
+                    return -1 * o1.compareTo( o2 );
+                }
+            } );
+            for ( Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements(); )
+            {
+                JarEntry entry = e.nextElement();
+                String className = toClassName( entry );
+                if ( className != null )
+                {
+                    IPackageExport ex = findExport( className, exports );
+
+                    if ( found != null )
+                    {
+                        found.put( entry, ex );
+                    }
+                }
+            }
+        }
+
+        return found;
+    }
+
+
+    private static IPackageExport findExport( String className, IPackageExport[] exports )
+    {
+        for ( IPackageExport e : exports )
+        {
+            if ( className.startsWith( e.getPackageName() ) )
+            {
+                return e;
+            }
+        }
+        return null;
+    }
+
+
+    private static String toClassName( JarEntry entry )
+    {
+        String name = entry.getName();
+        if ( name.endsWith( CLASS_EXTENSION ) )
+        {
+            name = name.substring( 0, name.length() - CLASS_EXTENSION.length() );
+            name = name.replace( '/', '.' );
+            return name;
+        }
+        else
+        {
+            return null;
+        }
+    }
 }
diff --git a/sigil/eclipse/search/src/org/apache/felix/sigil/search/index/Index.java b/sigil/eclipse/search/src/org/apache/felix/sigil/search/index/Index.java
index a9501f7..b08885f 100644
--- a/sigil/eclipse/search/src/org/apache/felix/sigil/search/index/Index.java
+++ b/sigil/eclipse/search/src/org/apache/felix/sigil/search/index/Index.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.search.index;
 
+
 import java.lang.ref.SoftReference;
 import java.util.Collections;
 import java.util.HashMap;
@@ -44,190 +45,248 @@
 import org.eclipse.jdt.core.IPackageFragment;
 import org.osgi.framework.Version;
 
-public class Index {
-	private HashMap<String, ClassData> primary = new HashMap<String, ClassData>();
-	private HashMap<IBundleRepository, HashSet<String>> secondary = new HashMap<IBundleRepository, HashSet<String>>();
-	
-	private final ReadWriteLock lock = new ReentrantReadWriteLock();
-	
-	static class ClassData {
-		HashMap<IBundleRepository, Set<ISearchResult>> provided = new HashMap<IBundleRepository, Set<ISearchResult>>();
 
-		void add(IBundleRepository rep, ISearchResult export) {
-			Set<ISearchResult> exports = provided.get(rep);
-			
-			if ( exports == null ) {
-				exports = new HashSet<ISearchResult>();
-				provided.put( rep, exports );
-			}
-			
-			exports.add(export);
-		}
+public class Index
+{
+    private HashMap<String, ClassData> primary = new HashMap<String, ClassData>();
+    private HashMap<IBundleRepository, HashSet<String>> secondary = new HashMap<IBundleRepository, HashSet<String>>();
 
-		List<ISearchResult> getResults() {
-			LinkedList<ISearchResult> exports = new LinkedList<ISearchResult>();
-			for ( Set<ISearchResult> p : provided.values() ) {
-				exports.addAll(p);
-			}
-			return exports;
-		}
+    private final ReadWriteLock lock = new ReentrantReadWriteLock();
 
-		void remove(IBundleRepository rep) {
-			provided.remove(rep);
-		}
-		
-		boolean isEmpty() {
-			return provided.isEmpty();
-		}
-	}
-	
-	static class SearchResult implements ISearchResult {
-		private final String className;
-		private final String packageName;
-		private final IBundleRepository rep;
-		private final String bundleSymbolicName;
-		private final Version version;
-		private final boolean exported;
-		
-		private SoftReference<ISigilBundle> bundleReference;
-		private SoftReference<IPackageExport> exportReference;
-		
-		public SearchResult(String className, IBundleRepository rep, ISigilBundle bundle, String packageName, boolean exported) {
-			this.className = className;
-			this.rep = rep;
-			this.exported = exported;
-			this.bundleSymbolicName = bundle.getBundleInfo().getSymbolicName();
-			this.version = bundle.getVersion();
-			this.packageName = packageName;
-		}
+    static class ClassData
+    {
+        HashMap<IBundleRepository, Set<ISearchResult>> provided = new HashMap<IBundleRepository, Set<ISearchResult>>();
 
-		public String getClassName() {
-			return className;
-		}
-		
-		public String getPackageName() {
-			return packageName;
-		}
 
-		public IPackageExport getExport() {
-			IPackageExport ipe = null;
-			if ( exported ) {
-				ipe = exportReference == null ? null : exportReference.get();
-				if (ipe == null) {
-					ipe = getProvider().findExport(packageName);
-					exportReference = new SoftReference<IPackageExport>(ipe);
-				}
-			}
-			return ipe; 
-		}
+        void add( IBundleRepository rep, ISearchResult export )
+        {
+            Set<ISearchResult> exports = provided.get( rep );
 
-		public ISigilBundle getProvider() {
-			ISigilBundle b = bundleReference == null ? null : bundleReference.get();
-			if ( b == null ) {
-				IRequiredBundle rb = ModelElementFactory.getInstance().newModelElement(IRequiredBundle.class);
-				rb.setSymbolicName(bundleSymbolicName);
-				VersionRange versions = new VersionRange(false, version, version, false);
-				rb.setVersions(versions);
-				b = rep.findProvider(rb, 0);
-				bundleReference = new SoftReference<ISigilBundle>(b);
-			}
-			return b;
-		}
-		
-	}
+            if ( exports == null )
+            {
+                exports = new HashSet<ISearchResult>();
+                provided.put( rep, exports );
+            }
 
-	public void addEntry(JavaClass c, IBundleRepository rep, ISigilBundle bundle, boolean exported) {
-		addEntry(c.getClassName(), rep, bundle, c.getPackageName(), exported);
-	}
-	
-	public void addEntry(ICompilationUnit unit, IBundleRepository rep, ISigilBundle bundle, boolean exported) {
-		String name = unit.getElementName();
-		if ( name.endsWith( ".java" ) ) {
-			name = name.substring(0, name.length() - 5 );
-		}
-		IPackageFragment p = (IPackageFragment) unit.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
-		addEntry(p.getElementName() + "." + name, rep, bundle, p.getElementName(), exported);
-	}
+            exports.add( export );
+        }
 
-	private void addEntry(String className, IBundleRepository rep, ISigilBundle bundle, String packageName, boolean exported) {
-		List<String> keys = genKeys(className);
-		lock.writeLock().lock();
-		try {
-			for ( String key : keys ) {
-				ClassData data = primary.get(key);
-				
-				if ( data == null ) {
-					data = new ClassData();
-					primary.put(key, data);
-				}
-				
-				SearchResult result = new SearchResult(className, rep, bundle, packageName, exported);
-				data.add(rep, result);
-			}
-			
-			HashSet<String> all = secondary.get(rep);
-			if ( all == null ) {
-				all = new HashSet<String>();
-				secondary.put(rep, all);
-			}
-			all.addAll(keys);
-		}
-		finally {
-			lock.writeLock().unlock();
-		}
-	}
 
-	
-	public List<ISearchResult> findProviders(String className, IProgressMonitor monitor) {
-		lock.readLock().lock();
-		try {
-			ClassData data = primary.get(className);
-			return data == null ? Collections.<ISearchResult>emptyList() : data.getResults();
-		}
-		finally {
-			lock.readLock().unlock();
-		}
-	}	
-	
-	public List<ISearchResult> findProviders(Pattern className, IProgressMonitor monitor) {
-		lock.readLock().lock();
-		try {
-			ClassData data = primary.get(className);
-			return data == null ? Collections.<ISearchResult>emptyList() : data.getResults();
-		}
-		finally {
-			lock.readLock().unlock();
-		}
-	}
-	
-	public void delete(IBundleRepository rep) {
-		lock.writeLock().lock();
-		try {
-			Set<String> keys = secondary.remove(rep);
-			if ( keys != null ) {
-				for ( String key : keys ) {
-					ClassData data = primary.get(key);
-					data.remove(rep);
-					if ( data.isEmpty() ) {
-						primary.remove(key);
-					}
-				}
-			}
-		}
-		finally {
-			lock.writeLock().unlock();
-		}
-	}
-	
-	private List<String> genKeys(String className) {
-		LinkedList<String> keys = new LinkedList<String>();
-		keys.add(className);
-		int i = className.lastIndexOf('.');
-		if ( i != -1 ) {
-			String name = className.substring(i + 1);
-			keys.add( name );
-		}
-		return keys;
-	}
+        List<ISearchResult> getResults()
+        {
+            LinkedList<ISearchResult> exports = new LinkedList<ISearchResult>();
+            for ( Set<ISearchResult> p : provided.values() )
+            {
+                exports.addAll( p );
+            }
+            return exports;
+        }
+
+
+        void remove( IBundleRepository rep )
+        {
+            provided.remove( rep );
+        }
+
+
+        boolean isEmpty()
+        {
+            return provided.isEmpty();
+        }
+    }
+
+    static class SearchResult implements ISearchResult
+    {
+        private final String className;
+        private final String packageName;
+        private final IBundleRepository rep;
+        private final String bundleSymbolicName;
+        private final Version version;
+        private final boolean exported;
+
+        private SoftReference<ISigilBundle> bundleReference;
+        private SoftReference<IPackageExport> exportReference;
+
+
+        public SearchResult( String className, IBundleRepository rep, ISigilBundle bundle, String packageName,
+            boolean exported )
+        {
+            this.className = className;
+            this.rep = rep;
+            this.exported = exported;
+            this.bundleSymbolicName = bundle.getBundleInfo().getSymbolicName();
+            this.version = bundle.getVersion();
+            this.packageName = packageName;
+        }
+
+
+        public String getClassName()
+        {
+            return className;
+        }
+
+
+        public String getPackageName()
+        {
+            return packageName;
+        }
+
+
+        public IPackageExport getExport()
+        {
+            IPackageExport ipe = null;
+            if ( exported )
+            {
+                ipe = exportReference == null ? null : exportReference.get();
+                if ( ipe == null )
+                {
+                    ipe = getProvider().findExport( packageName );
+                    exportReference = new SoftReference<IPackageExport>( ipe );
+                }
+            }
+            return ipe;
+        }
+
+
+        public ISigilBundle getProvider()
+        {
+            ISigilBundle b = bundleReference == null ? null : bundleReference.get();
+            if ( b == null )
+            {
+                IRequiredBundle rb = ModelElementFactory.getInstance().newModelElement( IRequiredBundle.class );
+                rb.setSymbolicName( bundleSymbolicName );
+                VersionRange versions = new VersionRange( false, version, version, false );
+                rb.setVersions( versions );
+                b = rep.findProvider( rb, 0 );
+                bundleReference = new SoftReference<ISigilBundle>( b );
+            }
+            return b;
+        }
+
+    }
+
+
+    public void addEntry( JavaClass c, IBundleRepository rep, ISigilBundle bundle, boolean exported )
+    {
+        addEntry( c.getClassName(), rep, bundle, c.getPackageName(), exported );
+    }
+
+
+    public void addEntry( ICompilationUnit unit, IBundleRepository rep, ISigilBundle bundle, boolean exported )
+    {
+        String name = unit.getElementName();
+        if ( name.endsWith( ".java" ) )
+        {
+            name = name.substring( 0, name.length() - 5 );
+        }
+        IPackageFragment p = ( IPackageFragment ) unit.getAncestor( IJavaElement.PACKAGE_FRAGMENT );
+        addEntry( p.getElementName() + "." + name, rep, bundle, p.getElementName(), exported );
+    }
+
+
+    private void addEntry( String className, IBundleRepository rep, ISigilBundle bundle, String packageName,
+        boolean exported )
+    {
+        List<String> keys = genKeys( className );
+        lock.writeLock().lock();
+        try
+        {
+            for ( String key : keys )
+            {
+                ClassData data = primary.get( key );
+
+                if ( data == null )
+                {
+                    data = new ClassData();
+                    primary.put( key, data );
+                }
+
+                SearchResult result = new SearchResult( className, rep, bundle, packageName, exported );
+                data.add( rep, result );
+            }
+
+            HashSet<String> all = secondary.get( rep );
+            if ( all == null )
+            {
+                all = new HashSet<String>();
+                secondary.put( rep, all );
+            }
+            all.addAll( keys );
+        }
+        finally
+        {
+            lock.writeLock().unlock();
+        }
+    }
+
+
+    public List<ISearchResult> findProviders( String className, IProgressMonitor monitor )
+    {
+        lock.readLock().lock();
+        try
+        {
+            ClassData data = primary.get( className );
+            return data == null ? Collections.<ISearchResult> emptyList() : data.getResults();
+        }
+        finally
+        {
+            lock.readLock().unlock();
+        }
+    }
+
+
+    public List<ISearchResult> findProviders( Pattern className, IProgressMonitor monitor )
+    {
+        lock.readLock().lock();
+        try
+        {
+            ClassData data = primary.get( className );
+            return data == null ? Collections.<ISearchResult> emptyList() : data.getResults();
+        }
+        finally
+        {
+            lock.readLock().unlock();
+        }
+    }
+
+
+    public void delete( IBundleRepository rep )
+    {
+        lock.writeLock().lock();
+        try
+        {
+            Set<String> keys = secondary.remove( rep );
+            if ( keys != null )
+            {
+                for ( String key : keys )
+                {
+                    ClassData data = primary.get( key );
+                    data.remove( rep );
+                    if ( data.isEmpty() )
+                    {
+                        primary.remove( key );
+                    }
+                }
+            }
+        }
+        finally
+        {
+            lock.writeLock().unlock();
+        }
+    }
+
+
+    private List<String> genKeys( String className )
+    {
+        LinkedList<String> keys = new LinkedList<String>();
+        keys.add( className );
+        int i = className.lastIndexOf( '.' );
+        if ( i != -1 )
+        {
+            String name = className.substring( i + 1 );
+            keys.add( name );
+        }
+        return keys;
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/DisplayAction.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/DisplayAction.java
index 58c7f80..4bb49ef 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/DisplayAction.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/DisplayAction.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.actions;
 
+
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.resource.ImageDescriptor;
@@ -26,43 +27,61 @@
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.actions.WorkspaceModifyOperation;
 
-public abstract class DisplayAction extends Action {
 
-	public DisplayAction() {
-		super();
-	}
+public abstract class DisplayAction extends Action
+{
 
-	public DisplayAction(String text) {
-		super(text);
-	}
+    public DisplayAction()
+    {
+        super();
+    }
 
-	public DisplayAction(String text, ImageDescriptor image) {
-		super(text, image);
-	}
 
-	public DisplayAction(String text, int style) {
-		super(text, style);
-	}
+    public DisplayAction( String text )
+    {
+        super( text );
+    }
 
-	protected Display findDisplay() {
-		Display d = Display.getCurrent();
-		
-		if ( d == null ) {
-			d = Display.getDefault();
-		}
-		
-		return d;
-	}
 
-	protected void runInUI(final Shell shell, final WorkspaceModifyOperation op) {
-	}
+    public DisplayAction( String text, ImageDescriptor image )
+    {
+        super( text, image );
+    }
 
-	protected void info(final Shell shell, final String msg) {
-		shell.getDisplay().asyncExec( new Runnable() {
-			public void run() {
-				MessageDialog.openInformation(shell, "Information", msg );
-			}
-		} );
-	}
+
+    public DisplayAction( String text, int style )
+    {
+        super( text, style );
+    }
+
+
+    protected Display findDisplay()
+    {
+        Display d = Display.getCurrent();
+
+        if ( d == null )
+        {
+            d = Display.getDefault();
+        }
+
+        return d;
+    }
+
+
+    protected void runInUI( final Shell shell, final WorkspaceModifyOperation op )
+    {
+    }
+
+
+    protected void info( final Shell shell, final String msg )
+    {
+        shell.getDisplay().asyncExec( new Runnable()
+        {
+            public void run()
+            {
+                MessageDialog.openInformation( shell, "Information", msg );
+            }
+        } );
+    }
 
 }
\ No newline at end of file
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/PruneProjectDependenciesAction.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/PruneProjectDependenciesAction.java
index 6481880..7d306e7 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/PruneProjectDependenciesAction.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/PruneProjectDependenciesAction.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.actions;
 
+
 import java.util.Collection;
 
 import org.apache.felix.sigil.eclipse.SigilCore;
@@ -38,59 +39,77 @@
 import org.eclipse.ui.actions.WorkspaceModifyOperation;
 import org.eclipse.ui.progress.IProgressService;
 
-public class PruneProjectDependenciesAction extends DisplayAction {
-	
-	private ISigilProjectModel project;
-	
-	public PruneProjectDependenciesAction(ISigilProjectModel project) {
-		this.project = project;
-	}
 
-	@Override
-	public void run() {
- 		final Shell shell = findDisplay().getActiveShell();
- 		
-		Job job = new Job("Resolving imports") {
+public class PruneProjectDependenciesAction extends DisplayAction
+{
 
-			@Override
-			protected IStatus run(IProgressMonitor monitor) {
-				Collection<IModelElement> unused = JavaHelper.findUnusedReferences(project, monitor);
-				
-				if ( unused.isEmpty() ) {
-					info( shell, "No unused references found" );
-				}
-				else {
-					final ResourceReviewDialog<IModelElement> dialog = new ResourceReviewDialog<IModelElement>(shell, "Review Unused Imports", unused);
-					
-					shell.getDisplay().asyncExec( new Runnable() {
-						public void run() {
-							if ( dialog.open() == Window.OK ) {
-								WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
-									@Override
-									protected void execute(IProgressMonitor monitor) throws CoreException {
-										for ( IModelElement e : dialog.getResources() ) {
-											if ( !project.getBundle().getBundleInfo().removeChild(e) ) {
-												SigilCore.error( "Failed to remove " + e );
-											}
-										}
-										
-										project.save(monitor);
-									}			
-								};
-								
-								SigilUI.runWorkspaceOperation(op, shell);
-							}
-						}
-					});
-				}
-				
-				return Status.OK_STATUS;
-			}
-		};
-		
-		job.schedule();
-		
-		IProgressService p = PlatformUI.getWorkbench().getProgressService();
-		p.showInDialog(shell, job);				
-	}	
+    private ISigilProjectModel project;
+
+
+    public PruneProjectDependenciesAction( ISigilProjectModel project )
+    {
+        this.project = project;
+    }
+
+
+    @Override
+    public void run()
+    {
+        final Shell shell = findDisplay().getActiveShell();
+
+        Job job = new Job( "Resolving imports" )
+        {
+
+            @Override
+            protected IStatus run( IProgressMonitor monitor )
+            {
+                Collection<IModelElement> unused = JavaHelper.findUnusedReferences( project, monitor );
+
+                if ( unused.isEmpty() )
+                {
+                    info( shell, "No unused references found" );
+                }
+                else
+                {
+                    final ResourceReviewDialog<IModelElement> dialog = new ResourceReviewDialog<IModelElement>( shell,
+                        "Review Unused Imports", unused );
+
+                    shell.getDisplay().asyncExec( new Runnable()
+                    {
+                        public void run()
+                        {
+                            if ( dialog.open() == Window.OK )
+                            {
+                                WorkspaceModifyOperation op = new WorkspaceModifyOperation()
+                                {
+                                    @Override
+                                    protected void execute( IProgressMonitor monitor ) throws CoreException
+                                    {
+                                        for ( IModelElement e : dialog.getResources() )
+                                        {
+                                            if ( !project.getBundle().getBundleInfo().removeChild( e ) )
+                                            {
+                                                SigilCore.error( "Failed to remove " + e );
+                                            }
+                                        }
+
+                                        project.save( monitor );
+                                    }
+                                };
+
+                                SigilUI.runWorkspaceOperation( op, shell );
+                            }
+                        }
+                    } );
+                }
+
+                return Status.OK_STATUS;
+            }
+        };
+
+        job.schedule();
+
+        IProgressService p = PlatformUI.getWorkbench().getProgressService();
+        p.showInDialog( shell, job );
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/RefreshRepositoryAction.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/RefreshRepositoryAction.java
index 77d0fd4..b19249d 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/RefreshRepositoryAction.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/RefreshRepositoryAction.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.actions;
 
+
 import java.lang.reflect.InvocationTargetException;
 import java.util.List;
 
@@ -32,43 +33,55 @@
 import org.eclipse.core.runtime.SubMonitor;
 import org.eclipse.ui.actions.WorkspaceModifyOperation;
 
-public class RefreshRepositoryAction extends DisplayAction {
-	private final IRepositoryModel[] model;
 
-	public RefreshRepositoryAction(IRepositoryModel... model) {
-		super( "Refresh repository");
-		this.model = model;
-	}
-	
-	@Override
-	public void run() {
-		WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
+public class RefreshRepositoryAction extends DisplayAction
+{
+    private final IRepositoryModel[] model;
 
-			@Override
-			protected void execute(IProgressMonitor monitor)
-					throws CoreException, InvocationTargetException,
-					InterruptedException {
-				boolean changed = false;
-				
-				for ( IBundleRepository b : SigilCore.getGlobalRepositoryManager().getRepositories() ) {
-					for ( IRepositoryModel m : model ) {
-						if ( b.getId().equals( m.getId() ) ) {
-							b.refresh();
-							changed = true;
-						}
-					}
-				}
-				
-				if ( changed ) {
-					List<ISigilProjectModel> projects = SigilCore.getRoot().getProjects();
-					SubMonitor sub = SubMonitor.convert(monitor, projects.size() * 10);
-					for ( ISigilProjectModel p : projects ) {
-						p.resetClasspath(sub.newChild(10));
-					}
-				}
-			}
-		};
-		
-		SigilUI.runWorkspaceOperation(op, null);
-	}
+
+    public RefreshRepositoryAction( IRepositoryModel... model )
+    {
+        super( "Refresh repository" );
+        this.model = model;
+    }
+
+
+    @Override
+    public void run()
+    {
+        WorkspaceModifyOperation op = new WorkspaceModifyOperation()
+        {
+
+            @Override
+            protected void execute( IProgressMonitor monitor ) throws CoreException, InvocationTargetException,
+                InterruptedException
+            {
+                boolean changed = false;
+
+                for ( IBundleRepository b : SigilCore.getGlobalRepositoryManager().getRepositories() )
+                {
+                    for ( IRepositoryModel m : model )
+                    {
+                        if ( b.getId().equals( m.getId() ) )
+                        {
+                            b.refresh();
+                            changed = true;
+                        }
+                    }
+                }
+
+                if ( changed )
+                {
+                    List<ISigilProjectModel> projects = SigilCore.getRoot().getProjects();
+                    SubMonitor sub = SubMonitor.convert( monitor, projects.size() * 10 );
+                    for ( ISigilProjectModel p : projects )
+                    {
+                        p.resetClasspath( sub.newChild( 10 ) );
+                    }
+                }
+            }
+        };
+
+        SigilUI.runWorkspaceOperation( op, null );
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/ResolveProjectDependenciesAction.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/ResolveProjectDependenciesAction.java
index 719df19..cf98e27 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/ResolveProjectDependenciesAction.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/actions/ResolveProjectDependenciesAction.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.actions;
 
+
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
@@ -39,73 +40,93 @@
 import org.eclipse.ui.actions.WorkspaceModifyOperation;
 import org.eclipse.ui.progress.IProgressService;
 
-public class ResolveProjectDependenciesAction extends DisplayAction {
 
-	private ISigilProjectModel project;
-	private boolean review;
+public class ResolveProjectDependenciesAction extends DisplayAction
+{
 
-	public ResolveProjectDependenciesAction(ISigilProjectModel project, boolean review) {
-		this.project = project;
-		this.review = review;
-	}
-	
-	public void run() {
-		final Shell shell = findDisplay().getActiveShell();
-		
-		Job job = new Job("Resolving dependencies" ) {
-			@Override
-			protected IStatus run(IProgressMonitor monitor) {
-				monitor.beginTask("", IProgressMonitor.UNKNOWN);
-				
-				List<IPackageImport> imports = JavaHelper.findRequiredImports(project, monitor);
-				
-				if ( imports.isEmpty() ) {
-					info( shell, "No new dependencies found" );
-				}
-				else {
-					Collections.sort(imports, new Comparator<IPackageImport>() {
-						public int compare(IPackageImport o1, IPackageImport o2) {
-							int i = o1.getPackageName().compareTo(o2.getPackageName());
+    private ISigilProjectModel project;
+    private boolean review;
 
-							// shouldn't get more than one import for same package
-							// but may as well sort if do...
-							if ( i == 0 ) {
-								i = o1.getVersions().getFloor().compareTo(o2.getVersions().getFloor() );
-							}
-							
-							return i;
-						}
-					});
-					
-					final ResourceReviewDialog<IPackageImport> dialog = new ResourceReviewDialog<IPackageImport>(shell, "Review New Dependencies", imports);					
-					shell.getDisplay().asyncExec( new Runnable() {
-						public void run() {
-							if ( !review || dialog.open() == Window.OK ) {
-								WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
-									@Override
-									protected void execute(IProgressMonitor monitor) throws CoreException {
-										for ( IPackageImport pi : dialog.getResources() ) {
-											project.getBundle().getBundleInfo().addImport(pi);
-										}
-										
-										project.save(monitor);
-									}			
-								};
-								
-								SigilUI.runWorkspaceOperation(op, shell);
-							}
-						}
-					} );
-				}
-				
-				return Status.OK_STATUS;
-			}
-		};
-		
-		job.schedule();
-		
-		IProgressService p = PlatformUI.getWorkbench().getProgressService();
-		p.showInDialog(shell, job);
-	}
+
+    public ResolveProjectDependenciesAction( ISigilProjectModel project, boolean review )
+    {
+        this.project = project;
+        this.review = review;
+    }
+
+
+    public void run()
+    {
+        final Shell shell = findDisplay().getActiveShell();
+
+        Job job = new Job( "Resolving dependencies" )
+        {
+            @Override
+            protected IStatus run( IProgressMonitor monitor )
+            {
+                monitor.beginTask( "", IProgressMonitor.UNKNOWN );
+
+                List<IPackageImport> imports = JavaHelper.findRequiredImports( project, monitor );
+
+                if ( imports.isEmpty() )
+                {
+                    info( shell, "No new dependencies found" );
+                }
+                else
+                {
+                    Collections.sort( imports, new Comparator<IPackageImport>()
+                    {
+                        public int compare( IPackageImport o1, IPackageImport o2 )
+                        {
+                            int i = o1.getPackageName().compareTo( o2.getPackageName() );
+
+                            // shouldn't get more than one import for same package
+                            // but may as well sort if do...
+                            if ( i == 0 )
+                            {
+                                i = o1.getVersions().getFloor().compareTo( o2.getVersions().getFloor() );
+                            }
+
+                            return i;
+                        }
+                    } );
+
+                    final ResourceReviewDialog<IPackageImport> dialog = new ResourceReviewDialog<IPackageImport>(
+                        shell, "Review New Dependencies", imports );
+                    shell.getDisplay().asyncExec( new Runnable()
+                    {
+                        public void run()
+                        {
+                            if ( !review || dialog.open() == Window.OK )
+                            {
+                                WorkspaceModifyOperation op = new WorkspaceModifyOperation()
+                                {
+                                    @Override
+                                    protected void execute( IProgressMonitor monitor ) throws CoreException
+                                    {
+                                        for ( IPackageImport pi : dialog.getResources() )
+                                        {
+                                            project.getBundle().getBundleInfo().addImport( pi );
+                                        }
+
+                                        project.save( monitor );
+                                    }
+                                };
+
+                                SigilUI.runWorkspaceOperation( op, shell );
+                            }
+                        }
+                    } );
+                }
+
+                return Status.OK_STATUS;
+            }
+        };
+
+        job.schedule();
+
+        IProgressService p = PlatformUI.getWorkbench().getProgressService();
+        p.showInDialog( shell, job );
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/classpath/SigilClassPathContainer.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/classpath/SigilClassPathContainer.java
index 4646ac0..5df4373 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/classpath/SigilClassPathContainer.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/classpath/SigilClassPathContainer.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.classpath;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.job.ThreadProgressMonitor;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
@@ -29,67 +30,88 @@
 import org.eclipse.jdt.core.IClasspathContainer;
 import org.eclipse.jdt.core.IClasspathEntry;
 
+
 /**
  * @author dave
  *
  */
-public class SigilClassPathContainer implements IClasspathContainer {
+public class SigilClassPathContainer implements IClasspathContainer
+{
 
     private IClasspathEntry[] entries;
     private ISigilProjectModel sigil;
 
-    public SigilClassPathContainer(ISigilProjectModel sigil) {
-    	this.sigil = sigil;
-	}
 
-	/* (non-Javadoc)
+    public SigilClassPathContainer( ISigilProjectModel sigil )
+    {
+        this.sigil = sigil;
+    }
+
+
+    /* (non-Javadoc)
      * @see org.eclipse.jdt.core.IClasspathContainer#getClasspathEntries()
      */
-    public IClasspathEntry[] getClasspathEntries() {
-        if ( entries == null ) {
-        	buildClassPathEntries();
+    public IClasspathEntry[] getClasspathEntries()
+    {
+        if ( entries == null )
+        {
+            buildClassPathEntries();
         }
-        
+
         return entries;
     }
 
+
     /* (non-Javadoc)
      * @see org.eclipse.jdt.core.IClasspathContainer#getDescription()
      */
-    public String getDescription() {
+    public String getDescription()
+    {
         return "Bundle Context Classpath";
     }
 
+
     /* (non-Javadoc)
      * @see org.eclipse.jdt.core.IClasspathContainer#getKind()
      */
-    public int getKind() {
+    public int getKind()
+    {
         return K_SYSTEM;
     }
 
+
     /* (non-Javadoc)
      * @see org.eclipse.jdt.core.IClasspathContainer#getPath()
      */
-    public IPath getPath() {
+    public IPath getPath()
+    {
         return new Path( SigilCore.CLASSPATH_CONTAINER_PATH );
     }
 
+
     /**
      * @return
      * @throws CoreException 
      * @throws CoreException 
      */
-    private void buildClassPathEntries() {
-		try {
-			IProgressMonitor monitor = ThreadProgressMonitor.getProgressMonitor();
-			entries = sigil.findExternalClasspath(monitor).toArray( new IClasspathEntry[0] );
-		} catch (CoreException e) {
-    		SigilCore.error( "Failed to build classpath entries", e);
-		}
-		finally {
-			if ( entries == null ) {
-	    		entries = new IClasspathEntry[] {};
-			}
-		}
+    private void buildClassPathEntries()
+    {
+        try
+        {
+            IProgressMonitor monitor = ThreadProgressMonitor.getProgressMonitor();
+            entries = sigil.findExternalClasspath( monitor ).toArray( new IClasspathEntry[0] );
+        }
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Failed to build classpath entries", e );
+        }
+        finally
+        {
+            if ( entries == null )
+            {
+                entries = new IClasspathEntry[]
+                    {};
+            }
+        }
     }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/classpath/SigilClasspathContainerInitializer.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/classpath/SigilClasspathContainerInitializer.java
index 3acb68b..8eba41e 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/classpath/SigilClasspathContainerInitializer.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/classpath/SigilClasspathContainerInitializer.java
@@ -17,66 +17,79 @@
  * under the License.
  */
 
-package org.apache.felix.sigil.ui.eclipse.classpath;

-

+package org.apache.felix.sigil.ui.eclipse.classpath;
+
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.job.*;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
-import org.eclipse.core.runtime.CoreException;

-import org.eclipse.core.runtime.IPath;

-import org.eclipse.core.runtime.IProgressMonitor;

-import org.eclipse.core.runtime.jobs.Job;

-import org.eclipse.jdt.core.ClasspathContainerInitializer;

-import org.eclipse.jdt.core.IClasspathContainer;

-import org.eclipse.jdt.core.IJavaProject;

-import org.eclipse.jdt.core.JavaCore;

-

-public class SigilClasspathContainerInitializer extends ClasspathContainerInitializer {

-

-	public SigilClasspathContainerInitializer() {

-		// TODO Auto-generated constructor stub

-	}

-

-	@Override
-	public boolean canUpdateClasspathContainer(IPath containerPath,
-			IJavaProject project) {
-		return true;
-	}
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jdt.core.ClasspathContainerInitializer;
+import org.eclipse.jdt.core.IClasspathContainer;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
 
-	@Override
-	public void requestClasspathContainerUpdate(IPath containerPath, IJavaProject project, IClasspathContainer containerSuggestion)
-			throws CoreException {
-		ISigilProjectModel sigil = SigilCore.create(project.getProject());
-		
-        IClasspathContainer sigilContainer = new SigilClassPathContainer(sigil);
-		
-		IJavaProject[] affectedProjects = new IJavaProject[] { project };
-        
-        IClasspathContainer[] respectiveContainers = new IClasspathContainer[] { sigilContainer };
-        
+
+public class SigilClasspathContainerInitializer extends ClasspathContainerInitializer
+{
+
+    public SigilClasspathContainerInitializer()
+    {
+        // TODO Auto-generated constructor stub
+    }
+
+
+    @Override
+    public boolean canUpdateClasspathContainer( IPath containerPath, IJavaProject project )
+    {
+        return true;
+    }
+
+
+    @Override
+    public void requestClasspathContainerUpdate( IPath containerPath, IJavaProject project,
+        IClasspathContainer containerSuggestion ) throws CoreException
+    {
+        ISigilProjectModel sigil = SigilCore.create( project.getProject() );
+
+        IClasspathContainer sigilContainer = new SigilClassPathContainer( sigil );
+
+        IJavaProject[] affectedProjects = new IJavaProject[]
+            { project };
+
+        IClasspathContainer[] respectiveContainers = new IClasspathContainer[]
+            { sigilContainer };
+
         IProgressMonitor monitor = ThreadProgressMonitor.getProgressMonitor();
-        
-        if ( monitor == null ) { 
-        	monitor = Job.getJobManager().createProgressGroup();
+
+        if ( monitor == null )
+        {
+            monitor = Job.getJobManager().createProgressGroup();
         }
 
-        JavaCore.setClasspathContainer(containerPath, affectedProjects, respectiveContainers , monitor);
-	}
+        JavaCore.setClasspathContainer( containerPath, affectedProjects, respectiveContainers, monitor );
+    }
 
-	@Override

-	public void initialize(IPath containerPath, IJavaProject project)

-			throws CoreException {
-		ISigilProjectModel sigil = SigilCore.create(project.getProject());
-		

-        IClasspathContainer sigilContainer = new SigilClassPathContainer(sigil);

-		

-		IJavaProject[] affectedProjects = new IJavaProject[] { project };

-        

-        IClasspathContainer[] respectiveContainers = new IClasspathContainer[] { sigilContainer };

-        

-        IProgressMonitor monitor = Job.getJobManager().createProgressGroup();

-

-        JavaCore.setClasspathContainer(containerPath, affectedProjects, respectiveContainers , monitor);

-	}

-

-}

+
+    @Override
+    public void initialize( IPath containerPath, IJavaProject project ) throws CoreException
+    {
+        ISigilProjectModel sigil = SigilCore.create( project.getProject() );
+
+        IClasspathContainer sigilContainer = new SigilClassPathContainer( sigil );
+
+        IJavaProject[] affectedProjects = new IJavaProject[]
+            { project };
+
+        IClasspathContainer[] respectiveContainers = new IClasspathContainer[]
+            { sigilContainer };
+
+        IProgressMonitor monitor = Job.getJobManager().createProgressGroup();
+
+        JavaCore.setClasspathContainer( containerPath, affectedProjects, respectiveContainers, monitor );
+    }
+
+}
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/classpath/SigilLibraryPage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/classpath/SigilLibraryPage.java
index 5453e77..5a337bb 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/classpath/SigilLibraryPage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/classpath/SigilLibraryPage.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.classpath;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.jdt.core.IClasspathEntry;
@@ -29,38 +30,52 @@
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Label;
 
-public class SigilLibraryPage extends WizardPage implements IClasspathContainerPage {
+
+public class SigilLibraryPage extends WizardPage implements IClasspathContainerPage
+{
 
     private IClasspathEntry classpathEntry;
 
-    public SigilLibraryPage() {
+
+    public SigilLibraryPage()
+    {
         super( "Sigil" );
     }
-    
-    public void createControl(Composite parent) {
-        setTitle("Sigil Library");
 
-        Label label = new Label(parent, SWT.NONE);
-        label.setText("Press Finish to add the Sigil Library");
-        label.setFont(parent.getFont());
 
-        setControl(label);
+    public void createControl( Composite parent )
+    {
+        setTitle( "Sigil Library" );
+
+        Label label = new Label( parent, SWT.NONE );
+        label.setText( "Press Finish to add the Sigil Library" );
+        label.setFont( parent.getFont() );
+
+        setControl( label );
     }
 
-    public boolean finish() {
-        classpathEntry = JavaCore.newContainerEntry(new Path(SigilCore.CLASSPATH_CONTAINER_PATH));
+
+    public boolean finish()
+    {
+        classpathEntry = JavaCore.newContainerEntry( new Path( SigilCore.CLASSPATH_CONTAINER_PATH ) );
         return true;
     }
 
-    public boolean isPageComplete() {
+
+    public boolean isPageComplete()
+    {
         return true;
     }
 
-    public IClasspathEntry getSelection() {
+
+    public IClasspathEntry getSelection()
+    {
         return classpathEntry;
     }
 
-    public void setSelection(IClasspathEntry containerEntry) {
+
+    public void setSelection( IClasspathEntry containerEntry )
+    {
         this.classpathEntry = containerEntry;
     }
 
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/AbstractResourceCommandHandler.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/AbstractResourceCommandHandler.java
index a7dae76..8b96edd 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/AbstractResourceCommandHandler.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/AbstractResourceCommandHandler.java
@@ -19,10 +19,13 @@
 
 package org.apache.felix.sigil.ui.eclipse.handlers;
 
+
 import org.eclipse.core.commands.AbstractHandler;
 
-public abstract class AbstractResourceCommandHandler extends AbstractHandler {
 
-	protected abstract IResourceCommandHandler getResourceCommandHandler();
+public abstract class AbstractResourceCommandHandler extends AbstractHandler
+{
+
+    protected abstract IResourceCommandHandler getResourceCommandHandler();
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/EditorResourceCommandHandler.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/EditorResourceCommandHandler.java
index b637cf1..543b066 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/EditorResourceCommandHandler.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/EditorResourceCommandHandler.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.handlers;
 
+
 import java.lang.reflect.InvocationTargetException;
 
 import org.eclipse.core.commands.ExecutionEvent;
@@ -35,45 +36,63 @@
 import org.eclipse.ui.IFileEditorInput;
 import org.eclipse.ui.handlers.HandlerUtil;
 
-public abstract class EditorResourceCommandHandler extends AbstractResourceCommandHandler {
-	
-	public Object execute(ExecutionEvent event) throws ExecutionException {
-		final Shell shell = HandlerUtil.getActiveShell(event);
-		final IEditorPart editorPart = HandlerUtil.getActiveEditor(event);
-		if ( editorPart != null ) {
-			IEditorInput editorInput = editorPart.getEditorInput();
-			
-			if(!(editorInput instanceof IFileEditorInput)) {
-				throw new ExecutionException("Editor input must be a file");
-			}
-			IFileEditorInput fileInput = (IFileEditorInput) editorInput;
-			
-			try {
-				// Save the editor content (if dirty)
-				IRunnableWithProgress saveOperation = new IRunnableWithProgress() {
-					public void run(IProgressMonitor monitor) throws InvocationTargetException,
-					InterruptedException {
-						if(editorPart.isDirty()) {
-							if(MessageDialog.openQuestion(shell, "Save File", "The file contents must be saved before the command can be executed. Do you wish to save now?")) {
-								editorPart.doSave(monitor);
-							} else {
-								throw new InterruptedException();
-							}
-						}
-					}
-				};
-				new ProgressMonitorDialog(shell).run(false, true, saveOperation);
-	
-				// Execute on the file
-				IFile file = fileInput.getFile();
-				getResourceCommandHandler().execute(new IResource[] { file }, event);
-			} catch (InvocationTargetException e) {
-				throw new ExecutionException("Error saving file", e.getTargetException());
-			} catch (InterruptedException e) {
-				// Exit the command silently
-			}
-		}			
-		return null;
-	}
+
+public abstract class EditorResourceCommandHandler extends AbstractResourceCommandHandler
+{
+
+    public Object execute( ExecutionEvent event ) throws ExecutionException
+    {
+        final Shell shell = HandlerUtil.getActiveShell( event );
+        final IEditorPart editorPart = HandlerUtil.getActiveEditor( event );
+        if ( editorPart != null )
+        {
+            IEditorInput editorInput = editorPart.getEditorInput();
+
+            if ( !( editorInput instanceof IFileEditorInput ) )
+            {
+                throw new ExecutionException( "Editor input must be a file" );
+            }
+            IFileEditorInput fileInput = ( IFileEditorInput ) editorInput;
+
+            try
+            {
+                // Save the editor content (if dirty)
+                IRunnableWithProgress saveOperation = new IRunnableWithProgress()
+                {
+                    public void run( IProgressMonitor monitor ) throws InvocationTargetException, InterruptedException
+                    {
+                        if ( editorPart.isDirty() )
+                        {
+                            if ( MessageDialog
+                                .openQuestion( shell, "Save File",
+                                    "The file contents must be saved before the command can be executed. Do you wish to save now?" ) )
+                            {
+                                editorPart.doSave( monitor );
+                            }
+                            else
+                            {
+                                throw new InterruptedException();
+                            }
+                        }
+                    }
+                };
+                new ProgressMonitorDialog( shell ).run( false, true, saveOperation );
+
+                // Execute on the file
+                IFile file = fileInput.getFile();
+                getResourceCommandHandler().execute( new IResource[]
+                    { file }, event );
+            }
+            catch ( InvocationTargetException e )
+            {
+                throw new ExecutionException( "Error saving file", e.getTargetException() );
+            }
+            catch ( InterruptedException e )
+            {
+                // Exit the command silently
+            }
+        }
+        return null;
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/IResourceCommandHandler.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/IResourceCommandHandler.java
index 04cc045..87dd09e 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/IResourceCommandHandler.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/IResourceCommandHandler.java
@@ -19,12 +19,15 @@
 
 package org.apache.felix.sigil.ui.eclipse.handlers;
 
+
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.resources.IResource;
 
-public interface IResourceCommandHandler {
-	
-	Object execute(IResource[] resources, ExecutionEvent event) throws ExecutionException;
-	
+
+public interface IResourceCommandHandler
+{
+
+    Object execute( IResource[] resources, ExecutionEvent event ) throws ExecutionException;
+
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/SelectionResourceCommandHandler.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/SelectionResourceCommandHandler.java
index e40da15..7d064d3 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/SelectionResourceCommandHandler.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/SelectionResourceCommandHandler.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.handlers;
 
+
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.resources.IResource;
@@ -26,16 +27,19 @@
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.ui.handlers.HandlerUtil;
 
-public abstract class SelectionResourceCommandHandler extends AbstractResourceCommandHandler {
-	
-	public final Object execute(ExecutionEvent event) throws ExecutionException {
-		ISelection selection = HandlerUtil.getCurrentSelection(event);
-		
-		Object[] objectArray = ((IStructuredSelection) selection).toArray();
-		IResource[] resourceArray = new IResource[objectArray.length];
-		System.arraycopy(objectArray, 0, resourceArray, 0, objectArray.length);
-		
-		return getResourceCommandHandler().execute(resourceArray, event);
-	}
+
+public abstract class SelectionResourceCommandHandler extends AbstractResourceCommandHandler
+{
+
+    public final Object execute( ExecutionEvent event ) throws ExecutionException
+    {
+        ISelection selection = HandlerUtil.getCurrentSelection( event );
+
+        Object[] objectArray = ( ( IStructuredSelection ) selection ).toArray();
+        IResource[] resourceArray = new IResource[objectArray.length];
+        System.arraycopy( objectArray, 0, resourceArray, 0, objectArray.length );
+
+        return getResourceCommandHandler().execute( resourceArray, event );
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/ConvertProjectCommandHandler.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/ConvertProjectCommandHandler.java
index 0aaed76..2c1cfb2 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/ConvertProjectCommandHandler.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/ConvertProjectCommandHandler.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.handlers.project;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.apache.felix.sigil.ui.eclipse.handlers.IResourceCommandHandler;
@@ -34,36 +35,43 @@
 import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.ui.actions.WorkspaceModifyOperation;
 
-public class ConvertProjectCommandHandler implements IResourceCommandHandler {
 
-	public Object execute(IResource[] resources, ExecutionEvent event)
-			throws ExecutionException {
-		for ( IResource r : resources ) {
-			final IProject project = (IProject) r;
-			if ( project != null ) {
-				WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
-					@Override
-					protected void execute(IProgressMonitor monitor)
-							throws CoreException {
-						SigilCore.makeSigilProject(project, monitor);
-						IJavaProject java = JavaCore.create(project);
-						ISigilProjectModel sigil = SigilCore.create(project);
-						IClasspathEntry[] entries = java.getRawClasspath();
-						for (int i = 0; i < entries.length; i++) {
-							IClasspathEntry entry = entries[i];
-							if(entry.getEntryKind()==IClasspathEntry.CPE_SOURCE) {
-								String encodedClasspath = sigil.getJavaModel().encodeClasspathEntry( entry );
-								sigil.getBundle().addClasspathEntry(encodedClasspath);
-							}
-						}
-						sigil.save(monitor);
-					}				
-				};
-				SigilUI.runWorkspaceOperation(op, null);
-			}
-		}
-		
-		return null;
-	}
+public class ConvertProjectCommandHandler implements IResourceCommandHandler
+{
+
+    public Object execute( IResource[] resources, ExecutionEvent event ) throws ExecutionException
+    {
+        for ( IResource r : resources )
+        {
+            final IProject project = ( IProject ) r;
+            if ( project != null )
+            {
+                WorkspaceModifyOperation op = new WorkspaceModifyOperation()
+                {
+                    @Override
+                    protected void execute( IProgressMonitor monitor ) throws CoreException
+                    {
+                        SigilCore.makeSigilProject( project, monitor );
+                        IJavaProject java = JavaCore.create( project );
+                        ISigilProjectModel sigil = SigilCore.create( project );
+                        IClasspathEntry[] entries = java.getRawClasspath();
+                        for ( int i = 0; i < entries.length; i++ )
+                        {
+                            IClasspathEntry entry = entries[i];
+                            if ( entry.getEntryKind() == IClasspathEntry.CPE_SOURCE )
+                            {
+                                String encodedClasspath = sigil.getJavaModel().encodeClasspathEntry( entry );
+                                sigil.getBundle().addClasspathEntry( encodedClasspath );
+                            }
+                        }
+                        sigil.save( monitor );
+                    }
+                };
+                SigilUI.runWorkspaceOperation( op, null );
+            }
+        }
+
+        return null;
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/ConvertProjectHandler.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/ConvertProjectHandler.java
index 0656905..e632480 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/ConvertProjectHandler.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/ConvertProjectHandler.java
@@ -19,14 +19,18 @@
 
 package org.apache.felix.sigil.ui.eclipse.handlers.project;
 
+
 import org.apache.felix.sigil.ui.eclipse.handlers.IResourceCommandHandler;
 import org.apache.felix.sigil.ui.eclipse.handlers.SelectionResourceCommandHandler;
 
-public class ConvertProjectHandler extends SelectionResourceCommandHandler {
 
-	@Override
-	protected IResourceCommandHandler getResourceCommandHandler() {
-		return new ConvertProjectCommandHandler();
-	}
+public class ConvertProjectHandler extends SelectionResourceCommandHandler
+{
+
+    @Override
+    protected IResourceCommandHandler getResourceCommandHandler()
+    {
+        return new ConvertProjectCommandHandler();
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/RefreshSigilClasspathCommandHandler.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/RefreshSigilClasspathCommandHandler.java
index 140d1ee..9d79875 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/RefreshSigilClasspathCommandHandler.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/RefreshSigilClasspathCommandHandler.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.handlers.project;
 
+
 import java.lang.reflect.InvocationTargetException;
 
 import org.apache.felix.sigil.eclipse.SigilCore;
@@ -33,31 +34,37 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.ui.actions.WorkspaceModifyOperation;
 
-public class RefreshSigilClasspathCommandHandler implements
-		IResourceCommandHandler {
 
-	public Object execute(IResource[] resources, ExecutionEvent event)
-			throws ExecutionException {
-		try {
-			for ( IResource res : resources ) {
-				IProject p = (IProject) res;
-				final ISigilProjectModel model = SigilCore.create(p);
-				
-				WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
-					@Override
-					protected void execute(IProgressMonitor monitor)
-							throws CoreException, InvocationTargetException,
-							InterruptedException {
-						model.resetClasspath(monitor);
-					}
-				};
-				
-				SigilUI.runWorkspaceOperation(op, null);
-			}
-		} catch (CoreException e) {
-			SigilCore.error( "Failed to create sigil project for refresh action", e );
-		}
-		return null;
-	}
+public class RefreshSigilClasspathCommandHandler implements IResourceCommandHandler
+{
+
+    public Object execute( IResource[] resources, ExecutionEvent event ) throws ExecutionException
+    {
+        try
+        {
+            for ( IResource res : resources )
+            {
+                IProject p = ( IProject ) res;
+                final ISigilProjectModel model = SigilCore.create( p );
+
+                WorkspaceModifyOperation op = new WorkspaceModifyOperation()
+                {
+                    @Override
+                    protected void execute( IProgressMonitor monitor ) throws CoreException, InvocationTargetException,
+                        InterruptedException
+                    {
+                        model.resetClasspath( monitor );
+                    }
+                };
+
+                SigilUI.runWorkspaceOperation( op, null );
+            }
+        }
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Failed to create sigil project for refresh action", e );
+        }
+        return null;
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/RefreshSigilClasspathHandler.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/RefreshSigilClasspathHandler.java
index 25fbd41..be1acbb 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/RefreshSigilClasspathHandler.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/handlers/project/RefreshSigilClasspathHandler.java
@@ -19,14 +19,18 @@
 
 package org.apache.felix.sigil.ui.eclipse.handlers.project;
 
+
 import org.apache.felix.sigil.ui.eclipse.handlers.IResourceCommandHandler;
 import org.apache.felix.sigil.ui.eclipse.handlers.SelectionResourceCommandHandler;
 
-public class RefreshSigilClasspathHandler extends SelectionResourceCommandHandler {
 
-	@Override
-	protected IResourceCommandHandler getResourceCommandHandler() {
-		return new RefreshSigilClasspathCommandHandler();
-	}
+public class RefreshSigilClasspathHandler extends SelectionResourceCommandHandler
+{
+
+    @Override
+    protected IResourceCommandHandler getResourceCommandHandler()
+    {
+        return new RefreshSigilClasspathCommandHandler();
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/startup/SigilStartup.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/startup/SigilStartup.java
index ce00ffb..a0e4d6d 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/startup/SigilStartup.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/startup/SigilStartup.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.startup;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.job.ResolveProjectsJob;
 import org.apache.felix.sigil.repository.IRepositoryChangeListener;
@@ -27,27 +28,34 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.ui.IStartup;
 
-public class SigilStartup implements IStartup {
 
-	public void earlyStartup() {
-		// Create a task to run the resolver
-		final Runnable resolver = new Runnable() {
-			public void run() {
-				IWorkspace workspace = ResourcesPlugin.getWorkspace();
-				ResolveProjectsJob job = new ResolveProjectsJob(workspace);
-				job.setSystem(true);
-				job.schedule();
-			}
-		};
-		
-		// Register a repository change listener to re-run the resolver when repository changes
-		SigilCore.getGlobalRepositoryManager().addRepositoryChangeListener(new IRepositoryChangeListener() {
-			public void repositoryChanged(RepositoryChangeEvent event) {
-				resolver.run();
-			}
-		});
+public class SigilStartup implements IStartup
+{
 
-		// Run the resolver now
-		resolver.run();
-	}
+    public void earlyStartup()
+    {
+        // Create a task to run the resolver
+        final Runnable resolver = new Runnable()
+        {
+            public void run()
+            {
+                IWorkspace workspace = ResourcesPlugin.getWorkspace();
+                ResolveProjectsJob job = new ResolveProjectsJob( workspace );
+                job.setSystem( true );
+                job.schedule();
+            }
+        };
+
+        // Register a repository change listener to re-run the resolver when repository changes
+        SigilCore.getGlobalRepositoryManager().addRepositoryChangeListener( new IRepositoryChangeListener()
+        {
+            public void repositoryChanged( RepositoryChangeEvent event )
+            {
+                resolver.run();
+            }
+        } );
+
+        // Run the resolver now
+        resolver.run();
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/SigilUI.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/SigilUI.java
index 43fdabd..ed2120a 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/SigilUI.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/SigilUI.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui;
 
+
 import java.io.InputStream;
 import java.lang.reflect.InvocationTargetException;
 import java.util.Locale;
@@ -37,145 +38,196 @@
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.osgi.framework.BundleContext;
 
+
 /**
  * The activator class controls the plug-in life cycle
  */
-public class SigilUI extends AbstractUIPlugin {
+public class SigilUI extends AbstractUIPlugin
+{
 
-	// The plug-in ID
-	public static final String PLUGIN_ID = "org.cauldron.sigil.ui";
+    // The plug-in ID
+    public static final String PLUGIN_ID = "org.cauldron.sigil.ui";
 
-	public static final String REPOSITORY_WIZARD_EXTENSION_POINT_ID = "org.cauldron.sigil.ui.repositorywizard";
+    public static final String REPOSITORY_WIZARD_EXTENSION_POINT_ID = "org.cauldron.sigil.ui.repositorywizard";
 
-	public static final String PREF_NOPROMPT_INSTALL_COMPOSITE_WITH_ERRORS = "nopromptInstallCompositeError";
-	public static final String PREF_INSTALL_COMPOSITE_WITH_ERRORS_ANSWER = "answerInstallCompositeError";
+    public static final String PREF_NOPROMPT_INSTALL_COMPOSITE_WITH_ERRORS = "nopromptInstallCompositeError";
+    public static final String PREF_INSTALL_COMPOSITE_WITH_ERRORS_ANSWER = "answerInstallCompositeError";
 
-	public static final String ID_REPOSITORY_VIEW = "org.cauldron.sigil.ui.repositoryBrowser";
-	public static final String ID_DEPENDENCY_VIEW = "org.cauldron.sigil.ui.bundleDependencyView";
-	public static final String ID_INSTANCES_VIEW = "org.cauldron.sigil.runtime.newtonInstancesView";
+    public static final String ID_REPOSITORY_VIEW = "org.cauldron.sigil.ui.repositoryBrowser";
+    public static final String ID_DEPENDENCY_VIEW = "org.cauldron.sigil.ui.bundleDependencyView";
+    public static final String ID_INSTANCES_VIEW = "org.cauldron.sigil.runtime.newtonInstancesView";
 
-	// The shared instance
-	private static SigilUI plugin;
-	
-	/**
-	 * The constructor
-	 */
-	public SigilUI() {
-	}
+    // The shared instance
+    private static SigilUI plugin;
 
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
-	 */
-	public void start(BundleContext context) throws Exception {
-		super.start(context);
-		SigilCore.getDefault();
-		plugin = this;
-	}
 
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
-	 */
-	public void stop(BundleContext context) throws Exception {
-		plugin = null;
-		super.stop(context);
-	}
+    /**
+     * The constructor
+     */
+    public SigilUI()
+    {
+    }
 
-	/**
-	 * Returns the shared instance
-	 *
-	 * @return the shared instance
-	 */
-	public static SigilUI getDefault() {
-		return plugin;
-	}
 
-	public static ResourceBundle getResourceBundle() {
-		return ResourceBundle.getBundle( "resources." + SigilUI.class.getName(), Locale.getDefault(), SigilUI.class.getClassLoader() );
-	}
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+     */
+    public void start( BundleContext context ) throws Exception
+    {
+        super.start( context );
+        SigilCore.getDefault();
+        plugin = this;
+    }
 
-	public static void runWorkspaceOperation(IRunnableWithProgress op, Shell shell) {
-		if ( shell == null ) {
-			shell = getActiveWorkbenchShell();
-		}
-		try {
-			new ProgressMonitorDialog(shell).run(true, true, op);
-		} catch (InvocationTargetException e) {
-			SigilCore.error( "Workspace operation failed", e);
-		} catch (InterruptedException e1) {
-			SigilCore.log( "Workspace operation interrupted");
-		}
-	}
-	
-	public static void runWorkspaceOperationSync(IRunnableWithProgress op, Shell shell) throws Throwable {
-		if ( shell == null ) {
-			shell = getActiveWorkbenchShell();
-		}
-		try {
-			new ProgressMonitorDialog(shell).run(false, true, op);
-		} catch (InvocationTargetException e) {
-			throw e.getCause();
-		} catch (InterruptedException e1) {
-			SigilCore.log( "Workspace operation interrupted");
-		}
-	}
-	public static IWorkbenchWindow getActiveWorkbenchWindow() {
-		return getDefault().getWorkbench().getActiveWorkbenchWindow();
-	}
-	
-	public static Shell getActiveWorkbenchShell() {
-		final Shell[] shell = new Shell[1];
-		runInUISync( new Runnable() {
-			public void run() {
-				shell[0] = getActiveDisplay().getActiveShell();
-			}
-		});
-		return shell[0];
-	}
 
-	public static Display getActiveDisplay() {
-		Display d = Display.getCurrent();
-		
-		if ( d == null ) {
-			d = Display.getDefault();
-		}
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+     */
+    public void stop( BundleContext context ) throws Exception
+    {
+        plugin = null;
+        super.stop( context );
+    }
 
-		return d;
-	}
 
-	public static void runInUI(Runnable runnable) {
-		getActiveDisplay().asyncExec(runnable);
-	}
+    /**
+     * Returns the shared instance
+     *
+     * @return the shared instance
+     */
+    public static SigilUI getDefault()
+    {
+        return plugin;
+    }
 
-	public static void runInUISync(Runnable runnable) {
-		getActiveDisplay().syncExec(runnable);
-	}
-	
-	public static Image cacheImage(String path, ClassLoader classLoader) {
-		ImageRegistry registry = SigilUI.getDefault().getImageRegistry();
-		
-		Image image = registry.get( path );
-		
-		if ( image == null ) {
-			image = loadImage( path, classLoader );
-			// XXX-FIXME-XXX add null image
-			if ( image != null ) {
-				registry.put( path, image);
-			}
-		}
-		
-		return image; 
-	}
 
-	private static Image loadImage(String resource, ClassLoader loader) {
-		InputStream in = loader.getResourceAsStream( resource );
-		if ( in != null ) {
-			ImageData data = new ImageData( in );
-			return new Image( SigilUI.getActiveDisplay(), data );
-		}
-		else {
-			return null;
-		}
-	}
+    public static ResourceBundle getResourceBundle()
+    {
+        return ResourceBundle.getBundle( "resources." + SigilUI.class.getName(), Locale.getDefault(), SigilUI.class
+            .getClassLoader() );
+    }
+
+
+    public static void runWorkspaceOperation( IRunnableWithProgress op, Shell shell )
+    {
+        if ( shell == null )
+        {
+            shell = getActiveWorkbenchShell();
+        }
+        try
+        {
+            new ProgressMonitorDialog( shell ).run( true, true, op );
+        }
+        catch ( InvocationTargetException e )
+        {
+            SigilCore.error( "Workspace operation failed", e );
+        }
+        catch ( InterruptedException e1 )
+        {
+            SigilCore.log( "Workspace operation interrupted" );
+        }
+    }
+
+
+    public static void runWorkspaceOperationSync( IRunnableWithProgress op, Shell shell ) throws Throwable
+    {
+        if ( shell == null )
+        {
+            shell = getActiveWorkbenchShell();
+        }
+        try
+        {
+            new ProgressMonitorDialog( shell ).run( false, true, op );
+        }
+        catch ( InvocationTargetException e )
+        {
+            throw e.getCause();
+        }
+        catch ( InterruptedException e1 )
+        {
+            SigilCore.log( "Workspace operation interrupted" );
+        }
+    }
+
+
+    public static IWorkbenchWindow getActiveWorkbenchWindow()
+    {
+        return getDefault().getWorkbench().getActiveWorkbenchWindow();
+    }
+
+
+    public static Shell getActiveWorkbenchShell()
+    {
+        final Shell[] shell = new Shell[1];
+        runInUISync( new Runnable()
+        {
+            public void run()
+            {
+                shell[0] = getActiveDisplay().getActiveShell();
+            }
+        } );
+        return shell[0];
+    }
+
+
+    public static Display getActiveDisplay()
+    {
+        Display d = Display.getCurrent();
+
+        if ( d == null )
+        {
+            d = Display.getDefault();
+        }
+
+        return d;
+    }
+
+
+    public static void runInUI( Runnable runnable )
+    {
+        getActiveDisplay().asyncExec( runnable );
+    }
+
+
+    public static void runInUISync( Runnable runnable )
+    {
+        getActiveDisplay().syncExec( runnable );
+    }
+
+
+    public static Image cacheImage( String path, ClassLoader classLoader )
+    {
+        ImageRegistry registry = SigilUI.getDefault().getImageRegistry();
+
+        Image image = registry.get( path );
+
+        if ( image == null )
+        {
+            image = loadImage( path, classLoader );
+            // XXX-FIXME-XXX add null image
+            if ( image != null )
+            {
+                registry.put( path, image );
+            }
+        }
+
+        return image;
+    }
+
+
+    private static Image loadImage( String resource, ClassLoader loader )
+    {
+        InputStream in = loader.getResourceAsStream( resource );
+        if ( in != null )
+        {
+            ImageData data = new ImageData( in );
+            return new Image( SigilUI.getActiveDisplay(), data );
+        }
+        else
+        {
+            return null;
+        }
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/completion/CompletionProposal.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/completion/CompletionProposal.java
index 7e10863..569814f 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/completion/CompletionProposal.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/completion/CompletionProposal.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.completion;
 
+
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.contentassist.ICompletionProposal;
@@ -26,100 +27,123 @@
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Point;
 
-class CompletionProposal implements ICompletionProposal {
 
-	private int fReplacementOffset;
-	private int fReplacementLength;
-	private int fCursorPosition;
-	private String fReplacementString;
-	private String fAdditionalProposalInfo;
-	private IContextInformation fContextInformation;
-	private String fDisplayString;
-	private Image fImage;
-	
-	/**
-	 * Creates a new completion proposal based on the provided information. The replacement string is
-	 * considered being the display string too. All remaining fields are set to <code>null</code>.
-	 *
-	 * @param replacementString the actual string to be inserted into the document
-	 * @param replacementOffset the offset of the text to be replaced
-	 * @param replacementLength the length of the text to be replaced
-	 * @param cursorPosition the position of the cursor following the insert relative to replacementOffset
-	 */
-	public CompletionProposal(String replacementString, int replacementOffset, int replacementLength, int cursorPosition) {
-		this(replacementString, replacementOffset, replacementLength, cursorPosition, null, null, null, null);
-	}
+class CompletionProposal implements ICompletionProposal
+{
 
-	/**
-	 * Creates a new completion proposal. All fields are initialized based on the provided information.
-	 *
-	 * @param replacementString the actual string to be inserted into the document
-	 * @param replacementOffset the offset of the text to be replaced
-	 * @param replacementLength the length of the text to be replaced
-	 * @param cursorPosition the position of the cursor following the insert relative to replacementOffset
-	 * @param image the image to display for this proposal
-	 * @param displayString the string to be displayed for the proposal
-	 * @param contextInformation the context information associated with this proposal
-	 * @param additionalProposalInfo the additional information associated with this proposal
-	 */
-	public CompletionProposal(String replacementString, int replacementOffset, int replacementLength, int cursorPosition, Image image, String displayString, IContextInformation contextInformation, String additionalProposalInfo) {
-		fReplacementString= replacementString;
-		fReplacementOffset= replacementOffset;
-		fReplacementLength= replacementLength;
-		fCursorPosition= cursorPosition;
-		fImage= image;
-		fDisplayString= displayString;
-		fContextInformation= contextInformation;
-		fAdditionalProposalInfo= additionalProposalInfo;
-	}
-	
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.text.contentassist.ICompletionProposal#apply(org.eclipse.jface.text.IDocument)
-	 */
-	public void apply( IDocument document ) {
-		try {
-			document.replace(fReplacementOffset, fReplacementLength, fReplacementString);
-		} catch (BadLocationException x) {
-			// ignore
-		}
-	}
+    private int fReplacementOffset;
+    private int fReplacementLength;
+    private int fCursorPosition;
+    private String fReplacementString;
+    private String fAdditionalProposalInfo;
+    private IContextInformation fContextInformation;
+    private String fDisplayString;
+    private Image fImage;
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo()
-	 */
-	public String getAdditionalProposalInfo() {
-		return fAdditionalProposalInfo;
-	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getContextInformation()
-	 */
-	public IContextInformation getContextInformation() {
-		return fContextInformation;
-	}
+    /**
+     * Creates a new completion proposal based on the provided information. The replacement string is
+     * considered being the display string too. All remaining fields are set to <code>null</code>.
+     *
+     * @param replacementString the actual string to be inserted into the document
+     * @param replacementOffset the offset of the text to be replaced
+     * @param replacementLength the length of the text to be replaced
+     * @param cursorPosition the position of the cursor following the insert relative to replacementOffset
+     */
+    public CompletionProposal( String replacementString, int replacementOffset, int replacementLength,
+        int cursorPosition )
+    {
+        this( replacementString, replacementOffset, replacementLength, cursorPosition, null, null, null, null );
+    }
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getDisplayString()
-	 */
-	public String getDisplayString() {
-		if (fDisplayString != null)
-			return fDisplayString;
-		return fReplacementString;
-	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getImage()
-	 */
-	public Image getImage() {
-		return fImage;
-	}
+    /**
+     * Creates a new completion proposal. All fields are initialized based on the provided information.
+     *
+     * @param replacementString the actual string to be inserted into the document
+     * @param replacementOffset the offset of the text to be replaced
+     * @param replacementLength the length of the text to be replaced
+     * @param cursorPosition the position of the cursor following the insert relative to replacementOffset
+     * @param image the image to display for this proposal
+     * @param displayString the string to be displayed for the proposal
+     * @param contextInformation the context information associated with this proposal
+     * @param additionalProposalInfo the additional information associated with this proposal
+     */
+    public CompletionProposal( String replacementString, int replacementOffset, int replacementLength,
+        int cursorPosition, Image image, String displayString, IContextInformation contextInformation,
+        String additionalProposalInfo )
+    {
+        fReplacementString = replacementString;
+        fReplacementOffset = replacementOffset;
+        fReplacementLength = replacementLength;
+        fCursorPosition = cursorPosition;
+        fImage = image;
+        fDisplayString = displayString;
+        fContextInformation = contextInformation;
+        fAdditionalProposalInfo = additionalProposalInfo;
+    }
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getSelection(org.eclipse.jface.text.IDocument)
-	 */
-	public Point getSelection( IDocument document ) {
-		return new Point(fReplacementOffset + fCursorPosition, 0);
-	}
-	
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.text.contentassist.ICompletionProposal#apply(org.eclipse.jface.text.IDocument)
+     */
+    public void apply( IDocument document )
+    {
+        try
+        {
+            document.replace( fReplacementOffset, fReplacementLength, fReplacementString );
+        }
+        catch ( BadLocationException x )
+        {
+            // ignore
+        }
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo()
+     */
+    public String getAdditionalProposalInfo()
+    {
+        return fAdditionalProposalInfo;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getContextInformation()
+     */
+    public IContextInformation getContextInformation()
+    {
+        return fContextInformation;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getDisplayString()
+     */
+    public String getDisplayString()
+    {
+        if ( fDisplayString != null )
+            return fDisplayString;
+        return fReplacementString;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getImage()
+     */
+    public Image getImage()
+    {
+        return fImage;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getSelection(org.eclipse.jface.text.IDocument)
+     */
+    public Point getSelection( IDocument document )
+    {
+        return new Point( fReplacementOffset + fCursorPosition, 0 );
+    }
+
 }
\ No newline at end of file
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/AbstractResourceSection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/AbstractResourceSection.java
index a6d11ad..1147e2d 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/AbstractResourceSection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/AbstractResourceSection.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import java.io.File;
 
 import org.apache.felix.sigil.eclipse.SigilCore;
@@ -42,134 +43,182 @@
 import org.eclipse.swt.widgets.Tree;
 import org.eclipse.ui.forms.IManagedForm;
 
-public abstract class AbstractResourceSection extends SigilSection implements IResourceChangeListener, ICheckStateListener  {
 
-	protected static final Object[] EMPTY = new Object[]{};
-	protected Tree tree;
-	protected CheckboxTreeViewer viewer;
-	private IWorkspace workspace;
+public abstract class AbstractResourceSection extends SigilSection implements IResourceChangeListener,
+    ICheckStateListener
+{
 
-	public AbstractResourceSection(SigilPage page, Composite parent,
-			ISigilProjectModel project) throws CoreException {
-		super(page, parent, project);
-	}
+    protected static final Object[] EMPTY = new Object[]
+        {};
+    protected Tree tree;
+    protected CheckboxTreeViewer viewer;
+    private IWorkspace workspace;
 
-	@Override
-	public void initialize(IManagedForm form) {
-		super.initialize(form);
-		viewer.setAllChecked(false);
-		viewer.setGrayedElements( EMPTY );
-		refreshSelections();
-		viewer.refresh();		
-	}
-	
-	@Override
-	public void refresh() {
-		refreshSelections();
-		super.refresh();
-	}
 
-	public void checkStateChanged(CheckStateChangedEvent event) {
-		handleStateChanged( (IResource) event.getElement(), event.getChecked(), true, true );
-	}
+    public AbstractResourceSection( SigilPage page, Composite parent, ISigilProjectModel project ) throws CoreException
+    {
+        super( page, parent, project );
+    }
 
-	public void resourceChanged(IResourceChangeEvent event) {
-		if ( !getSection().getDisplay().isDisposed() ) {
-			getSection().getDisplay().asyncExec( new Runnable() {
-				public void run() {
-					if ( getSection().isVisible() ) {
-						viewer.refresh();
-					}
-				}			
-			});
-		}
-	}
-	
-	protected void startWorkspaceListener(IWorkspace workspace) {
-		this.workspace = workspace;
-		workspace.addResourceChangeListener(this);
-	}
-	
-	@Override
-	public void dispose() {
-		workspace.removeResourceChangeListener(this);
-	}
 
-	protected abstract void refreshSelections();
-	
-	protected abstract void syncResourceModel(IResource element, boolean checked);
+    @Override
+    public void initialize( IManagedForm form )
+    {
+        super.initialize( form );
+        viewer.setAllChecked( false );
+        viewer.setGrayedElements( EMPTY );
+        refreshSelections();
+        viewer.refresh();
+    }
 
-	protected IResource findResource(IPath path) {
-		IProject project2 = getProjectModel().getProject();
-		File f = project2.getLocation().append(path).toFile();
-		
-		if ( f.exists() ) {
-			try {
-				if ( f.isFile() ) {
-					return project2.getFile(path);
-				}
-				else {
-					return project2.getFolder(path);
-				}
-			}
-			catch (IllegalArgumentException e) {
-				SigilCore.error( "Unknown path " + path );
-				return null;
-			}
-		}
-		else {
-			SigilCore.error( "Unknown file " + f );
-			return null;
-		}
-	}	
-	
 
-	protected void handleStateChanged(IResource element, boolean checked, boolean recurse,
-			boolean sync) {
-				if ( element instanceof IContainer ) {
-					setParentsGrayChecked(element, checked);
-					if ( recurse ) {
-						recursiveCheck( (IContainer) element, checked, sync );
-					}
-				}
-				else {
-					setParentsGrayChecked(element, checked);
-				}
-				
-				if ( sync ) {
-					syncResourceModel( element, checked );
-				}
-			}
+    @Override
+    public void refresh()
+    {
+        refreshSelections();
+        super.refresh();
+    }
 
-	private void recursiveCheck(IContainer element, final boolean checked, final boolean sync) {
-		try {
-			element.accept( new IResourceVisitor() {
-				public boolean visit(IResource resource) throws CoreException {
-					viewer.setChecked(resource, checked);
-					if ( sync ) {
-						syncResourceModel(resource, checked);
-					}
-					return true;
-				}
-			} );
-		}
-		catch ( CoreException e ) {
-			DebugPlugin.log( e.getStatus() );
-		}
-	}
 
-	private void setParentsGrayChecked(IResource r, boolean checked) {
-		while ( r.getParent() != null ) {
-			r = r.getParent();
-			if ( (viewer.getGrayed(r) && viewer.getChecked(r)) == checked) {
-				break;
-			}
-			if ( viewer.getChecked(r) == checked ) {
-				viewer.setGrayed( r, !checked );
-			}
-			else {
-				viewer.setGrayChecked(r, checked);
-			}
-		}
-	}
+    public void checkStateChanged( CheckStateChangedEvent event )
+    {
+        handleStateChanged( ( IResource ) event.getElement(), event.getChecked(), true, true );
+    }
+
+
+    public void resourceChanged( IResourceChangeEvent event )
+    {
+        if ( !getSection().getDisplay().isDisposed() )
+        {
+            getSection().getDisplay().asyncExec( new Runnable()
+            {
+                public void run()
+                {
+                    if ( getSection().isVisible() )
+                    {
+                        viewer.refresh();
+                    }
+                }
+            } );
+        }
+    }
+
+
+    protected void startWorkspaceListener( IWorkspace workspace )
+    {
+        this.workspace = workspace;
+        workspace.addResourceChangeListener( this );
+    }
+
+
+    @Override
+    public void dispose()
+    {
+        workspace.removeResourceChangeListener( this );
+    }
+
+
+    protected abstract void refreshSelections();
+
+
+    protected abstract void syncResourceModel( IResource element, boolean checked );
+
+
+    protected IResource findResource( IPath path )
+    {
+        IProject project2 = getProjectModel().getProject();
+        File f = project2.getLocation().append( path ).toFile();
+
+        if ( f.exists() )
+        {
+            try
+            {
+                if ( f.isFile() )
+                {
+                    return project2.getFile( path );
+                }
+                else
+                {
+                    return project2.getFolder( path );
+                }
+            }
+            catch ( IllegalArgumentException e )
+            {
+                SigilCore.error( "Unknown path " + path );
+                return null;
+            }
+        }
+        else
+        {
+            SigilCore.error( "Unknown file " + f );
+            return null;
+        }
+    }
+
+
+    protected void handleStateChanged( IResource element, boolean checked, boolean recurse, boolean sync )
+    {
+        if ( element instanceof IContainer )
+        {
+            setParentsGrayChecked( element, checked );
+            if ( recurse )
+            {
+                recursiveCheck( ( IContainer ) element, checked, sync );
+            }
+        }
+        else
+        {
+            setParentsGrayChecked( element, checked );
+        }
+
+        if ( sync )
+        {
+            syncResourceModel( element, checked );
+        }
+    }
+
+
+    private void recursiveCheck( IContainer element, final boolean checked, final boolean sync )
+    {
+        try
+        {
+            element.accept( new IResourceVisitor()
+            {
+                public boolean visit( IResource resource ) throws CoreException
+                {
+                    viewer.setChecked( resource, checked );
+                    if ( sync )
+                    {
+                        syncResourceModel( resource, checked );
+                    }
+                    return true;
+                }
+            } );
+        }
+        catch ( CoreException e )
+        {
+            DebugPlugin.log( e.getStatus() );
+        }
+    }
+
+
+    private void setParentsGrayChecked( IResource r, boolean checked )
+    {
+        while ( r.getParent() != null )
+        {
+            r = r.getParent();
+            if ( ( viewer.getGrayed( r ) && viewer.getChecked( r ) ) == checked )
+            {
+                break;
+            }
+            if ( viewer.getChecked( r ) == checked )
+            {
+                viewer.setGrayed( r, !checked );
+            }
+            else
+            {
+                viewer.setGrayChecked( r, checked );
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/BundleDependencySection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/BundleDependencySection.java
index d21598b..7899c72 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/BundleDependencySection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/BundleDependencySection.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
@@ -45,118 +46,151 @@
 import org.eclipse.ui.forms.widgets.TableWrapData;
 import org.eclipse.ui.forms.widgets.TableWrapLayout;
 
-public abstract class BundleDependencySection extends SigilSection {
 
-	private Set<? extends IModelElement> unresolvedElements;
-	
-	protected ProjectTableViewer viewer;
-	private Button add;
-	private Button edit;
-	private Button remove;
+public abstract class BundleDependencySection extends SigilSection
+{
 
-	public BundleDependencySection(SigilPage page, Composite parent, ISigilProjectModel project, Set<IModelElement> unresolvedElements) throws CoreException {
-		super(page, parent, project);
-		viewer.setUnresolvedElements(unresolvedElements);
-	}
-	
-	public BundleDependencySection(SigilPage page, Composite parent, ISigilProjectModel project) throws CoreException {
-		this(page, parent, project, null);
-	}
-	
-	protected abstract String getTitle();
-	
-	protected abstract Label createLabel(Composite parent, FormToolkit toolkit);
-	
-	protected abstract IContentProvider getContentProvider();
+    private Set<? extends IModelElement> unresolvedElements;
 
-	protected abstract void handleAdd();
-	
-	protected abstract void handleEdit();
-	
-	protected abstract void handleRemoved();
-	
-	@Override
-	public void refresh() {
-		super.refresh();
-		viewer.refresh();
-	}
-	
-	protected ISelection getSelection() {
-		return viewer.getSelection();
-	}
+    protected ProjectTableViewer viewer;
+    private Button add;
+    private Button edit;
+    private Button remove;
 
-	@Override
-	protected void createSection(Section section, FormToolkit toolkit) {
-		setTitle( getTitle() );
-		
-		Composite body = createGridBody(2, false, toolkit);
-		
-        Label label = createLabel(body, toolkit);
-        
-        label.setLayoutData( new GridData(SWT.LEFT, SWT.CENTER, true, true, 2, 1 ) );
-        
-		Table bundleTable = toolkit.createTable(body, SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL | SWT.BORDER);
-		GridData data = new GridData( GridData.FILL_BOTH );
-		data.heightHint = 600;
+
+    public BundleDependencySection( SigilPage page, Composite parent, ISigilProjectModel project,
+        Set<IModelElement> unresolvedElements ) throws CoreException
+    {
+        super( page, parent, project );
+        viewer.setUnresolvedElements( unresolvedElements );
+    }
+
+
+    public BundleDependencySection( SigilPage page, Composite parent, ISigilProjectModel project ) throws CoreException
+    {
+        this( page, parent, project, null );
+    }
+
+
+    protected abstract String getTitle();
+
+
+    protected abstract Label createLabel( Composite parent, FormToolkit toolkit );
+
+
+    protected abstract IContentProvider getContentProvider();
+
+
+    protected abstract void handleAdd();
+
+
+    protected abstract void handleEdit();
+
+
+    protected abstract void handleRemoved();
+
+
+    @Override
+    public void refresh()
+    {
+        super.refresh();
+        viewer.refresh();
+    }
+
+
+    protected ISelection getSelection()
+    {
+        return viewer.getSelection();
+    }
+
+
+    @Override
+    protected void createSection( Section section, FormToolkit toolkit )
+    {
+        setTitle( getTitle() );
+
+        Composite body = createGridBody( 2, false, toolkit );
+
+        Label label = createLabel( body, toolkit );
+
+        label.setLayoutData( new GridData( SWT.LEFT, SWT.CENTER, true, true, 2, 1 ) );
+
+        Table bundleTable = toolkit.createTable( body, SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL | SWT.BORDER );
+        GridData data = new GridData( GridData.FILL_BOTH );
+        data.heightHint = 600;
         bundleTable.setLayoutData( data );
-        bundleTable.setLinesVisible(false);        
-        createButtons(body, toolkit);        
+        bundleTable.setLinesVisible( false );
+        createButtons( body, toolkit );
         createViewer( bundleTable );
-	}
-	
-	protected void createButtons(Composite body, FormToolkit toolkit) {
-	    Composite buttons = toolkit.createComposite(body);
-	    TableWrapLayout layout = new TableWrapLayout();
-	    layout.numColumns = 1;
-	    layout.topMargin = 0;
-	    layout.leftMargin = 0;
-	    layout.rightMargin = 0;
-	    layout.bottomMargin = 0;
-	    buttons.setLayout( layout );
-	    GridData data = new GridData();
-	    data.verticalAlignment = SWT.TOP;
-	    buttons.setLayoutData(data);
-	    
-	    add = toolkit.createButton(buttons, "Add", SWT.NULL);
-	    add.setLayoutData( new TableWrapData( TableWrapData.FILL ) );
-	    add.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleAdd();
-			}        	
-	    } );
-	    
-	    edit = toolkit.createButton(buttons, "Edit", SWT.NULL);
-	    edit.setLayoutData( new TableWrapData( TableWrapData.FILL ) );
-	    edit.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleEdit();
-			}        	
-	    } );
-	    
-	    remove = toolkit.createButton(buttons, "Remove", SWT.NULL);
-	    remove.setLayoutData( new TableWrapData( TableWrapData.FILL ) );
-	    remove.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleRemoved();
-			}
-	    } );
-	    
-	    setSelected(false);
-	}
+    }
 
-	protected void createViewer(Table bundleTable) {
-	    viewer = new ProjectTableViewer(bundleTable);
-	    viewer.setContentProvider(getContentProvider());  
-	    viewer.addSelectionChangedListener( new ISelectionChangedListener() {
-			public void selectionChanged(SelectionChangedEvent event) {
-				setSelected(!event.getSelection().isEmpty());
-			}
-	    });
-	}
 
-	private void setSelected(boolean selected) {
-		edit.setEnabled(selected);
-		remove.setEnabled(selected);
-	}
+    protected void createButtons( Composite body, FormToolkit toolkit )
+    {
+        Composite buttons = toolkit.createComposite( body );
+        TableWrapLayout layout = new TableWrapLayout();
+        layout.numColumns = 1;
+        layout.topMargin = 0;
+        layout.leftMargin = 0;
+        layout.rightMargin = 0;
+        layout.bottomMargin = 0;
+        buttons.setLayout( layout );
+        GridData data = new GridData();
+        data.verticalAlignment = SWT.TOP;
+        buttons.setLayoutData( data );
+
+        add = toolkit.createButton( buttons, "Add", SWT.NULL );
+        add.setLayoutData( new TableWrapData( TableWrapData.FILL ) );
+        add.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                handleAdd();
+            }
+        } );
+
+        edit = toolkit.createButton( buttons, "Edit", SWT.NULL );
+        edit.setLayoutData( new TableWrapData( TableWrapData.FILL ) );
+        edit.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                handleEdit();
+            }
+        } );
+
+        remove = toolkit.createButton( buttons, "Remove", SWT.NULL );
+        remove.setLayoutData( new TableWrapData( TableWrapData.FILL ) );
+        remove.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                handleRemoved();
+            }
+        } );
+
+        setSelected( false );
+    }
+
+
+    protected void createViewer( Table bundleTable )
+    {
+        viewer = new ProjectTableViewer( bundleTable );
+        viewer.setContentProvider( getContentProvider() );
+        viewer.addSelectionChangedListener( new ISelectionChangedListener()
+        {
+            public void selectionChanged( SelectionChangedEvent event )
+            {
+                setSelected( !event.getSelection().isEmpty() );
+            }
+        } );
+    }
+
+
+    private void setSelected( boolean selected )
+    {
+        edit.setEnabled( selected );
+        remove.setEnabled( selected );
+    }
 
 }
\ No newline at end of file
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ClasspathSection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ClasspathSection.java
index 789aeb5..1e8e718 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ClasspathSection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ClasspathSection.java
@@ -56,39 +56,49 @@
 import org.eclipse.ui.forms.widgets.TableWrapData;
 import org.eclipse.ui.forms.widgets.TableWrapLayout;
 
-public class ClasspathSection extends SigilSection {
 
-	private ProjectTableViewer viewer;
-	private final Comparator<IClasspathEntry> CLASSPATH_COMPARATOR = new Comparator<IClasspathEntry>() {
-		public int compare(IClasspathEntry o1, IClasspathEntry o2) {
-			return compareClasspaths(o1, o2);
-		}
-	};
+public class ClasspathSection extends SigilSection
+{
 
-	public ClasspathSection(SigilPage page, Composite parent, ISigilProjectModel project) throws CoreException {
-		super( page, parent, project );
-	}
-	
-	@Override
-	protected void createSection(Section section, FormToolkit toolkit) {
-		setTitle( "Classpath");
-		
-		Composite body = createGridBody(2, false, toolkit);
-		
+    private ProjectTableViewer viewer;
+    private final Comparator<IClasspathEntry> CLASSPATH_COMPARATOR = new Comparator<IClasspathEntry>()
+    {
+        public int compare( IClasspathEntry o1, IClasspathEntry o2 )
+        {
+            return compareClasspaths( o1, o2 );
+        }
+    };
+
+
+    public ClasspathSection( SigilPage page, Composite parent, ISigilProjectModel project ) throws CoreException
+    {
+        super( page, parent, project );
+    }
+
+
+    @Override
+    protected void createSection( Section section, FormToolkit toolkit )
+    {
+        setTitle( "Classpath" );
+
+        Composite body = createGridBody( 2, false, toolkit );
+
         Label label = toolkit.createLabel( body, "Specify the internal classpath of this bundle." );
-        label.setLayoutData( new GridData(SWT.LEFT, SWT.CENTER, true, true, 2, 1 ) );
-		
-		Table bundleTable = toolkit.createTable(body, SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL | SWT.BORDER);
-		GridData tableLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
-		tableLayoutData.heightHint = 150;
-        bundleTable.setLayoutData(tableLayoutData);
-        
-        createButtons(body, toolkit);
-        createViewer( bundleTable );
-	}
+        label.setLayoutData( new GridData( SWT.LEFT, SWT.CENTER, true, true, 2, 1 ) );
 
-	private void createButtons(Composite body, FormToolkit toolkit) {
-        Composite buttons = toolkit.createComposite(body);
+        Table bundleTable = toolkit.createTable( body, SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL | SWT.BORDER );
+        GridData tableLayoutData = new GridData( SWT.FILL, SWT.FILL, true, true );
+        tableLayoutData.heightHint = 150;
+        bundleTable.setLayoutData( tableLayoutData );
+
+        createButtons( body, toolkit );
+        createViewer( bundleTable );
+    }
+
+
+    private void createButtons( Composite body, FormToolkit toolkit )
+    {
+        Composite buttons = toolkit.createComposite( body );
         TableWrapLayout layout = new TableWrapLayout();
         layout.numColumns = 1;
         layout.topMargin = 0;
@@ -96,145 +106,197 @@
         layout.rightMargin = 0;
         layout.bottomMargin = 0;
         buttons.setLayout( layout );
-        
-        Button add = toolkit.createButton(buttons, "Add", SWT.NULL);
+
+        Button add = toolkit.createButton( buttons, "Add", SWT.NULL );
         add.setLayoutData( new TableWrapData( TableWrapData.FILL ) );
-        add.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleAdd();
-			}        	
+        add.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                handleAdd();
+            }
         } );
-        
-        Button remove = toolkit.createButton(buttons, "Remove", SWT.NULL);
+
+        Button remove = toolkit.createButton( buttons, "Remove", SWT.NULL );
         remove.setLayoutData( new TableWrapData( TableWrapData.FILL ) );
-        remove.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleRemoved();
-			}
+        remove.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                handleRemoved();
+            }
         } );
-	}
+    }
 
-	private void createViewer(Table bundleTable) {
-        viewer = new ProjectTableViewer(bundleTable);
-        viewer.setContentProvider( new DefaultTableProvider() {
-			public Object[] getElements(Object inputElement) {
-				ArrayList<IClasspathEntry> cp = new ArrayList<IClasspathEntry>();
-				for (IClasspathEntry cpe : JavaHelper.findClasspathEntries(getBundle())) {
-					cp.add(cpe);
-				}
-				
-				Collections.sort(cp, new Comparator<IClasspathEntry>() {
-					public int compare(IClasspathEntry o1, IClasspathEntry o2) {
-						return o1.toString().compareTo(o2.toString());
-					}
-				});
-				return cp.toArray();
-			}
-        });    
-        viewer.setComparator(new ViewerComparator() {
-			@Override
-			public int category(Object element) {
-				return index((IClasspathEntry) element);
-			}
-        });
-	}
-	
-	protected ISigilBundle getBundle() {
-		return getProjectModel().getBundle();
-	}
 
-	private void handleAdd() {
-		try {
-			BackgroundLoadingSelectionDialog<IClasspathEntry> dialog = new BackgroundLoadingSelectionDialog<IClasspathEntry>(getSection().getShell(), "Classpath Entry:", true);
-			
-			dialog.setDescriptor(new IElementDescriptor<IClasspathEntry>() {
-				public String getName(IClasspathEntry element) {
-					return element.getPath().toString();
-				}
-			
-				public String getLabel(IClasspathEntry element) {
-					return getName(element);
-				}
-			});
-			
-			dialog.setLabelProvider(new ModelLabelProvider());
-			
-			dialog.setFilter(new IFilter<IClasspathEntry>() {
-				public boolean select(IClasspathEntry cp) {
-					switch ( cp.getEntryKind() ) {
-					case IClasspathEntry.CPE_LIBRARY:
-					case IClasspathEntry.CPE_VARIABLE:
-					case IClasspathEntry.CPE_SOURCE:
-						return !getBundle().getClasspathEntrys().contains(encode(cp));
-					default:
-						return false;
-					}
-				}
-			});
-			
-			dialog.setComparator(CLASSPATH_COMPARATOR);
-			
-			IClasspathEntry[] classpath = getProjectModel().getJavaModel().getRawClasspath();
-			dialog.addElements(Arrays.asList(classpath));
-			if ( dialog.open() == Window.OK ) {
-				List<IClasspathEntry> selectedElements = dialog.getSelectedElements();
-				
-				Object[] added = selectedElements.toArray();
-				for (IClasspathEntry entry : selectedElements) {
-					getBundle().addClasspathEntry(encode(entry));
-				}
-				viewer.add(added);
-				viewer.refresh();
-				markDirty();
-			}
-		} catch (JavaModelException e) {
-			ErrorDialog.openError(getSection().getShell(), "Error", null, e.getStatus());
-		}
-	}
+    private void createViewer( Table bundleTable )
+    {
+        viewer = new ProjectTableViewer( bundleTable );
+        viewer.setContentProvider( new DefaultTableProvider()
+        {
+            public Object[] getElements( Object inputElement )
+            {
+                ArrayList<IClasspathEntry> cp = new ArrayList<IClasspathEntry>();
+                for ( IClasspathEntry cpe : JavaHelper.findClasspathEntries( getBundle() ) )
+                {
+                    cp.add( cpe );
+                }
 
-	private int compareClasspaths(IClasspathEntry o1, IClasspathEntry o2) {
-		if ( o1.getEntryKind() == o2.getEntryKind() ) {
-			ModelLabelProvider mlp = viewer.getLabelProvider();
-			return mlp.getText(o1).compareTo(mlp.getText(o2));
-		}
-		else {
-			int i1 = index(o1);
-			int i2 = index(o2);
-			
-			if ( i1 < i2 ) {
-				return -1;
-			}
-			else {
-				return 1;
-			}
-		}
-	}
+                Collections.sort( cp, new Comparator<IClasspathEntry>()
+                {
+                    public int compare( IClasspathEntry o1, IClasspathEntry o2 )
+                    {
+                        return o1.toString().compareTo( o2.toString() );
+                    }
+                } );
+                return cp.toArray();
+            }
+        } );
+        viewer.setComparator( new ViewerComparator()
+        {
+            @Override
+            public int category( Object element )
+            {
+                return index( ( IClasspathEntry ) element );
+            }
+        } );
+    }
 
-	private static int index(IClasspathEntry o1) {
-		switch ( o1.getEntryKind() ) {
-		case IClasspathEntry.CPE_SOURCE: return 0;
-		case IClasspathEntry.CPE_PROJECT: return 1;
-		case IClasspathEntry.CPE_LIBRARY: return 2;
-		case IClasspathEntry.CPE_VARIABLE: return 3;
-		case IClasspathEntry.CPE_CONTAINER: return 4;
-		default: throw new IllegalStateException( "Unknown classpath entry type " + o1);
-		}
-	}
 
-	private String encode(IClasspathEntry cp) {
-		return getProjectModel().getJavaModel().encodeClasspathEntry(cp).trim();
-	}
+    protected ISigilBundle getBundle()
+    {
+        return getProjectModel().getBundle();
+    }
 
-	@SuppressWarnings("unchecked")
-	private void handleRemoved() {
-		IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
 
-		if ( !selection.isEmpty() ) {
-			for ( Iterator<IClasspathEntry> i = selection.iterator(); i.hasNext(); ) {			
-				getBundle().removeClasspathEntry(getProjectModel().getJavaModel().encodeClasspathEntry(i.next()).trim());
-			}		
-			viewer.remove(selection.toArray());
-			markDirty();
-		}
-	}
+    private void handleAdd()
+    {
+        try
+        {
+            BackgroundLoadingSelectionDialog<IClasspathEntry> dialog = new BackgroundLoadingSelectionDialog<IClasspathEntry>(
+                getSection().getShell(), "Classpath Entry:", true );
+
+            dialog.setDescriptor( new IElementDescriptor<IClasspathEntry>()
+            {
+                public String getName( IClasspathEntry element )
+                {
+                    return element.getPath().toString();
+                }
+
+
+                public String getLabel( IClasspathEntry element )
+                {
+                    return getName( element );
+                }
+            } );
+
+            dialog.setLabelProvider( new ModelLabelProvider() );
+
+            dialog.setFilter( new IFilter<IClasspathEntry>()
+            {
+                public boolean select( IClasspathEntry cp )
+                {
+                    switch ( cp.getEntryKind() )
+                    {
+                        case IClasspathEntry.CPE_LIBRARY:
+                        case IClasspathEntry.CPE_VARIABLE:
+                        case IClasspathEntry.CPE_SOURCE:
+                            return !getBundle().getClasspathEntrys().contains( encode( cp ) );
+                        default:
+                            return false;
+                    }
+                }
+            } );
+
+            dialog.setComparator( CLASSPATH_COMPARATOR );
+
+            IClasspathEntry[] classpath = getProjectModel().getJavaModel().getRawClasspath();
+            dialog.addElements( Arrays.asList( classpath ) );
+            if ( dialog.open() == Window.OK )
+            {
+                List<IClasspathEntry> selectedElements = dialog.getSelectedElements();
+
+                Object[] added = selectedElements.toArray();
+                for ( IClasspathEntry entry : selectedElements )
+                {
+                    getBundle().addClasspathEntry( encode( entry ) );
+                }
+                viewer.add( added );
+                viewer.refresh();
+                markDirty();
+            }
+        }
+        catch ( JavaModelException e )
+        {
+            ErrorDialog.openError( getSection().getShell(), "Error", null, e.getStatus() );
+        }
+    }
+
+
+    private int compareClasspaths( IClasspathEntry o1, IClasspathEntry o2 )
+    {
+        if ( o1.getEntryKind() == o2.getEntryKind() )
+        {
+            ModelLabelProvider mlp = viewer.getLabelProvider();
+            return mlp.getText( o1 ).compareTo( mlp.getText( o2 ) );
+        }
+        else
+        {
+            int i1 = index( o1 );
+            int i2 = index( o2 );
+
+            if ( i1 < i2 )
+            {
+                return -1;
+            }
+            else
+            {
+                return 1;
+            }
+        }
+    }
+
+
+    private static int index( IClasspathEntry o1 )
+    {
+        switch ( o1.getEntryKind() )
+        {
+            case IClasspathEntry.CPE_SOURCE:
+                return 0;
+            case IClasspathEntry.CPE_PROJECT:
+                return 1;
+            case IClasspathEntry.CPE_LIBRARY:
+                return 2;
+            case IClasspathEntry.CPE_VARIABLE:
+                return 3;
+            case IClasspathEntry.CPE_CONTAINER:
+                return 4;
+            default:
+                throw new IllegalStateException( "Unknown classpath entry type " + o1 );
+        }
+    }
+
+
+    private String encode( IClasspathEntry cp )
+    {
+        return getProjectModel().getJavaModel().encodeClasspathEntry( cp ).trim();
+    }
+
+
+    @SuppressWarnings("unchecked")
+    private void handleRemoved()
+    {
+        IStructuredSelection selection = ( IStructuredSelection ) viewer.getSelection();
+
+        if ( !selection.isEmpty() )
+        {
+            for ( Iterator<IClasspathEntry> i = selection.iterator(); i.hasNext(); )
+            {
+                getBundle().removeClasspathEntry(
+                    getProjectModel().getJavaModel().encodeClasspathEntry( i.next() ).trim() );
+            }
+            viewer.remove( selection.toArray() );
+            markDirty();
+        }
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ContainerTreeProvider.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ContainerTreeProvider.java
index f775ec3..1def990 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ContainerTreeProvider.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ContainerTreeProvider.java
@@ -19,45 +19,63 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import org.apache.felix.sigil.ui.eclipse.ui.util.DefaultTreeContentProvider;
 import org.eclipse.core.resources.IContainer;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.debug.core.DebugPlugin;
 
-public class ContainerTreeProvider extends DefaultTreeContentProvider {
 
-	private static final Object[] EMPTY = new Object[] {};
-	
-	public Object[] getChildren(Object parentElement) {
-		if ( parentElement instanceof IContainer ) {
-			IContainer f = (IContainer) parentElement;
-			try {
-				return f.members();
-			} catch (CoreException e) {
-				DebugPlugin.log( e.getStatus() );
-			}
-		}
-		return EMPTY;	
-	}
+public class ContainerTreeProvider extends DefaultTreeContentProvider
+{
 
-	public Object getParent(Object element) {
-		IResource r = (IResource) element;
-		return r.getParent();
-	}
+    private static final Object[] EMPTY = new Object[]
+        {};
 
-	public boolean hasChildren(Object element) {
-		if ( element instanceof IContainer ) {
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
 
-	public Object[] getElements(Object inputElement) {
-		IContainer container = (IContainer) inputElement;
-		return getChildren(container);
-	}
+    public Object[] getChildren( Object parentElement )
+    {
+        if ( parentElement instanceof IContainer )
+        {
+            IContainer f = ( IContainer ) parentElement;
+            try
+            {
+                return f.members();
+            }
+            catch ( CoreException e )
+            {
+                DebugPlugin.log( e.getStatus() );
+            }
+        }
+        return EMPTY;
+    }
+
+
+    public Object getParent( Object element )
+    {
+        IResource r = ( IResource ) element;
+        return r.getParent();
+    }
+
+
+    public boolean hasChildren( Object element )
+    {
+        if ( element instanceof IContainer )
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    public Object[] getElements( Object inputElement )
+    {
+        IContainer container = ( IContainer ) inputElement;
+        return getChildren( container );
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ContentSummarySection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ContentSummarySection.java
index bb9abed..ef9d0f6 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ContentSummarySection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ContentSummarySection.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.apache.felix.sigil.ui.eclipse.ui.form.SigilPage;
 import org.apache.felix.sigil.ui.eclipse.ui.form.SigilSection;
@@ -30,35 +31,42 @@
 import org.eclipse.ui.forms.widgets.Hyperlink;
 import org.eclipse.ui.forms.widgets.Section;
 
-public class ContentSummarySection extends SigilSection {
 
-	public ContentSummarySection(SigilPage page, Composite parent, ISigilProjectModel project) throws CoreException {
-		super( page, parent, project );
-	}
+public class ContentSummarySection extends SigilSection
+{
 
-	@Override
-	protected void createSection(Section section, FormToolkit toolkit) {
-		setTitle( "Project Content");
-		
-		Composite body = createTableWrapBody(2, toolkit);
-		Hyperlink link = toolkit.createHyperlink( body, "Contents:", SWT.NONE );
-		link.setHref( ContentsForm.PAGE_ID );
-		link.addHyperlinkListener(this);
-		toolkit.createLabel( body, "Manage the content that this bundle provides." );
-		
-		link = toolkit.createHyperlink( body, "Dependencies:", SWT.NONE );
-		link.setHref( DependenciesForm.PAGE_ID );
-		link.addHyperlinkListener(this);
-		toolkit.createLabel( body, "Manage the dependencies that this bundle needs to run." );
-		
-		link = toolkit.createHyperlink( body, "Exports:", SWT.NONE );
-		link.setHref( ExportsForm.PAGE_ID );
-		link.addHyperlinkListener(this);
-		toolkit.createLabel( body, "Manage the resources that this bundle exports." );
-	}
+    public ContentSummarySection( SigilPage page, Composite parent, ISigilProjectModel project ) throws CoreException
+    {
+        super( page, parent, project );
+    }
 
-	@Override
-	public void linkActivated(HyperlinkEvent e) {
-		getPage().getEditor().setActivePage( (String) e.getHref() );
-	}
+
+    @Override
+    protected void createSection( Section section, FormToolkit toolkit )
+    {
+        setTitle( "Project Content" );
+
+        Composite body = createTableWrapBody( 2, toolkit );
+        Hyperlink link = toolkit.createHyperlink( body, "Contents:", SWT.NONE );
+        link.setHref( ContentsForm.PAGE_ID );
+        link.addHyperlinkListener( this );
+        toolkit.createLabel( body, "Manage the content that this bundle provides." );
+
+        link = toolkit.createHyperlink( body, "Dependencies:", SWT.NONE );
+        link.setHref( DependenciesForm.PAGE_ID );
+        link.addHyperlinkListener( this );
+        toolkit.createLabel( body, "Manage the dependencies that this bundle needs to run." );
+
+        link = toolkit.createHyperlink( body, "Exports:", SWT.NONE );
+        link.setHref( ExportsForm.PAGE_ID );
+        link.addHyperlinkListener( this );
+        toolkit.createLabel( body, "Manage the resources that this bundle exports." );
+    }
+
+
+    @Override
+    public void linkActivated( HyperlinkEvent e )
+    {
+        getPage().getEditor().setActivePage( ( String ) e.getHref() );
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ContentsForm.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ContentsForm.java
index 75fdde4..ca0e74b 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ContentsForm.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ContentsForm.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.apache.felix.sigil.ui.eclipse.ui.form.SigilPage;
@@ -31,25 +32,31 @@
 import org.eclipse.ui.forms.widgets.TableWrapData;
 import org.eclipse.ui.forms.widgets.TableWrapLayout;
 
-public class ContentsForm extends SigilPage  {
 
-	public static final String PAGE_ID = "contents";
-	
-	private ISigilProjectModel project;
-	
-	public ContentsForm(FormEditor editor, ISigilProjectModel project) {
-		super(editor, PAGE_ID, "Contents");
-		this.project = project;
-	}
-	
+public class ContentsForm extends SigilPage
+{
+
+    public static final String PAGE_ID = "contents";
+
+    private ISigilProjectModel project;
+
+
+    public ContentsForm( FormEditor editor, ISigilProjectModel project )
+    {
+        super( editor, PAGE_ID, "Contents" );
+        this.project = project;
+    }
+
+
     @Override
-    protected void createFormContent(IManagedForm managedForm) {
+    protected void createFormContent( IManagedForm managedForm )
+    {
         FormToolkit toolkit = managedForm.getToolkit();
-        
+
         ScrolledForm form = managedForm.getForm();
         form.setText( "Contents" );
-        
-        Composite body = form.getBody();        
+
+        Composite body = form.getBody();
         TableWrapLayout layout = new TableWrapLayout();
         layout.bottomMargin = 10;
         layout.topMargin = 5;
@@ -57,41 +64,43 @@
         layout.rightMargin = 10;
         layout.numColumns = 2;
         layout.horizontalSpacing = 10;
-        body.setLayout(layout);
-        body.setLayoutData(new TableWrapData(TableWrapData.FILL));
-        
-        Composite top = toolkit.createComposite(body);
+        body.setLayout( layout );
+        body.setLayoutData( new TableWrapData( TableWrapData.FILL ) );
+
+        Composite top = toolkit.createComposite( body );
         layout = new TableWrapLayout();
         layout.verticalSpacing = 20;
-        top.setLayout(layout);
-        TableWrapData data = new TableWrapData(TableWrapData.FILL_GRAB);
+        top.setLayout( layout );
+        TableWrapData data = new TableWrapData( TableWrapData.FILL_GRAB );
         data.colspan = 2;
-        top.setLayoutData(data);
-        
-        Composite left = toolkit.createComposite(body);
+        top.setLayoutData( data );
+
+        Composite left = toolkit.createComposite( body );
         layout = new TableWrapLayout();
         layout.verticalSpacing = 20;
-        left.setLayout(layout);
-        left.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
-        
-        Composite right = toolkit.createComposite(body);
+        left.setLayout( layout );
+        left.setLayoutData( new TableWrapData( TableWrapData.FILL_GRAB ) );
+
+        Composite right = toolkit.createComposite( body );
         layout = new TableWrapLayout();
         layout.verticalSpacing = 20;
-        right.setLayout(layout);
-        right.setLayoutData( new TableWrapData( TableWrapData.FILL_GRAB) );
-                
-        try {
-	        ClasspathSection classpath = new ClasspathSection( this, top, project );
-	        managedForm.addPart( classpath );
-	        
-	        ResourceBuildSection runtimeBuild = new ResourceBuildSection( this, left, project );
-	        managedForm.addPart( runtimeBuild );
-	        
-	        DownloadSection download = new DownloadSection( this, right, project );
-	        managedForm.addPart( download );	        
+        right.setLayout( layout );
+        right.setLayoutData( new TableWrapData( TableWrapData.FILL_GRAB ) );
+
+        try
+        {
+            ClasspathSection classpath = new ClasspathSection( this, top, project );
+            managedForm.addPart( classpath );
+
+            ResourceBuildSection runtimeBuild = new ResourceBuildSection( this, left, project );
+            managedForm.addPart( runtimeBuild );
+
+            DownloadSection download = new DownloadSection( this, right, project );
+            managedForm.addPart( download );
         }
-        catch (CoreException e) {
-        	SigilCore.error( "Failed to create contents form", e);
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Failed to create contents form", e );
         }
     }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DependenciesForm.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DependenciesForm.java
index 3dbce0c..1bb7e3d 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DependenciesForm.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DependenciesForm.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import java.util.Set;
 
 import org.apache.felix.sigil.eclipse.SigilCore;
@@ -34,36 +35,43 @@
 import org.eclipse.ui.forms.widgets.TableWrapData;
 import org.eclipse.ui.forms.widgets.TableWrapLayout;
 
-public class DependenciesForm extends SigilPage  {
 
-	public static final String PAGE_ID = "dependencies";
-	
-	private final ISigilProjectModel project;
-	private final Set<IModelElement> unresolvedElements;
+public class DependenciesForm extends SigilPage
+{
 
-	private ImportPackagesSection importPackages;
-	private RequiresBundleSection requiresSection;
+    public static final String PAGE_ID = "dependencies";
 
-	
-	public DependenciesForm(FormEditor editor, ISigilProjectModel project, Set<IModelElement> unresolved) {
-		super(editor, PAGE_ID, "Dependencies");
-		this.project = project;
-		this.unresolvedElements = unresolved;
-	}
-	
+    private final ISigilProjectModel project;
+    private final Set<IModelElement> unresolvedElements;
+
+    private ImportPackagesSection importPackages;
+    private RequiresBundleSection requiresSection;
+
+
+    public DependenciesForm( FormEditor editor, ISigilProjectModel project, Set<IModelElement> unresolved )
+    {
+        super( editor, PAGE_ID, "Dependencies" );
+        this.project = project;
+        this.unresolvedElements = unresolved;
+    }
+
+
     @Override
-	public boolean canLeaveThePage() {
-    	return !isDirty();
-	}
+    public boolean canLeaveThePage()
+    {
+        return !isDirty();
+    }
 
-	@Override
-    protected void createFormContent(IManagedForm managedForm) {
+
+    @Override
+    protected void createFormContent( IManagedForm managedForm )
+    {
         FormToolkit toolkit = managedForm.getToolkit();
-        
+
         ScrolledForm form = managedForm.getForm();
         form.setText( "Dependencies" );
-        
-        Composite body = form.getBody();        
+
+        Composite body = form.getBody();
         TableWrapLayout layout = new TableWrapLayout();
         layout.bottomMargin = 10;
         layout.topMargin = 5;
@@ -71,41 +79,43 @@
         layout.rightMargin = 10;
         layout.numColumns = 2;
         layout.horizontalSpacing = 10;
-        body.setLayout(layout);
-        body.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
-        
-        Composite left = toolkit.createComposite(body);
+        body.setLayout( layout );
+        body.setLayoutData( new TableWrapData( TableWrapData.FILL_GRAB ) );
+
+        Composite left = toolkit.createComposite( body );
         layout = new TableWrapLayout();
         layout.verticalSpacing = 20;
-        left.setLayout(layout);
-        TableWrapData layoutData = new TableWrapData(TableWrapData.FILL_GRAB);
+        left.setLayout( layout );
+        TableWrapData layoutData = new TableWrapData( TableWrapData.FILL_GRAB );
         layoutData.rowspan = 2;
-        left.setLayoutData(layoutData);
-        
-        Composite right = toolkit.createComposite(body);
+        left.setLayoutData( layoutData );
+
+        Composite right = toolkit.createComposite( body );
         layout = new TableWrapLayout();
         layout.verticalSpacing = 20;
-        right.setLayout(layout);
-        right.setLayoutData(new TableWrapData( TableWrapData.FILL_GRAB) );
-        
-        Composite bottom = toolkit.createComposite(body);
+        right.setLayout( layout );
+        right.setLayoutData( new TableWrapData( TableWrapData.FILL_GRAB ) );
+
+        Composite bottom = toolkit.createComposite( body );
         layout = new TableWrapLayout();
         layout.verticalSpacing = 20;
-        bottom.setLayout(layout);
-        bottom.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
-                
-        try {
-	        importPackages = new ImportPackagesSection( this, left, project, unresolvedElements );
-	        managedForm.addPart( importPackages );
-	        
-	        requiresSection = new RequiresBundleSection(this, right, project, unresolvedElements );
-	        managedForm.addPart(requiresSection);
-	        
-	        DependencyManagementSection depMgmt = new DependencyManagementSection(this, bottom, project);
-	        managedForm.addPart(depMgmt);
+        bottom.setLayout( layout );
+        bottom.setLayoutData( new TableWrapData( TableWrapData.FILL_GRAB ) );
+
+        try
+        {
+            importPackages = new ImportPackagesSection( this, left, project, unresolvedElements );
+            managedForm.addPart( importPackages );
+
+            requiresSection = new RequiresBundleSection( this, right, project, unresolvedElements );
+            managedForm.addPart( requiresSection );
+
+            DependencyManagementSection depMgmt = new DependencyManagementSection( this, bottom, project );
+            managedForm.addPart( depMgmt );
         }
-        catch (CoreException e) {
-        	SigilCore.error( "Failed to create dependencies form", e);
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Failed to create dependencies form", e );
         }
     }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DependencyManagementSection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DependencyManagementSection.java
index 234b83f..255fdae 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DependencyManagementSection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DependencyManagementSection.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -62,135 +63,174 @@
 import org.eclipse.ui.forms.widgets.Hyperlink;
 import org.eclipse.ui.forms.widgets.Section;
 
-public class DependencyManagementSection extends SigilSection {
 
-	private Hyperlink hypConvertRBtoIP;
+public class DependencyManagementSection extends SigilSection
+{
 
-	public DependencyManagementSection(SigilPage page, Composite parent,
-			ISigilProjectModel project) throws CoreException {
-		super(page, parent, project);
-	}
+    private Hyperlink hypConvertRBtoIP;
 
-	protected void createSection(Section section, FormToolkit toolkit) throws CoreException {
-		setTitle("Dependency Management");
-		
-		Composite body = createGridBody(1, false, toolkit);
-		
-		hypConvertRBtoIP = toolkit.createHyperlink(body, "Convert Required Bundles to Imported Packages", SWT.NONE);
-		hypConvertRBtoIP.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		
-		hypConvertRBtoIP.addHyperlinkListener(new HyperlinkAdapter() {
-			public void linkActivated(HyperlinkEvent e) {
-				run();
-			}
-		});
-	}
-	
-	protected void run() {
-		final Map<String, IPackageExport> exports = new HashMap<String, IPackageExport>();
-		final Set<String> imports = new HashSet<String>();
-		
-		// Find all exports
-		final ExportedPackageFinder exportFinder = new ExportedPackageFinder(getProjectModel(), new AccumulatorAdapter<IPackageExport>() {
-			public void addElements(Collection<? extends IPackageExport> elements) {
-				for (IPackageExport export : elements) {
-					exports.put(export.getPackageName(), export);
-				}
-			}
-		});
-		Job findExportsJob = new Job("Find exports") {
-			protected IStatus run(IProgressMonitor monitor) {
-				return exportFinder.run(monitor);
-			}
-		};
-		findExportsJob.setUser(true);
-		findExportsJob.schedule();
-		
-		// Find imports from Java source
-		Job findImportsJob = new Job("Find imports") {
-			protected IStatus run(IProgressMonitor monitor) {
-				IJavaProject javaProject = getProjectModel().getJavaModel();
-				try {
-					IPackageFragment[] packages = javaProject.getPackageFragments();
-					for (IPackageFragment pkg : packages) {
-						ICompilationUnit[] compilationUnits = pkg.getCompilationUnits();
-						for (ICompilationUnit compilationUnit : compilationUnits) {
-							IImportDeclaration[] importDecls = compilationUnit.getImports();
-							for (IImportDeclaration importDecl : importDecls) {
-								imports.add(getPackageName(importDecl));
-							}
-						}
-					}
-					return Status.OK_STATUS;
-				} catch (JavaModelException e) {
-					return new Status(IStatus.ERROR, SigilUI.PLUGIN_ID, 0, "Error finding imports", e);
-				}
-			}
-		};
-		findImportsJob.setUser(true);
-		findImportsJob.schedule();
-		
-		// Wait for both jobs to complete
-		try {
-			findImportsJob.join();
-			findExportsJob.join();
-		} catch (InterruptedException e) {
-			// Aborted, just do nothing
-			return;
-		}
-		
-		// Get the version rules
-		IPreferenceStore prefStore = SigilCore.getDefault().getPreferenceStore();
-		VersionRangeBoundingRule lowerBoundRule = VersionRangeBoundingRule.valueOf(prefStore.getString(SigilCore.DEFAULT_VERSION_LOWER_BOUND));
-		VersionRangeBoundingRule upperBoundRule = VersionRangeBoundingRule.valueOf(prefStore.getString(SigilCore.DEFAULT_VERSION_UPPER_BOUND));
-		
-		// Get the existing imports for the bundle
-		IBundleModelElement bundleInfo = getProjectModel().getBundle().getBundleInfo();
-		Set<IPackageImport> existingImports = bundleInfo.getImports();
-		Map<String, IPackageImport> existingImportsMap = new HashMap<String, IPackageImport>();
-		for (IPackageImport existingImport : existingImports) {
-			existingImportsMap.put(existingImport.getPackageName(), existingImport);
-		}
-		
-		// Add imports to the bundle
-		ModelElementFactory elementFactory = ModelElementFactory.getInstance();
-		int count = 0;
-		for (String pkgImport : imports) {
-			IPackageExport export = exports.get(pkgImport);
-			if(export != null && !existingImportsMap.containsKey(pkgImport)) {
-				VersionRange versionRange = VersionRange.newInstance(export.getVersion(), lowerBoundRule, upperBoundRule);
-				IPackageImport newImport = elementFactory.newModelElement(IPackageImport.class);
-				newImport.setPackageName(pkgImport);
-				newImport.setVersions(versionRange);
-				newImport.setOptional(false);
-				
-				bundleInfo.addImport(newImport);
-				count++;
-			}
-		}
-		
-		// Remove required bundles
-		Set<IRequiredBundle> requiredBundles = bundleInfo.getRequiredBundles();
-		int requiredBundlesSize = requiredBundles.size();
-		for (IRequiredBundle requiredBundle : requiredBundles) {
-			bundleInfo.removeRequiredBundle(requiredBundle);
-		}
 
-		// Update the editor
-		if(count + requiredBundlesSize > 0) {
-			IFormPart[] parts = getPage().getManagedForm().getParts();
-			for (IFormPart formPart : parts) {
-				formPart.refresh();
-				((AbstractFormPart) formPart).markDirty();
-			}
-		}
-		
-		MessageDialog.openInformation(getManagedForm().getForm().getShell(), "Dependency Management", "Removed " + requiredBundlesSize + " required bundle(s) and added " + count + " imported package(s).");
-	}
-	
-	private static String getPackageName(IImportDeclaration decl) {
-		String name = decl.getElementName();
-		int lastDot = name.lastIndexOf('.');
-		return name.substring(0, lastDot);
-	}
+    public DependencyManagementSection( SigilPage page, Composite parent, ISigilProjectModel project )
+        throws CoreException
+    {
+        super( page, parent, project );
+    }
+
+
+    protected void createSection( Section section, FormToolkit toolkit ) throws CoreException
+    {
+        setTitle( "Dependency Management" );
+
+        Composite body = createGridBody( 1, false, toolkit );
+
+        hypConvertRBtoIP = toolkit.createHyperlink( body, "Convert Required Bundles to Imported Packages", SWT.NONE );
+        hypConvertRBtoIP.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+
+        hypConvertRBtoIP.addHyperlinkListener( new HyperlinkAdapter()
+        {
+            public void linkActivated( HyperlinkEvent e )
+            {
+                run();
+            }
+        } );
+    }
+
+
+    protected void run()
+    {
+        final Map<String, IPackageExport> exports = new HashMap<String, IPackageExport>();
+        final Set<String> imports = new HashSet<String>();
+
+        // Find all exports
+        final ExportedPackageFinder exportFinder = new ExportedPackageFinder( getProjectModel(),
+            new AccumulatorAdapter<IPackageExport>()
+            {
+                public void addElements( Collection<? extends IPackageExport> elements )
+                {
+                    for ( IPackageExport export : elements )
+                    {
+                        exports.put( export.getPackageName(), export );
+                    }
+                }
+            } );
+        Job findExportsJob = new Job( "Find exports" )
+        {
+            protected IStatus run( IProgressMonitor monitor )
+            {
+                return exportFinder.run( monitor );
+            }
+        };
+        findExportsJob.setUser( true );
+        findExportsJob.schedule();
+
+        // Find imports from Java source
+        Job findImportsJob = new Job( "Find imports" )
+        {
+            protected IStatus run( IProgressMonitor monitor )
+            {
+                IJavaProject javaProject = getProjectModel().getJavaModel();
+                try
+                {
+                    IPackageFragment[] packages = javaProject.getPackageFragments();
+                    for ( IPackageFragment pkg : packages )
+                    {
+                        ICompilationUnit[] compilationUnits = pkg.getCompilationUnits();
+                        for ( ICompilationUnit compilationUnit : compilationUnits )
+                        {
+                            IImportDeclaration[] importDecls = compilationUnit.getImports();
+                            for ( IImportDeclaration importDecl : importDecls )
+                            {
+                                imports.add( getPackageName( importDecl ) );
+                            }
+                        }
+                    }
+                    return Status.OK_STATUS;
+                }
+                catch ( JavaModelException e )
+                {
+                    return new Status( IStatus.ERROR, SigilUI.PLUGIN_ID, 0, "Error finding imports", e );
+                }
+            }
+        };
+        findImportsJob.setUser( true );
+        findImportsJob.schedule();
+
+        // Wait for both jobs to complete
+        try
+        {
+            findImportsJob.join();
+            findExportsJob.join();
+        }
+        catch ( InterruptedException e )
+        {
+            // Aborted, just do nothing
+            return;
+        }
+
+        // Get the version rules
+        IPreferenceStore prefStore = SigilCore.getDefault().getPreferenceStore();
+        VersionRangeBoundingRule lowerBoundRule = VersionRangeBoundingRule.valueOf( prefStore
+            .getString( SigilCore.DEFAULT_VERSION_LOWER_BOUND ) );
+        VersionRangeBoundingRule upperBoundRule = VersionRangeBoundingRule.valueOf( prefStore
+            .getString( SigilCore.DEFAULT_VERSION_UPPER_BOUND ) );
+
+        // Get the existing imports for the bundle
+        IBundleModelElement bundleInfo = getProjectModel().getBundle().getBundleInfo();
+        Set<IPackageImport> existingImports = bundleInfo.getImports();
+        Map<String, IPackageImport> existingImportsMap = new HashMap<String, IPackageImport>();
+        for ( IPackageImport existingImport : existingImports )
+        {
+            existingImportsMap.put( existingImport.getPackageName(), existingImport );
+        }
+
+        // Add imports to the bundle
+        ModelElementFactory elementFactory = ModelElementFactory.getInstance();
+        int count = 0;
+        for ( String pkgImport : imports )
+        {
+            IPackageExport export = exports.get( pkgImport );
+            if ( export != null && !existingImportsMap.containsKey( pkgImport ) )
+            {
+                VersionRange versionRange = VersionRange.newInstance( export.getVersion(), lowerBoundRule,
+                    upperBoundRule );
+                IPackageImport newImport = elementFactory.newModelElement( IPackageImport.class );
+                newImport.setPackageName( pkgImport );
+                newImport.setVersions( versionRange );
+                newImport.setOptional( false );
+
+                bundleInfo.addImport( newImport );
+                count++;
+            }
+        }
+
+        // Remove required bundles
+        Set<IRequiredBundle> requiredBundles = bundleInfo.getRequiredBundles();
+        int requiredBundlesSize = requiredBundles.size();
+        for ( IRequiredBundle requiredBundle : requiredBundles )
+        {
+            bundleInfo.removeRequiredBundle( requiredBundle );
+        }
+
+        // Update the editor
+        if ( count + requiredBundlesSize > 0 )
+        {
+            IFormPart[] parts = getPage().getManagedForm().getParts();
+            for ( IFormPart formPart : parts )
+            {
+                formPart.refresh();
+                ( ( AbstractFormPart ) formPart ).markDirty();
+            }
+        }
+
+        MessageDialog.openInformation( getManagedForm().getForm().getShell(), "Dependency Management", "Removed "
+            + requiredBundlesSize + " required bundle(s) and added " + count + " imported package(s)." );
+    }
+
+
+    private static String getPackageName( IImportDeclaration decl )
+    {
+        String name = decl.getElementName();
+        int lastDot = name.lastIndexOf( '.' );
+        return name.substring( 0, lastDot );
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DownloadSection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DownloadSection.java
index 0de878b..1cf045c 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DownloadSection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/DownloadSection.java
@@ -20,8 +20,6 @@
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
 
-
-
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.apache.felix.sigil.model.ModelElementFactory;
@@ -41,100 +39,124 @@
 import org.eclipse.ui.forms.widgets.Section;
 import org.eclipse.ui.forms.widgets.TableWrapData;
 
+
 /**
  * @author dave
  *
  */
-public class DownloadSection extends AbstractResourceSection {
+public class DownloadSection extends AbstractResourceSection
+{
 
-	/**
-	 * @param page
-	 * @param parent
-	 * @param project
-	 * @throws CoreException 
-	 */
-	
-	private IDownloadJar dl;
-	
-	public DownloadSection(SigilPage page, Composite parent, ISigilProjectModel project) throws CoreException {
-		super( page, parent, project );
-	}
+    /**
+     * @param page
+     * @param parent
+     * @param project
+     * @throws CoreException 
+     */
 
-	@Override
-	protected void createSection(Section section, FormToolkit toolkit) throws CoreException {
-		setTitle( "Codebase" );
-		
-		Composite body = createTableWrapBody(1, toolkit);
+    private IDownloadJar dl;
+
+
+    public DownloadSection( SigilPage page, Composite parent, ISigilProjectModel project ) throws CoreException
+    {
+        super( page, parent, project );
+    }
+
+
+    @Override
+    protected void createSection( Section section, FormToolkit toolkit ) throws CoreException
+    {
+        setTitle( "Codebase" );
+
+        Composite body = createTableWrapBody( 1, toolkit );
 
         toolkit.createLabel( body, "Specify which resources are included as part of this bundles remote codebase." );
-		
-		tree = toolkit.createTree( body, SWT.CHECK | SWT.BORDER );
-		
-		TableWrapData data = new TableWrapData( TableWrapData.FILL_GRAB);
-		data.heightHint = 200;
-		tree.setLayoutData( data );
-		
-		viewer = new CheckboxTreeViewer( tree );
-		IFolder base = ResourcesPlugin.getWorkspace().getRoot().getFolder(getProjectModel().getJavaModel().getOutputLocation());
-		viewer.setContentProvider( new ContainerTreeProvider() );
-		viewer.setLabelProvider( new ModelLabelProvider() );
-		viewer.addCheckStateListener( this );
-		viewer.setInput( base );
-		
-		dl = getProjectModel().getBundle().getDownloadJar();
-		
-		startWorkspaceListener(base.getWorkspace());
-	}
 
-	@Override
-	public void refresh() {
-		dl = getProjectModel().getBundle().getDownloadJar();
-		super.refresh();
-	}
+        tree = toolkit.createTree( body, SWT.CHECK | SWT.BORDER );
 
-	@Override
-	public void commit(boolean onSave) {
-		getProjectModel().getBundle().setDownloadJar(dl);			
-		super.commit(onSave);
-	}
+        TableWrapData data = new TableWrapData( TableWrapData.FILL_GRAB );
+        data.heightHint = 200;
+        tree.setLayoutData( data );
 
-	@Override
-	protected void refreshSelections() {
-		// zero the state
-		if ( dl != null ) {
-			for ( IPath path : dl.getEntrys() ) {
-				IResource r = findResource( path );
-				if ( r != null ) {
-					viewer.expandToLevel(r, 0);
-					viewer.setChecked( r, true );
-					viewer.setGrayed( r, false );
-					handleStateChanged(r, true, false, false);
-				}
-				else {
-					SigilCore.error( "Unknown path " + path );
-				}
-			}
-		}
-	}	
-	
-	protected void syncResourceModel(IResource element, boolean checked) {
-		try {
-			if ( dl == null ) {
-				dl = ModelElementFactory.getInstance().newModelElement(IDownloadJar.class);
-				getProjectModel().getBundle().setDownloadJar(dl);
-			}
-			
-			if ( checked ) {
-				dl.addEntry( element.getProjectRelativePath() );
-			}
-			else {
-				dl.removeEntry( element.getProjectRelativePath() );
-			}
-			
-			markDirty();
-		}
-		catch (ModelElementFactoryException e) {
-			SigilCore.error( "Failed to create model element", e );
-		}
-	}	
+        viewer = new CheckboxTreeViewer( tree );
+        IFolder base = ResourcesPlugin.getWorkspace().getRoot().getFolder(
+            getProjectModel().getJavaModel().getOutputLocation() );
+        viewer.setContentProvider( new ContainerTreeProvider() );
+        viewer.setLabelProvider( new ModelLabelProvider() );
+        viewer.addCheckStateListener( this );
+        viewer.setInput( base );
+
+        dl = getProjectModel().getBundle().getDownloadJar();
+
+        startWorkspaceListener( base.getWorkspace() );
+    }
+
+
+    @Override
+    public void refresh()
+    {
+        dl = getProjectModel().getBundle().getDownloadJar();
+        super.refresh();
+    }
+
+
+    @Override
+    public void commit( boolean onSave )
+    {
+        getProjectModel().getBundle().setDownloadJar( dl );
+        super.commit( onSave );
+    }
+
+
+    @Override
+    protected void refreshSelections()
+    {
+        // zero the state
+        if ( dl != null )
+        {
+            for ( IPath path : dl.getEntrys() )
+            {
+                IResource r = findResource( path );
+                if ( r != null )
+                {
+                    viewer.expandToLevel( r, 0 );
+                    viewer.setChecked( r, true );
+                    viewer.setGrayed( r, false );
+                    handleStateChanged( r, true, false, false );
+                }
+                else
+                {
+                    SigilCore.error( "Unknown path " + path );
+                }
+            }
+        }
+    }
+
+
+    protected void syncResourceModel( IResource element, boolean checked )
+    {
+        try
+        {
+            if ( dl == null )
+            {
+                dl = ModelElementFactory.getInstance().newModelElement( IDownloadJar.class );
+                getProjectModel().getBundle().setDownloadJar( dl );
+            }
+
+            if ( checked )
+            {
+                dl.addEntry( element.getProjectRelativePath() );
+            }
+            else
+            {
+                dl.removeEntry( element.getProjectRelativePath() );
+            }
+
+            markDirty();
+        }
+        catch ( ModelElementFactoryException e )
+        {
+            SigilCore.error( "Failed to create model element", e );
+        }
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ExcludedResourcesFilter.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ExcludedResourcesFilter.java
index 87db86d..6ebc650 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ExcludedResourcesFilter.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ExcludedResourcesFilter.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import java.util.HashSet;
 import java.util.Set;
 import java.util.regex.Pattern;
@@ -31,33 +32,44 @@
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerFilter;
 
-public class ExcludedResourcesFilter extends ViewerFilter {
 
-	private final Set<Pattern> exclusionSet = new HashSet<Pattern>();
-	
-	public ExcludedResourcesFilter() {
-		loadExclusions();
-	}
+public class ExcludedResourcesFilter extends ViewerFilter
+{
 
-	public final synchronized void loadExclusions() {
-		exclusionSet.clear();
-		IPreferenceStore store = SigilCore.getDefault().getPreferenceStore();
-		String[] exclusions = PrefsUtils.stringToArray(store.getString(SigilCore.DEFAULT_EXCLUDED_RESOURCES));
-		for (String exclusion : exclusions) {
-			exclusionSet.add(GlobCompiler.compile(exclusion));
-		}
-	}
+    private final Set<Pattern> exclusionSet = new HashSet<Pattern>();
 
-	@Override
-	public synchronized boolean select(Viewer viewer, Object parentElement, Object element) {
-		IResource file = (IResource) element;
-		String path = file.getName();
-		for ( Pattern p :exclusionSet ) {
-			if ( p.matcher(path).matches() ) {
-				return false;
-			}
-		}
-		return true;
-	}
+
+    public ExcludedResourcesFilter()
+    {
+        loadExclusions();
+    }
+
+
+    public final synchronized void loadExclusions()
+    {
+        exclusionSet.clear();
+        IPreferenceStore store = SigilCore.getDefault().getPreferenceStore();
+        String[] exclusions = PrefsUtils.stringToArray( store.getString( SigilCore.DEFAULT_EXCLUDED_RESOURCES ) );
+        for ( String exclusion : exclusions )
+        {
+            exclusionSet.add( GlobCompiler.compile( exclusion ) );
+        }
+    }
+
+
+    @Override
+    public synchronized boolean select( Viewer viewer, Object parentElement, Object element )
+    {
+        IResource file = ( IResource ) element;
+        String path = file.getName();
+        for ( Pattern p : exclusionSet )
+        {
+            if ( p.matcher( path ).matches() )
+            {
+                return false;
+            }
+        }
+        return true;
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ExportPackagesSection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ExportPackagesSection.java
index 92d141c..8754d06 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ExportPackagesSection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ExportPackagesSection.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import java.util.Iterator;
 import java.util.List;
 
@@ -46,131 +47,173 @@
 import org.eclipse.ui.forms.widgets.FormToolkit;
 import org.osgi.framework.Version;
 
-public class ExportPackagesSection extends BundleDependencySection {
 
-	public ExportPackagesSection(SigilPage page, Composite parent, ISigilProjectModel project) throws CoreException {
-		super( page, parent, project );
-	}
-		
-	@Override
-	protected String getTitle() {
-		return "Export Packages";
-	}
+public class ExportPackagesSection extends BundleDependencySection
+{
 
-	@Override
-	protected Label createLabel(Composite parent, FormToolkit toolkit) {
-		return toolkit.createLabel( parent, "Specify which packages this bundle shares with other bundles." );
-	}
+    public ExportPackagesSection( SigilPage page, Composite parent, ISigilProjectModel project ) throws CoreException
+    {
+        super( page, parent, project );
+    }
 
-	@Override
-	protected IContentProvider getContentProvider() {
-        return new DefaultTableProvider() {
-			public Object[] getElements(Object inputElement) {
-				return getBundle().getBundleInfo().getExports().toArray();
-			}
-	    };
-	}
 
-	@Override
-	protected void handleAdd() {
-		NewPackageExportDialog dialog = ResourcesDialogHelper.createNewExportDialog(getSection().getShell(), "Add Exported Package", null, getProjectModel(), true);
+    @Override
+    protected String getTitle()
+    {
+        return "Export Packages";
+    }
 
-		if ( dialog.open() == Window.OK ) {
-			try {
-				// Add selected exports
-				boolean exportsAdded = false;
-				
-				List<IPackageFragment> newPkgFragments = dialog.getSelectedElements();
-				for (IPackageFragment pkgFragment : newPkgFragments) {
-					IPackageExport pkgExport = ModelElementFactory.getInstance().newModelElement(IPackageExport.class);
-					pkgExport.setPackageName(pkgFragment.getElementName());
-					pkgExport.setVersion(dialog.getVersion());
-					getBundle().getBundleInfo().addExport(pkgExport);
-					
-					exportsAdded = true;
-				}
 
-				// Add corresponding imports (maybe)
-				boolean importsAdded = false;
-				
-				IPreferenceStore store = SigilCore.getDefault().getPreferenceStore();
-				boolean shouldAddImports = OptionalPrompt.optionallyPrompt(store, SigilCore.PREFERENCES_ADD_IMPORT_FOR_EXPORT, "Add Exports", "Should corresponding imports be added?", getSection().getShell());
-				if(shouldAddImports) {
-					for (IPackageFragment pkgFragment : newPkgFragments) {
-						IPackageImport pkgImport = ModelElementFactory.getInstance().newModelElement(IPackageImport.class);
-						pkgImport.setPackageName(pkgFragment.getElementName());
-						VersionRangeBoundingRule lowerBound = VersionRangeBoundingRule.valueOf(store.getString(SigilCore.DEFAULT_VERSION_LOWER_BOUND));
-						VersionRangeBoundingRule upperBound = VersionRangeBoundingRule.valueOf(store.getString(SigilCore.DEFAULT_VERSION_UPPER_BOUND));
-						Version version = dialog.getVersion();
-						if(version == null) {
-							version = getBundle().getVersion();
-						}
-						VersionRange versionRange = VersionRange.newInstance(version, lowerBound, upperBound);
-						pkgImport.setVersions(versionRange);
-						
-						getBundle().getBundleInfo().addImport(pkgImport);
-						
-						importsAdded = true;
-					}
-				}
-				
-				if(importsAdded) {
-					((SigilProjectEditorPart) getPage().getEditor()).refreshAllPages();
-					markDirty();
-				} else if(exportsAdded) {
-					refresh();
-					markDirty();
-				}
-			}
-			catch (ModelElementFactoryException e) {
-				SigilCore.error( "Failed to buiild model element for package export", e);
-			}
-		}
-	}
+    @Override
+    protected Label createLabel( Composite parent, FormToolkit toolkit )
+    {
+        return toolkit.createLabel( parent, "Specify which packages this bundle shares with other bundles." );
+    }
 
-	@SuppressWarnings("unchecked")
-	@Override
-	protected void handleEdit() {
-		IStructuredSelection selection = (IStructuredSelection) getSelection();
-		
-		boolean changed = false;
-		
-		if ( !selection.isEmpty() ) {
-			for ( Iterator<IPackageExport> i = selection.iterator(); i.hasNext(); ) {	
-				IPackageExport packageExport = i.next();
-				NewPackageExportDialog dialog = ResourcesDialogHelper.createNewExportDialog(getSection().getShell(), "Edit Imported Package", packageExport, getProjectModel(), false);
-				if ( dialog.open() == Window.OK ) {
-					changed = true;
-					IPackageFragment pkgFragment = dialog.getSelectedElement();
-					packageExport.setPackageName(pkgFragment.getElementName());
-					packageExport.setVersion(dialog.getVersion());
-				}
-			}
-		}
-		
-		if ( changed ) {
-			refresh();
-			markDirty();
-		}
-	}
 
-	@SuppressWarnings("unchecked") 
-	@Override
-	protected void handleRemoved() {
-		IStructuredSelection selection = (IStructuredSelection) getSelection();
+    @Override
+    protected IContentProvider getContentProvider()
+    {
+        return new DefaultTableProvider()
+        {
+            public Object[] getElements( Object inputElement )
+            {
+                return getBundle().getBundleInfo().getExports().toArray();
+            }
+        };
+    }
 
-		if ( !selection.isEmpty() ) {
-			for ( Iterator<IPackageExport> i = selection.iterator(); i.hasNext(); ) {			
-				getBundle().getBundleInfo().removeExport( i.next() );
-			}		
-			
-			refresh();
-			markDirty();
-		}
-	}
-		
-	private ISigilBundle getBundle() {
-		return getProjectModel().getBundle();
-	}
+
+    @Override
+    protected void handleAdd()
+    {
+        NewPackageExportDialog dialog = ResourcesDialogHelper.createNewExportDialog( getSection().getShell(),
+            "Add Exported Package", null, getProjectModel(), true );
+
+        if ( dialog.open() == Window.OK )
+        {
+            try
+            {
+                // Add selected exports
+                boolean exportsAdded = false;
+
+                List<IPackageFragment> newPkgFragments = dialog.getSelectedElements();
+                for ( IPackageFragment pkgFragment : newPkgFragments )
+                {
+                    IPackageExport pkgExport = ModelElementFactory.getInstance().newModelElement( IPackageExport.class );
+                    pkgExport.setPackageName( pkgFragment.getElementName() );
+                    pkgExport.setVersion( dialog.getVersion() );
+                    getBundle().getBundleInfo().addExport( pkgExport );
+
+                    exportsAdded = true;
+                }
+
+                // Add corresponding imports (maybe)
+                boolean importsAdded = false;
+
+                IPreferenceStore store = SigilCore.getDefault().getPreferenceStore();
+                boolean shouldAddImports = OptionalPrompt.optionallyPrompt( store,
+                    SigilCore.PREFERENCES_ADD_IMPORT_FOR_EXPORT, "Add Exports",
+                    "Should corresponding imports be added?", getSection().getShell() );
+                if ( shouldAddImports )
+                {
+                    for ( IPackageFragment pkgFragment : newPkgFragments )
+                    {
+                        IPackageImport pkgImport = ModelElementFactory.getInstance().newModelElement(
+                            IPackageImport.class );
+                        pkgImport.setPackageName( pkgFragment.getElementName() );
+                        VersionRangeBoundingRule lowerBound = VersionRangeBoundingRule.valueOf( store
+                            .getString( SigilCore.DEFAULT_VERSION_LOWER_BOUND ) );
+                        VersionRangeBoundingRule upperBound = VersionRangeBoundingRule.valueOf( store
+                            .getString( SigilCore.DEFAULT_VERSION_UPPER_BOUND ) );
+                        Version version = dialog.getVersion();
+                        if ( version == null )
+                        {
+                            version = getBundle().getVersion();
+                        }
+                        VersionRange versionRange = VersionRange.newInstance( version, lowerBound, upperBound );
+                        pkgImport.setVersions( versionRange );
+
+                        getBundle().getBundleInfo().addImport( pkgImport );
+
+                        importsAdded = true;
+                    }
+                }
+
+                if ( importsAdded )
+                {
+                    ( ( SigilProjectEditorPart ) getPage().getEditor() ).refreshAllPages();
+                    markDirty();
+                }
+                else if ( exportsAdded )
+                {
+                    refresh();
+                    markDirty();
+                }
+            }
+            catch ( ModelElementFactoryException e )
+            {
+                SigilCore.error( "Failed to buiild model element for package export", e );
+            }
+        }
+    }
+
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected void handleEdit()
+    {
+        IStructuredSelection selection = ( IStructuredSelection ) getSelection();
+
+        boolean changed = false;
+
+        if ( !selection.isEmpty() )
+        {
+            for ( Iterator<IPackageExport> i = selection.iterator(); i.hasNext(); )
+            {
+                IPackageExport packageExport = i.next();
+                NewPackageExportDialog dialog = ResourcesDialogHelper.createNewExportDialog( getSection().getShell(),
+                    "Edit Imported Package", packageExport, getProjectModel(), false );
+                if ( dialog.open() == Window.OK )
+                {
+                    changed = true;
+                    IPackageFragment pkgFragment = dialog.getSelectedElement();
+                    packageExport.setPackageName( pkgFragment.getElementName() );
+                    packageExport.setVersion( dialog.getVersion() );
+                }
+            }
+        }
+
+        if ( changed )
+        {
+            refresh();
+            markDirty();
+        }
+    }
+
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected void handleRemoved()
+    {
+        IStructuredSelection selection = ( IStructuredSelection ) getSelection();
+
+        if ( !selection.isEmpty() )
+        {
+            for ( Iterator<IPackageExport> i = selection.iterator(); i.hasNext(); )
+            {
+                getBundle().getBundleInfo().removeExport( i.next() );
+            }
+
+            refresh();
+            markDirty();
+        }
+    }
+
+
+    private ISigilBundle getBundle()
+    {
+        return getProjectModel().getBundle();
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ExportsForm.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ExportsForm.java
index 0ef1d7f..3d200c8 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ExportsForm.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ExportsForm.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.apache.felix.sigil.ui.eclipse.ui.form.SigilPage;
@@ -30,23 +31,29 @@
 import org.eclipse.ui.forms.widgets.TableWrapData;
 import org.eclipse.ui.forms.widgets.TableWrapLayout;
 
-public class ExportsForm extends SigilPage  {
 
-	public static final String PAGE_ID = "exports";
-	
-	private ISigilProjectModel project;
-	
-	public ExportsForm(FormEditor editor, ISigilProjectModel project) {
-		super(editor, PAGE_ID, "Exports");
-		this.project = project;
-	}
-	
+public class ExportsForm extends SigilPage
+{
+
+    public static final String PAGE_ID = "exports";
+
+    private ISigilProjectModel project;
+
+
+    public ExportsForm( FormEditor editor, ISigilProjectModel project )
+    {
+        super( editor, PAGE_ID, "Exports" );
+        this.project = project;
+    }
+
+
     @Override
-    protected void createFormContent(IManagedForm managedForm) {
+    protected void createFormContent( IManagedForm managedForm )
+    {
         ScrolledForm form = managedForm.getForm();
         form.setText( "Exports" );
-        
-        Composite body = form.getBody();        
+
+        Composite body = form.getBody();
         TableWrapLayout layout = new TableWrapLayout();
         layout.bottomMargin = 10;
         layout.topMargin = 5;
@@ -55,15 +62,17 @@
         layout.numColumns = 1;
         layout.horizontalSpacing = 10;
         layout.verticalSpacing = 20;
-        body.setLayout(layout);
-        body.setLayoutData(new TableWrapData(TableWrapData.FILL));
-                       
-        try {
-	        ExportPackagesSection exportPackages = new ExportPackagesSection( this, body, project );
-	        managedForm.addPart( exportPackages );
+        body.setLayout( layout );
+        body.setLayoutData( new TableWrapData( TableWrapData.FILL ) );
+
+        try
+        {
+            ExportPackagesSection exportPackages = new ExportPackagesSection( this, body, project );
+            managedForm.addPart( exportPackages );
         }
-        catch (CoreException e) {
-        	SigilCore.error( "Failed to create contents form", e);
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Failed to create contents form", e );
         }
     }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/GeneralInfoSection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/GeneralInfoSection.java
index 916f95c..8cb74e1 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/GeneralInfoSection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/GeneralInfoSection.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.apache.felix.sigil.model.ModelElementFactory;
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
@@ -43,180 +44,227 @@
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.Version;
 
+
 /**
  * @author dave
  *
  */
-public class GeneralInfoSection extends SigilSection {
+public class GeneralInfoSection extends SigilSection
+{
 
-	private String name;
-	private String symbolicName;
+    private String name;
+    private String symbolicName;
     private Version version;
     private String description;
     private String provider;
     private String activator;
     private IRequiredBundle fragmentHost;
-    
+
     private SigilFormEntry nameEntry;
-	private SigilFormEntry symbolicNameEntry;
+    private SigilFormEntry symbolicNameEntry;
     private SigilFormEntry versionEntry;
     private SigilFormEntry descriptionEntry;
     private SigilFormEntry providerEntry;
     private SigilFormEntry activatorEntry;
     private SigilFormEntry fragmentHostEntry;
-    
+
+
     /**
      * @param parent
      * @param toolkit
      * @param style
      * @throws CoreException 
      */
-    public GeneralInfoSection(SigilPage page, Composite parent, ISigilProjectModel project) throws CoreException {
-		super( page, parent, project );
-	}    
-
-    protected void createSection(Section section,FormToolkit toolkit ) {
-        setTitle("General Information");
-                
-		Composite body = createGridBody(3, false, toolkit);
-        
-        Label label = toolkit.createLabel( body, "This section describes general information about this project." );
-        label.setLayoutData( new GridData(SWT.LEFT, SWT.CENTER, true, false, 3, 1) );
-       
-        symbolicNameEntry = new SigilFormEntry(body, toolkit, "Symbolic Name");
-        symbolicNameEntry.setFormEntryListener( new SigilFormEntryAdapter() {
-			@Override
-			public void textValueChanged(SigilFormEntry form) {
-				symbolicName = nullIfEmpty((String) form.getValue());
-				checkDirty();
-			}
-        });
-        
-        nameEntry = new SigilFormEntry(body, toolkit, "Name");
-        nameEntry.setFormEntryListener( new SigilFormEntryAdapter() {
-			@Override
-			public void textValueChanged(SigilFormEntry form) {
-				name = nullIfEmpty((String) form.getValue());
-				checkDirty();
-			}
-        });
-        
-        descriptionEntry = new SigilFormEntry(body, toolkit, "Description");
-        descriptionEntry.setFormEntryListener( new SigilFormEntryAdapter() {
-			@Override
-			public void textValueChanged(SigilFormEntry form) {
-				description = nullIfEmpty((String) form.getValue());
-				checkDirty();
-			}
-        });
-        
-        IFormValueConverter converter = new IFormValueConverter() {
-			public String getLabel(Object value) {
-				Version v = (Version) value;
-				return v.toString();
-			}
-
-			public Object getValue(String label) {
-				return Version.parseVersion(label);
-			}        	
-        };
-        
-        versionEntry = new SigilFormEntry(body, toolkit, "Version", null, converter);
-        versionEntry.setFormEntryListener( new SigilFormEntryAdapter() {
-			@Override
-			public void textValueChanged(SigilFormEntry form) {
-				version = (Version) form.getValue();
-				checkDirty();
-			}
-        });
-        
-        providerEntry = new SigilFormEntry(body, toolkit, "Provider");
-        providerEntry.setFormEntryListener( new SigilFormEntryAdapter() {
-			@Override
-			public void textValueChanged(SigilFormEntry form) {
-				provider = nullIfEmpty((String) form.getValue());
-				checkDirty();
-			}
-        });
-
-		activatorEntry = new SigilFormEntry(body, toolkit, "Bundle Activator", "Browse...", null);
-		activatorEntry.setFormEntryListener( new SigilFormEntryAdapter() {
-			@Override
-			public void textValueChanged(SigilFormEntry form) {
-				activator = (String) form.getValue();
-				checkDirty();
-			}
-
-			@Override
-			public void browseButtonSelected(SigilFormEntry form) {
-				BackgroundLoadingSelectionDialog<String> dialog = ResourcesDialogHelper.createClassSelectDialog(getShell(), "Add Bundle Activator", getProjectModel(), activator, BundleActivator.class.getName());
-				
-				if (dialog.open() == Window.OK) {
-					form.setValue(dialog.getSelectedElement());
-				}				
-			}			
-		});
-		
-		converter = new IFormValueConverter() {
-			public String getLabel(Object value) {
-				IRequiredBundle b = (IRequiredBundle) value;
-				return b == null ? null : b.getSymbolicName() + " " + b.getVersions();
-			}
-
-			public Object getValue(String label) {
-				return null;
-			}			
-		};
-		
-		fragmentHostEntry = new SigilFormEntry(body, toolkit, "Fragment Host", "Browse...", converter );
-		fragmentHostEntry.setFormEntryListener( new SigilFormEntryAdapter() {
-			@Override
-			public void textValueChanged(SigilFormEntry form) {
-				fragmentHost = (IRequiredBundle) form.getValue();
-				checkDirty();
-			}
-
-			@Override
-			public void browseButtonSelected(SigilFormEntry form) {
-				NewResourceSelectionDialog<IBundleModelElement> dialog = ResourcesDialogHelper.createRequiredBundleDialog( getSection().getShell(), "Add Required Bundle", getProjectModel(), null, getBundle().getBundleInfo().getRequiredBundles() );
-				
-				if (dialog.open() == Window.OK) {
-					IRequiredBundle required = ModelElementFactory.getInstance().newModelElement( IRequiredBundle.class );
-					required.setSymbolicName(dialog.getSelectedName());
-					required.setVersions(dialog.getSelectedVersions());				
-					form.setValue(required);
-				}				
-			}			
-		});
-		fragmentHostEntry.setFreeText(false);
+    public GeneralInfoSection( SigilPage page, Composite parent, ISigilProjectModel project ) throws CoreException
+    {
+        super( page, parent, project );
     }
-    
-	private static String nullIfEmpty(String value) {
-		if ( value.trim().length() == 0 ) {
-			return null;
-		}
-		return value;
-	}
-	
-	private Shell getShell() {
-		return getSection().getShell();
-	}
 
-	@Override
-	public void commit(boolean onSave) {
-		getBundle().getBundleInfo().setSymbolicName( symbolicName );
-		getBundle().getBundleInfo().setName( name );
-		getBundle().getBundleInfo().setVersion( version );
-		getBundle().getBundleInfo().setDescription( description );
-		getBundle().getBundleInfo().setVendor( provider );
-		getBundle().getBundleInfo().setFragmentHost(fragmentHost);
-		getBundle().getBundleInfo().setActivator(activator);
-		
-		super.commit(onSave);
-	}
 
-	@Override
-	public void refresh() {
+    protected void createSection( Section section, FormToolkit toolkit )
+    {
+        setTitle( "General Information" );
+
+        Composite body = createGridBody( 3, false, toolkit );
+
+        Label label = toolkit.createLabel( body, "This section describes general information about this project." );
+        label.setLayoutData( new GridData( SWT.LEFT, SWT.CENTER, true, false, 3, 1 ) );
+
+        symbolicNameEntry = new SigilFormEntry( body, toolkit, "Symbolic Name" );
+        symbolicNameEntry.setFormEntryListener( new SigilFormEntryAdapter()
+        {
+            @Override
+            public void textValueChanged( SigilFormEntry form )
+            {
+                symbolicName = nullIfEmpty( ( String ) form.getValue() );
+                checkDirty();
+            }
+        } );
+
+        nameEntry = new SigilFormEntry( body, toolkit, "Name" );
+        nameEntry.setFormEntryListener( new SigilFormEntryAdapter()
+        {
+            @Override
+            public void textValueChanged( SigilFormEntry form )
+            {
+                name = nullIfEmpty( ( String ) form.getValue() );
+                checkDirty();
+            }
+        } );
+
+        descriptionEntry = new SigilFormEntry( body, toolkit, "Description" );
+        descriptionEntry.setFormEntryListener( new SigilFormEntryAdapter()
+        {
+            @Override
+            public void textValueChanged( SigilFormEntry form )
+            {
+                description = nullIfEmpty( ( String ) form.getValue() );
+                checkDirty();
+            }
+        } );
+
+        IFormValueConverter converter = new IFormValueConverter()
+        {
+            public String getLabel( Object value )
+            {
+                Version v = ( Version ) value;
+                return v.toString();
+            }
+
+
+            public Object getValue( String label )
+            {
+                return Version.parseVersion( label );
+            }
+        };
+
+        versionEntry = new SigilFormEntry( body, toolkit, "Version", null, converter );
+        versionEntry.setFormEntryListener( new SigilFormEntryAdapter()
+        {
+            @Override
+            public void textValueChanged( SigilFormEntry form )
+            {
+                version = ( Version ) form.getValue();
+                checkDirty();
+            }
+        } );
+
+        providerEntry = new SigilFormEntry( body, toolkit, "Provider" );
+        providerEntry.setFormEntryListener( new SigilFormEntryAdapter()
+        {
+            @Override
+            public void textValueChanged( SigilFormEntry form )
+            {
+                provider = nullIfEmpty( ( String ) form.getValue() );
+                checkDirty();
+            }
+        } );
+
+        activatorEntry = new SigilFormEntry( body, toolkit, "Bundle Activator", "Browse...", null );
+        activatorEntry.setFormEntryListener( new SigilFormEntryAdapter()
+        {
+            @Override
+            public void textValueChanged( SigilFormEntry form )
+            {
+                activator = ( String ) form.getValue();
+                checkDirty();
+            }
+
+
+            @Override
+            public void browseButtonSelected( SigilFormEntry form )
+            {
+                BackgroundLoadingSelectionDialog<String> dialog = ResourcesDialogHelper.createClassSelectDialog(
+                    getShell(), "Add Bundle Activator", getProjectModel(), activator, BundleActivator.class.getName() );
+
+                if ( dialog.open() == Window.OK )
+                {
+                    form.setValue( dialog.getSelectedElement() );
+                }
+            }
+        } );
+
+        converter = new IFormValueConverter()
+        {
+            public String getLabel( Object value )
+            {
+                IRequiredBundle b = ( IRequiredBundle ) value;
+                return b == null ? null : b.getSymbolicName() + " " + b.getVersions();
+            }
+
+
+            public Object getValue( String label )
+            {
+                return null;
+            }
+        };
+
+        fragmentHostEntry = new SigilFormEntry( body, toolkit, "Fragment Host", "Browse...", converter );
+        fragmentHostEntry.setFormEntryListener( new SigilFormEntryAdapter()
+        {
+            @Override
+            public void textValueChanged( SigilFormEntry form )
+            {
+                fragmentHost = ( IRequiredBundle ) form.getValue();
+                checkDirty();
+            }
+
+
+            @Override
+            public void browseButtonSelected( SigilFormEntry form )
+            {
+                NewResourceSelectionDialog<IBundleModelElement> dialog = ResourcesDialogHelper
+                    .createRequiredBundleDialog( getSection().getShell(), "Add Required Bundle", getProjectModel(),
+                        null, getBundle().getBundleInfo().getRequiredBundles() );
+
+                if ( dialog.open() == Window.OK )
+                {
+                    IRequiredBundle required = ModelElementFactory.getInstance()
+                        .newModelElement( IRequiredBundle.class );
+                    required.setSymbolicName( dialog.getSelectedName() );
+                    required.setVersions( dialog.getSelectedVersions() );
+                    form.setValue( required );
+                }
+            }
+        } );
+        fragmentHostEntry.setFreeText( false );
+    }
+
+
+    private static String nullIfEmpty( String value )
+    {
+        if ( value.trim().length() == 0 )
+        {
+            return null;
+        }
+        return value;
+    }
+
+
+    private Shell getShell()
+    {
+        return getSection().getShell();
+    }
+
+
+    @Override
+    public void commit( boolean onSave )
+    {
+        getBundle().getBundleInfo().setSymbolicName( symbolicName );
+        getBundle().getBundleInfo().setName( name );
+        getBundle().getBundleInfo().setVersion( version );
+        getBundle().getBundleInfo().setDescription( description );
+        getBundle().getBundleInfo().setVendor( provider );
+        getBundle().getBundleInfo().setFragmentHost( fragmentHost );
+        getBundle().getBundleInfo().setActivator( activator );
+
+        super.commit( onSave );
+    }
+
+
+    @Override
+    public void refresh()
+    {
         symbolicName = getProjectModel().getBundle().getBundleInfo().getSymbolicName();
         name = getProjectModel().getBundle().getBundleInfo().getName();
         description = getProjectModel().getBundle().getBundleInfo().getDescription();
@@ -224,35 +272,42 @@
         provider = getProjectModel().getBundle().getBundleInfo().getVendor();
         fragmentHost = getProjectModel().getBundle().getBundleInfo().getFragmentHost();
         activator = getProjectModel().getBundle().getBundleInfo().getActivator();
-        
-        nameEntry.setValue(name);
-    	symbolicNameEntry.setValue(symbolicName);
-    	versionEntry.setValue(version);
-        descriptionEntry.setValue(description);
-        providerEntry.setValue(provider);
-        fragmentHostEntry.setValue(fragmentHost);
-        activatorEntry.setValue(activator);
-        
-		super.refresh();
-	}
 
-	private void checkDirty() {
-		boolean dirty = different(symbolicName, getProjectModel().getBundle().getBundleInfo().getSymbolicName() ) ||
-						different(name, getProjectModel().getBundle().getBundleInfo().getName() ) ||
-						different(version, getProjectModel().getBundle().getBundleInfo().getVersion() ) ||
-						different(description, getProjectModel().getBundle().getBundleInfo().getDescription()) ||
-						different(provider, getProjectModel().getBundle().getBundleInfo().getVendor()) ||
-						different(fragmentHost, getProjectModel().getBundle().getBundleInfo().getFragmentHost()) ||
-						different(activator, getProjectModel().getBundle().getBundleInfo().getActivator());
-				
-		if ( dirty ) markDirty();
-	}
-	
-	private boolean different(Object val1, Object val2) {
-		return val1 == null ? val2 != null : !val1.equals( val2 );
-	}
+        nameEntry.setValue( name );
+        symbolicNameEntry.setValue( symbolicName );
+        versionEntry.setValue( version );
+        descriptionEntry.setValue( description );
+        providerEntry.setValue( provider );
+        fragmentHostEntry.setValue( fragmentHost );
+        activatorEntry.setValue( activator );
 
-	private ISigilBundle getBundle() {
-		return getProjectModel().getBundle();
-	}
+        super.refresh();
+    }
+
+
+    private void checkDirty()
+    {
+        boolean dirty = different( symbolicName, getProjectModel().getBundle().getBundleInfo().getSymbolicName() )
+            || different( name, getProjectModel().getBundle().getBundleInfo().getName() )
+            || different( version, getProjectModel().getBundle().getBundleInfo().getVersion() )
+            || different( description, getProjectModel().getBundle().getBundleInfo().getDescription() )
+            || different( provider, getProjectModel().getBundle().getBundleInfo().getVendor() )
+            || different( fragmentHost, getProjectModel().getBundle().getBundleInfo().getFragmentHost() )
+            || different( activator, getProjectModel().getBundle().getBundleInfo().getActivator() );
+
+        if ( dirty )
+            markDirty();
+    }
+
+
+    private boolean different( Object val1, Object val2 )
+    {
+        return val1 == null ? val2 != null : !val1.equals( val2 );
+    }
+
+
+    private ISigilBundle getBundle()
+    {
+        return getProjectModel().getBundle();
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/IDependencyChecker.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/IDependencyChecker.java
index c99b6c2..fbacd0b 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/IDependencyChecker.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/IDependencyChecker.java
@@ -19,10 +19,15 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import org.apache.felix.sigil.model.osgi.IPackageImport;
 import org.apache.felix.sigil.model.osgi.IRequiredBundle;
 
-public interface IDependencyChecker {
-	boolean isSatisfied(IPackageImport packageImport);
-	boolean isSatisfied(IRequiredBundle requiredBundle);
+
+public interface IDependencyChecker
+{
+    boolean isSatisfied( IPackageImport packageImport );
+
+
+    boolean isSatisfied( IRequiredBundle requiredBundle );
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/IElementDescriptor.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/IElementDescriptor.java
index 7049e3d..16c85d5 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/IElementDescriptor.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/IElementDescriptor.java
@@ -19,18 +19,21 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
-public interface IElementDescriptor<E> {	
-	/**
-	 * Return the short identifying name of the element.
-	 */
-	String getName(E element);
 
-	/**
-	 * Return a label for the element, including the name but possibly supplying
-	 * additional information.
-	 * 
-	 * @param element
-	 * @return
-	 */
-	String getLabel(E element);
+public interface IElementDescriptor<E>
+{
+    /**
+     * Return the short identifying name of the element.
+     */
+    String getName( E element );
+
+
+    /**
+     * Return a label for the element, including the name but possibly supplying
+     * additional information.
+     * 
+     * @param element
+     * @return
+     */
+    String getLabel( E element );
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ImportPackagesSection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ImportPackagesSection.java
index 93cc7e2..3981fd7 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ImportPackagesSection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ImportPackagesSection.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -42,112 +43,133 @@
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.ui.forms.widgets.FormToolkit;
 
-public class ImportPackagesSection extends BundleDependencySection {
-	
-	public ImportPackagesSection(SigilPage page, Composite parent, ISigilProjectModel project, Set<IModelElement> unresolvedPackages) throws CoreException {
-		super( page, parent, project, unresolvedPackages );
-	}
 
-	@Override
-	protected String getTitle() {
-		return "Import Packages";
-	}
-	
-	@Override
-	protected Label createLabel(Composite parent, FormToolkit toolkit) {
-		return toolkit.createLabel( parent, "Specify which packages this bundle imports from other bundles." );
-	}
+public class ImportPackagesSection extends BundleDependencySection
+{
+
+    public ImportPackagesSection( SigilPage page, Composite parent, ISigilProjectModel project,
+        Set<IModelElement> unresolvedPackages ) throws CoreException
+    {
+        super( page, parent, project, unresolvedPackages );
+    }
 
 
-	@Override
-	protected IContentProvider getContentProvider() {
-		return new DefaultTableProvider() {
-			public Object[] getElements(Object inputElement) {
-				ArrayList<IPackageImport> imports = new ArrayList<IPackageImport>(getBundle().getBundleInfo().getImports());
-				Collections.sort(imports, new Comparator<IPackageImport>() {
-					public int compare(IPackageImport o1, IPackageImport o2) {
-						return o1.getPackageName().compareTo( o2.getPackageName() );
-					}
-				});
-				return imports.toArray();
-			}
+    @Override
+    protected String getTitle()
+    {
+        return "Import Packages";
+    }
+
+
+    @Override
+    protected Label createLabel( Composite parent, FormToolkit toolkit )
+    {
+        return toolkit.createLabel( parent, "Specify which packages this bundle imports from other bundles." );
+    }
+
+
+    @Override
+    protected IContentProvider getContentProvider()
+    {
+        return new DefaultTableProvider()
+        {
+            public Object[] getElements( Object inputElement )
+            {
+                ArrayList<IPackageImport> imports = new ArrayList<IPackageImport>( getBundle().getBundleInfo()
+                    .getImports() );
+                Collections.sort( imports, new Comparator<IPackageImport>()
+                {
+                    public int compare( IPackageImport o1, IPackageImport o2 )
+                    {
+                        return o1.getPackageName().compareTo( o2.getPackageName() );
+                    }
+                } );
+                return imports.toArray();
+            }
         };
-	}
+    }
 
-	protected ISigilBundle getBundle() {
-		return getProjectModel().getBundle();
-	}
 
-	@Override
-	protected void handleAdd() {
-		NewResourceSelectionDialog<? extends IPackageModelElement> dialog = 
-			ResourcesDialogHelper.createImportDialog(
-					getSection().getShell(), 
-					"Add Imported Package", 
-					getProjectModel(), 
-					null, 
-					getBundle().getBundleInfo().getImports() );
-		
-		if ( dialog.open() == Window.OK ) {
-			IPackageImport pi = ModelElementFactory.getInstance().newModelElement(IPackageImport.class);
-			pi.setPackageName(dialog.getSelectedName());
-			pi.setVersions(dialog.getSelectedVersions());
-			pi.setOptional(dialog.isOptional());
-			
-			getBundle().getBundleInfo().addImport(pi);
-			refresh();
-			markDirty();
-		}
-	}
+    protected ISigilBundle getBundle()
+    {
+        return getProjectModel().getBundle();
+    }
 
-	@SuppressWarnings("unchecked")
-	@Override
-	protected void handleRemoved() {
-		IStructuredSelection selection = (IStructuredSelection) getSelection();
 
-		if ( !selection.isEmpty() ) {
-			for ( Iterator<IPackageImport> i = selection.iterator(); i.hasNext(); ) {			
-				getBundle().getBundleInfo().removeImport( i.next() );
-			}		
-			
-			refresh();
-			markDirty();
-		}
-	}
-	
-	@SuppressWarnings("unchecked")
-	@Override
-	protected void handleEdit() {
-		IStructuredSelection selection = (IStructuredSelection) getSelection();
-		
-		boolean changed = false;
-		
-		if ( !selection.isEmpty() ) {
-			for ( Iterator<IPackageImport> i = selection.iterator(); i.hasNext(); ) {	
-				IPackageImport packageImport = i.next();
-				NewResourceSelectionDialog<? extends IPackageModelElement> dialog = 
-					ResourcesDialogHelper.createImportDialog( 
-							getSection().getShell(), 
-							"Edit Imported Package", 
-							getProjectModel(), 
-							packageImport, 
-							getBundle().getBundleInfo().getImports() );
-				if ( dialog.open() == Window.OK ) {
-					changed = true;
-					IPackageImport newImport = ModelElementFactory.getInstance().newModelElement(IPackageImport.class);
-					newImport.setPackageName(dialog.getSelectedName());
-					newImport.setVersions(dialog.getSelectedVersions());
-					newImport.setOptional(dialog.isOptional());
-					
-					getBundle().getBundleInfo().removeImport( packageImport );
-					getBundle().getBundleInfo().addImport(newImport);
-				}
-			}					
-		}
-		
-		if ( changed ) {
-			refresh();
-			markDirty();
-		}
-	}
+    @Override
+    protected void handleAdd()
+    {
+        NewResourceSelectionDialog<? extends IPackageModelElement> dialog = ResourcesDialogHelper.createImportDialog(
+            getSection().getShell(), "Add Imported Package", getProjectModel(), null, getBundle().getBundleInfo()
+                .getImports() );
+
+        if ( dialog.open() == Window.OK )
+        {
+            IPackageImport pi = ModelElementFactory.getInstance().newModelElement( IPackageImport.class );
+            pi.setPackageName( dialog.getSelectedName() );
+            pi.setVersions( dialog.getSelectedVersions() );
+            pi.setOptional( dialog.isOptional() );
+
+            getBundle().getBundleInfo().addImport( pi );
+            refresh();
+            markDirty();
+        }
+    }
+
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected void handleRemoved()
+    {
+        IStructuredSelection selection = ( IStructuredSelection ) getSelection();
+
+        if ( !selection.isEmpty() )
+        {
+            for ( Iterator<IPackageImport> i = selection.iterator(); i.hasNext(); )
+            {
+                getBundle().getBundleInfo().removeImport( i.next() );
+            }
+
+            refresh();
+            markDirty();
+        }
+    }
+
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected void handleEdit()
+    {
+        IStructuredSelection selection = ( IStructuredSelection ) getSelection();
+
+        boolean changed = false;
+
+        if ( !selection.isEmpty() )
+        {
+            for ( Iterator<IPackageImport> i = selection.iterator(); i.hasNext(); )
+            {
+                IPackageImport packageImport = i.next();
+                NewResourceSelectionDialog<? extends IPackageModelElement> dialog = ResourcesDialogHelper
+                    .createImportDialog( getSection().getShell(), "Edit Imported Package", getProjectModel(),
+                        packageImport, getBundle().getBundleInfo().getImports() );
+                if ( dialog.open() == Window.OK )
+                {
+                    changed = true;
+                    IPackageImport newImport = ModelElementFactory.getInstance().newModelElement( IPackageImport.class );
+                    newImport.setPackageName( dialog.getSelectedName() );
+                    newImport.setVersions( dialog.getSelectedVersions() );
+                    newImport.setOptional( dialog.isOptional() );
+
+                    getBundle().getBundleInfo().removeImport( packageImport );
+                    getBundle().getBundleInfo().addImport( newImport );
+                }
+            }
+        }
+
+        if ( changed )
+        {
+            refresh();
+            markDirty();
+        }
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/NewPackageExportDialog.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/NewPackageExportDialog.java
index bf6f83b..f6db23f 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/NewPackageExportDialog.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/NewPackageExportDialog.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import java.util.Comparator;
 
 import org.apache.felix.sigil.ui.eclipse.ui.util.BackgroundLoadingSelectionDialog;
@@ -37,114 +38,144 @@
 import org.eclipse.swt.widgets.Text;
 import org.osgi.framework.Version;
 
-public class NewPackageExportDialog extends BackgroundLoadingSelectionDialog<IPackageFragment> {
-	
-	private static final IElementDescriptor<IPackageFragment> PKG_FRAGMENT_STRINGIFIER = new IElementDescriptor<IPackageFragment>() {
-		public String getLabel(IPackageFragment element) {
-			return getName(element);
-		}
-		public String getName(IPackageFragment element) {
-			return element.getElementName();
-		}
-	};
-	
-	private static final Comparator<IPackageFragment> PKG_FRAGMENT_COMPARATOR = new Comparator<IPackageFragment>() {
-		public int compare(IPackageFragment o1, IPackageFragment o2) {
-			return o1.getElementName().compareTo(o2.getElementName());
-		}
-	};
-	
-	private Version version = null;
-	private String error = null;
-	private Version projectVersion = new Version(0,0,0);
-	
-	private Button btnInheritBundleVersion;
-	private Button btnExplicitVersion;
-	private Text txtVersion;
 
-	
-	public NewPackageExportDialog(Shell parentShell, boolean multiSelect) {
-		super(parentShell, "Package:", multiSelect);
-		setDescriptor(PKG_FRAGMENT_STRINGIFIER);
-		setComparator(PKG_FRAGMENT_COMPARATOR);
-	}
+public class NewPackageExportDialog extends BackgroundLoadingSelectionDialog<IPackageFragment>
+{
 
-	@Override
-	protected Control createDialogArea(Composite parent) {
-		// Create controls
-		Composite container = (Composite) super.createDialogArea(parent);
-		Composite composite = new Composite(container, SWT.NONE);
-		
-		Group grpVersion = new Group(composite, SWT.NONE);
-		grpVersion.setText("Version");
-		
-		btnInheritBundleVersion = new Button(grpVersion, SWT.RADIO);
-		btnInheritBundleVersion.setText("Inherit bundle version");
-		new Label(grpVersion, SWT.NONE); // Spacer
-		btnExplicitVersion = new Button(grpVersion, SWT.RADIO);
-		btnExplicitVersion.setText("Fixed version:");
-		txtVersion = new Text(grpVersion, SWT.BORDER);
-		
-		// Initialize
-		if(version == null) {
-			btnInheritBundleVersion.setSelection(true);
-			txtVersion.setEnabled(false);
-			txtVersion.setText(projectVersion.toString());
-		} else {
-			btnExplicitVersion.setSelection(true);
-			txtVersion.setEnabled(true);
-			txtVersion.setText(version.toString());
-		}
-		updateButtons();
-		
-		// Listeners
-		Listener radioAndTextListener = new Listener() {
-			public void handleEvent(Event event) {
-				error = null;
-				if(btnInheritBundleVersion.getSelection()) {
-					version = null;
-					txtVersion.setEnabled(false);
-				} else {
-					txtVersion.setEnabled(true);
-					try {
-						version = new Version(txtVersion.getText());
-					} catch (IllegalArgumentException e) {
-						error = "Invalid version";
-					}
-				}
-				setErrorMessage(error);
-				updateButtons();
-			}
-		};
-		txtVersion.addListener(SWT.Modify, radioAndTextListener);
-		btnInheritBundleVersion.addListener(SWT.Selection, radioAndTextListener);
-		btnExplicitVersion.addListener(SWT.Selection, radioAndTextListener);
-		
-		
-		// Layout
-		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		composite.setLayout(new GridLayout(1, false));
-		grpVersion.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		grpVersion.setLayout(new GridLayout(2, false));
-		txtVersion.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		
-		return container;
-	}
-	
-	@Override
-	protected boolean canComplete() {
-		return super.canComplete() && error == null;
-	}
-	
-	public void setProjectVersion(Version projectVersion) {
-		this.projectVersion = projectVersion;
-	}
+    private static final IElementDescriptor<IPackageFragment> PKG_FRAGMENT_STRINGIFIER = new IElementDescriptor<IPackageFragment>()
+    {
+        public String getLabel( IPackageFragment element )
+        {
+            return getName( element );
+        }
 
-	public void setVersion(Version version) {
-		this.version = version;
-	}
-	
-	public Version getVersion() {
-		return version;
-	}
+
+        public String getName( IPackageFragment element )
+        {
+            return element.getElementName();
+        }
+    };
+
+    private static final Comparator<IPackageFragment> PKG_FRAGMENT_COMPARATOR = new Comparator<IPackageFragment>()
+    {
+        public int compare( IPackageFragment o1, IPackageFragment o2 )
+        {
+            return o1.getElementName().compareTo( o2.getElementName() );
+        }
+    };
+
+    private Version version = null;
+    private String error = null;
+    private Version projectVersion = new Version( 0, 0, 0 );
+
+    private Button btnInheritBundleVersion;
+    private Button btnExplicitVersion;
+    private Text txtVersion;
+
+
+    public NewPackageExportDialog( Shell parentShell, boolean multiSelect )
+    {
+        super( parentShell, "Package:", multiSelect );
+        setDescriptor( PKG_FRAGMENT_STRINGIFIER );
+        setComparator( PKG_FRAGMENT_COMPARATOR );
+    }
+
+
+    @Override
+    protected Control createDialogArea( Composite parent )
+    {
+        // Create controls
+        Composite container = ( Composite ) super.createDialogArea( parent );
+        Composite composite = new Composite( container, SWT.NONE );
+
+        Group grpVersion = new Group( composite, SWT.NONE );
+        grpVersion.setText( "Version" );
+
+        btnInheritBundleVersion = new Button( grpVersion, SWT.RADIO );
+        btnInheritBundleVersion.setText( "Inherit bundle version" );
+        new Label( grpVersion, SWT.NONE ); // Spacer
+        btnExplicitVersion = new Button( grpVersion, SWT.RADIO );
+        btnExplicitVersion.setText( "Fixed version:" );
+        txtVersion = new Text( grpVersion, SWT.BORDER );
+
+        // Initialize
+        if ( version == null )
+        {
+            btnInheritBundleVersion.setSelection( true );
+            txtVersion.setEnabled( false );
+            txtVersion.setText( projectVersion.toString() );
+        }
+        else
+        {
+            btnExplicitVersion.setSelection( true );
+            txtVersion.setEnabled( true );
+            txtVersion.setText( version.toString() );
+        }
+        updateButtons();
+
+        // Listeners
+        Listener radioAndTextListener = new Listener()
+        {
+            public void handleEvent( Event event )
+            {
+                error = null;
+                if ( btnInheritBundleVersion.getSelection() )
+                {
+                    version = null;
+                    txtVersion.setEnabled( false );
+                }
+                else
+                {
+                    txtVersion.setEnabled( true );
+                    try
+                    {
+                        version = new Version( txtVersion.getText() );
+                    }
+                    catch ( IllegalArgumentException e )
+                    {
+                        error = "Invalid version";
+                    }
+                }
+                setErrorMessage( error );
+                updateButtons();
+            }
+        };
+        txtVersion.addListener( SWT.Modify, radioAndTextListener );
+        btnInheritBundleVersion.addListener( SWT.Selection, radioAndTextListener );
+        btnExplicitVersion.addListener( SWT.Selection, radioAndTextListener );
+
+        // Layout
+        composite.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        composite.setLayout( new GridLayout( 1, false ) );
+        grpVersion.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        grpVersion.setLayout( new GridLayout( 2, false ) );
+        txtVersion.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+
+        return container;
+    }
+
+
+    @Override
+    protected boolean canComplete()
+    {
+        return super.canComplete() && error == null;
+    }
+
+
+    public void setProjectVersion( Version projectVersion )
+    {
+        this.projectVersion = projectVersion;
+    }
+
+
+    public void setVersion( Version version )
+    {
+        this.version = version;
+    }
+
+
+    public Version getVersion()
+    {
+        return version;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/NewResourceSelectionDialog.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/NewResourceSelectionDialog.java
index db09307..26ec83f 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/NewResourceSelectionDialog.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/NewResourceSelectionDialog.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.model.common.VersionRange;
 import org.apache.felix.sigil.model.common.VersionRangeBoundingRule;
@@ -40,122 +41,156 @@
 import org.eclipse.swt.widgets.Shell;
 import org.osgi.framework.Version;
 
-public class NewResourceSelectionDialog<E extends IVersionedModelElement> extends BackgroundLoadingSelectionDialog<E> {
 
-	private VersionRangeComponent pnlVersionRange;
-	private boolean optionalEnabled = true;
-	private Button btnOptional;
+public class NewResourceSelectionDialog<E extends IVersionedModelElement> extends BackgroundLoadingSelectionDialog<E>
+{
 
-	private VersionRange selectedVersions = null;
-	private boolean optional = false;
+    private VersionRangeComponent pnlVersionRange;
+    private boolean optionalEnabled = true;
+    private Button btnOptional;
 
-	public NewResourceSelectionDialog(Shell parentShell, String selectionLabel, boolean multi) {
-		super(parentShell, selectionLabel, multi);
-	}
-	
-	public void setOptionalEnabled(boolean enabled) {
-		optionalEnabled = enabled;
-	}
+    private VersionRange selectedVersions = null;
+    private boolean optional = false;
 
-	@Override
-	protected Control createDialogArea(Composite parent) {
-		// Create controls
-		Composite container = (Composite) super.createDialogArea(parent);
-		Composite composite = new Composite(container, SWT.NONE);
-		
-		if ( optionalEnabled ) {
-			new Label(composite, SWT.NONE); //Spacer
-			btnOptional = new Button(composite, SWT.CHECK);
-			btnOptional.setText("Optional");
-		}
-		
-		Label lblVersionRange = new Label(composite, SWT.NONE);
-		lblVersionRange.setText("Version Range:");
-		Group group = new Group(composite, SWT.BORDER);
 
-		pnlVersionRange = new VersionRangeComponent(group, SWT.NONE);
-		
-		// Initialize
-		if (selectedVersions != null) {
-			pnlVersionRange.setVersions(selectedVersions);
-		}
-		
-		if ( optionalEnabled ) {		
-			btnOptional.setSelection(optional);
-			updateButtons();
-		}
-		
-		// Hookup Listeners
-		pnlVersionRange.addVersionChangeListener(new VersionsChangeListener() {
-			public void versionsChanged(VersionRange range) {
-				selectedVersions = range;
-				updateButtons();
-			}
-		});
-		pnlVersionRange.addValidationListener(new IValidationListener() {
-			public void validationMessage(String message, int level) {
-				setMessage(message, level);
-				updateButtons();
-			}
-		});
-		
-		if ( optionalEnabled ) {		
-			btnOptional.addSelectionListener(new SelectionAdapter() {
-				public void widgetSelected(SelectionEvent e) {
-					optional = btnOptional.getSelection();
-				}
-			});
-		}
-		
-		// Layout
-		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		GridLayout layout = new GridLayout(2, false);
-		layout.verticalSpacing = 10;
-		layout.horizontalSpacing = 10;
-		composite.setLayout(layout);
+    public NewResourceSelectionDialog( Shell parentShell, String selectionLabel, boolean multi )
+    {
+        super( parentShell, selectionLabel, multi );
+    }
 
-		lblVersionRange.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
-		group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		group.setLayout(new FillLayout());
 
-		return container;
-	}
+    public void setOptionalEnabled( boolean enabled )
+    {
+        optionalEnabled = enabled;
+    }
 
-	@Override
-	protected void elementSelected(E selection) {
-		if(selection != null) {
-			IPreferenceStore store = SigilCore.getDefault().getPreferenceStore();
-			VersionRangeBoundingRule lowerBoundRule = VersionRangeBoundingRule.valueOf(store.getString(SigilCore.DEFAULT_VERSION_LOWER_BOUND));
-			VersionRangeBoundingRule upperBoundRule = VersionRangeBoundingRule.valueOf(store.getString(SigilCore.DEFAULT_VERSION_UPPER_BOUND));
-			
-			Version version = selection.getVersion();
-			selectedVersions = VersionRange.newInstance(version, lowerBoundRule, upperBoundRule);
-			pnlVersionRange.setVersions(selectedVersions);
-		}
-	}
 
-	@Override
-	protected synchronized boolean canComplete() {
-		return super.canComplete() && selectedVersions != null;
-	}
+    @Override
+    protected Control createDialogArea( Composite parent )
+    {
+        // Create controls
+        Composite container = ( Composite ) super.createDialogArea( parent );
+        Composite composite = new Composite( container, SWT.NONE );
 
-	public VersionRange getSelectedVersions() {
-		return selectedVersions;
-	}
+        if ( optionalEnabled )
+        {
+            new Label( composite, SWT.NONE ); //Spacer
+            btnOptional = new Button( composite, SWT.CHECK );
+            btnOptional.setText( "Optional" );
+        }
 
-	public void setVersions(VersionRange versions) {
-		selectedVersions = versions;
-		if(pnlVersionRange != null && !pnlVersionRange.isDisposed()) {
-			pnlVersionRange.setVersions(versions);
-			updateButtons();
-		}
-	}
-	
-	public boolean isOptional() {
-		return optional;
-	}
-	
-	public void setOptional(boolean optional) {
-		this.optional = optional;
-	}
+        Label lblVersionRange = new Label( composite, SWT.NONE );
+        lblVersionRange.setText( "Version Range:" );
+        Group group = new Group( composite, SWT.BORDER );
+
+        pnlVersionRange = new VersionRangeComponent( group, SWT.NONE );
+
+        // Initialize
+        if ( selectedVersions != null )
+        {
+            pnlVersionRange.setVersions( selectedVersions );
+        }
+
+        if ( optionalEnabled )
+        {
+            btnOptional.setSelection( optional );
+            updateButtons();
+        }
+
+        // Hookup Listeners
+        pnlVersionRange.addVersionChangeListener( new VersionsChangeListener()
+        {
+            public void versionsChanged( VersionRange range )
+            {
+                selectedVersions = range;
+                updateButtons();
+            }
+        } );
+        pnlVersionRange.addValidationListener( new IValidationListener()
+        {
+            public void validationMessage( String message, int level )
+            {
+                setMessage( message, level );
+                updateButtons();
+            }
+        } );
+
+        if ( optionalEnabled )
+        {
+            btnOptional.addSelectionListener( new SelectionAdapter()
+            {
+                public void widgetSelected( SelectionEvent e )
+                {
+                    optional = btnOptional.getSelection();
+                }
+            } );
+        }
+
+        // Layout
+        composite.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        GridLayout layout = new GridLayout( 2, false );
+        layout.verticalSpacing = 10;
+        layout.horizontalSpacing = 10;
+        composite.setLayout( layout );
+
+        lblVersionRange.setLayoutData( new GridData( SWT.LEFT, SWT.TOP, false, false ) );
+        group.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        group.setLayout( new FillLayout() );
+
+        return container;
+    }
+
+
+    @Override
+    protected void elementSelected( E selection )
+    {
+        if ( selection != null )
+        {
+            IPreferenceStore store = SigilCore.getDefault().getPreferenceStore();
+            VersionRangeBoundingRule lowerBoundRule = VersionRangeBoundingRule.valueOf( store
+                .getString( SigilCore.DEFAULT_VERSION_LOWER_BOUND ) );
+            VersionRangeBoundingRule upperBoundRule = VersionRangeBoundingRule.valueOf( store
+                .getString( SigilCore.DEFAULT_VERSION_UPPER_BOUND ) );
+
+            Version version = selection.getVersion();
+            selectedVersions = VersionRange.newInstance( version, lowerBoundRule, upperBoundRule );
+            pnlVersionRange.setVersions( selectedVersions );
+        }
+    }
+
+
+    @Override
+    protected synchronized boolean canComplete()
+    {
+        return super.canComplete() && selectedVersions != null;
+    }
+
+
+    public VersionRange getSelectedVersions()
+    {
+        return selectedVersions;
+    }
+
+
+    public void setVersions( VersionRange versions )
+    {
+        selectedVersions = versions;
+        if ( pnlVersionRange != null && !pnlVersionRange.isDisposed() )
+        {
+            pnlVersionRange.setVersions( versions );
+            updateButtons();
+        }
+    }
+
+
+    public boolean isOptional()
+    {
+        return optional;
+    }
+
+
+    public void setOptional( boolean optional )
+    {
+        this.optional = optional;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/OverviewForm.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/OverviewForm.java
index c044515..f0aa509 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/OverviewForm.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/OverviewForm.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.apache.felix.sigil.ui.eclipse.ui.form.SigilPage;
@@ -30,27 +31,33 @@
 import org.eclipse.ui.forms.widgets.TableWrapData;
 import org.eclipse.ui.forms.widgets.TableWrapLayout;
 
+
 /**
  * @author dave
  *
  */
-public class OverviewForm extends SigilPage {
+public class OverviewForm extends SigilPage
+{
     public static final String PAGE_ID = "overview";
     private ISigilProjectModel sigil;
-    
-    public OverviewForm(SigilProjectEditorPart editor, ISigilProjectModel sigil) {
-        super(editor, PAGE_ID, "Overview");
+
+
+    public OverviewForm( SigilProjectEditorPart editor, ISigilProjectModel sigil )
+    {
+        super( editor, PAGE_ID, "Overview" );
         this.sigil = sigil;
     }
 
+
     @Override
-    protected void createFormContent(IManagedForm managedForm) {
+    protected void createFormContent( IManagedForm managedForm )
+    {
         FormToolkit toolkit = managedForm.getToolkit();
-        
+
         ScrolledForm form = managedForm.getForm();
         form.setText( "Overview" );
-        
-        Composite body = form.getBody();        
+
+        Composite body = form.getBody();
         TableWrapLayout layout = new TableWrapLayout();
         layout.bottomMargin = 10;
         layout.topMargin = 5;
@@ -58,39 +65,41 @@
         layout.rightMargin = 10;
         layout.numColumns = 2;
         layout.horizontalSpacing = 10;
-        body.setLayout(layout);
-        body.setLayoutData(new TableWrapData(TableWrapData.FILL));
-        
-        Composite left = toolkit.createComposite(body);
+        body.setLayout( layout );
+        body.setLayoutData( new TableWrapData( TableWrapData.FILL ) );
+
+        Composite left = toolkit.createComposite( body );
         layout = new TableWrapLayout();
         layout.verticalSpacing = 20;
-        left.setLayout(layout);
-        left.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
-        
-        Composite right = toolkit.createComposite(body);
+        left.setLayout( layout );
+        left.setLayoutData( new TableWrapData( TableWrapData.FILL_GRAB ) );
+
+        Composite right = toolkit.createComposite( body );
         layout = new TableWrapLayout();
         layout.verticalSpacing = 20;
-        right.setLayout(layout);
-        right.setLayoutData( new TableWrapData( TableWrapData.FILL_GRAB) );
-        
-        try {
-	        GeneralInfoSection general = new GeneralInfoSection(this, left, sigil);
-	        managedForm.addPart( general );
-	        
-	        ContentSummarySection content = new ContentSummarySection( this, right, sigil);
-	        managedForm.addPart( content );
-	        
-	        // XXX-FELIX
-	        // commented out due to removal of runtime newton integration
-	        // potential to bring back in medium term...
-	        //TestingSection testing = new TestingSection(this, right, newton);
-	        //managedForm.addPart(testing);
-	        
-	        ToolsSection tools = new ToolsSection(this, right, sigil);
-	        managedForm.addPart(tools);
+        right.setLayout( layout );
+        right.setLayoutData( new TableWrapData( TableWrapData.FILL_GRAB ) );
+
+        try
+        {
+            GeneralInfoSection general = new GeneralInfoSection( this, left, sigil );
+            managedForm.addPart( general );
+
+            ContentSummarySection content = new ContentSummarySection( this, right, sigil );
+            managedForm.addPart( content );
+
+            // XXX-FELIX
+            // commented out due to removal of runtime newton integration
+            // potential to bring back in medium term...
+            //TestingSection testing = new TestingSection(this, right, newton);
+            //managedForm.addPart(testing);
+
+            ToolsSection tools = new ToolsSection( this, right, sigil );
+            managedForm.addPart( tools );
         }
-        catch (CoreException e) {
-        	SigilCore.error( "Failed to create overview form", e );
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Failed to create overview form", e );
         }
     }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/PackageExportDialog.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/PackageExportDialog.java
index fb82550..246b2a3 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/PackageExportDialog.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/PackageExportDialog.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import org.eclipse.jface.viewers.IContentProvider;
 import org.eclipse.jface.viewers.ViewerFilter;
 import org.eclipse.swt.SWT;
@@ -30,42 +31,58 @@
 import org.eclipse.swt.widgets.Text;
 import org.osgi.framework.Version;
 
-public class PackageExportDialog extends ResourceSelectDialog  {
 
-	private Text versionText;
-	private Version version;
-	
-	public PackageExportDialog(Shell parentShell, String title, IContentProvider content, ViewerFilter filter, Object scope ) {
-		super(parentShell, content, filter, scope, title, "Package Name:", true);
-	}
-	
-	@Override
-	protected void createCustom(Composite body) {
-		Label l = new Label( body, SWT.NONE );
-		l.setText( "Version:" );
-		versionText = new Text(body, SWT.BORDER);
-		versionText.addKeyListener(new KeyAdapter() {
-			@Override
-			public void keyReleased(KeyEvent e) {
-				try {
-					version = Version.parseVersion(versionText.getText());
-					setErrorMessage(null);
-				}
-				catch (IllegalArgumentException ex) {
-					setErrorMessage("Invalid version");
-				}
-			}			
-		});
-		if ( version != null ) {
-			versionText.setText( version.toString() );
-		}
-	}
+public class PackageExportDialog extends ResourceSelectDialog
+{
 
-	public Version getVersion() {
-		return version;
-	}
+    private Text versionText;
+    private Version version;
 
-	public void setVersion(Version version) {
-		this.version = version;
-	}	
+
+    public PackageExportDialog( Shell parentShell, String title, IContentProvider content, ViewerFilter filter,
+        Object scope )
+    {
+        super( parentShell, content, filter, scope, title, "Package Name:", true );
+    }
+
+
+    @Override
+    protected void createCustom( Composite body )
+    {
+        Label l = new Label( body, SWT.NONE );
+        l.setText( "Version:" );
+        versionText = new Text( body, SWT.BORDER );
+        versionText.addKeyListener( new KeyAdapter()
+        {
+            @Override
+            public void keyReleased( KeyEvent e )
+            {
+                try
+                {
+                    version = Version.parseVersion( versionText.getText() );
+                    setErrorMessage( null );
+                }
+                catch ( IllegalArgumentException ex )
+                {
+                    setErrorMessage( "Invalid version" );
+                }
+            }
+        } );
+        if ( version != null )
+        {
+            versionText.setText( version.toString() );
+        }
+    }
+
+
+    public Version getVersion()
+    {
+        return version;
+    }
+
+
+    public void setVersion( Version version )
+    {
+        this.version = version;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ProjectLabelProvider.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ProjectLabelProvider.java
index 3a23d0e..5b0745b 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ProjectLabelProvider.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ProjectLabelProvider.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import java.io.InputStream;
 
 import org.apache.felix.sigil.eclipse.SigilCore;
@@ -39,140 +40,186 @@
 import org.eclipse.swt.graphics.ImageData;
 import org.eclipse.swt.widgets.Widget;
 
-public class ProjectLabelProvider extends DefaultLabelProvider implements IBaseLabelProvider {
 
-	private final Widget parent;
-	private final ImageRegistry registry;
-	private final IDependencyChecker checker;
-	
-	public ProjectLabelProvider(Widget parent, ImageRegistry registry ) {
-		this(parent, registry, null);
-	}
-	
-	public ProjectLabelProvider(Widget parent, ImageRegistry registry, IDependencyChecker checker) {
-		this.parent = parent;
-		this.registry = registry;
-		this.checker = checker;
-	}
+public class ProjectLabelProvider extends DefaultLabelProvider implements IBaseLabelProvider
+{
 
-	public Image getImage(Object element) {
-		Image result = null;
-		if ( element instanceof ISigilBundle || element instanceof IRequiredBundle || element instanceof IBundleModelElement) {
-			result = findBundle();
-		}
-		else if (element instanceof IPackageImport) {
-			if(checker != null) {
-				result = checker.isSatisfied((IPackageImport) element) ? findPackage() : findPackageError();
-			} else {
-				result = findPackage();
-			}
-		}
-		else if (element instanceof IPackageExport) {
-			result = findPackage();
-		}
-		else if ( element instanceof IPackageFragmentRoot ) {
-			IPackageFragmentRoot root = (IPackageFragmentRoot) element;
-			try {
-				if ( root.getKind() == IPackageFragmentRoot.K_SOURCE ) {
-					result = findPackage();
-				}
-				else {
-					result = findBundle();
-				}
-			} catch (JavaModelException e) {
-				SigilCore.error( "Failed to inspect package fragment root", e );
-			}
-		}
-		else if ( element instanceof IClasspathEntry ) {
-			result = findPackage();
-		}
-	
-		return result;
-	}
+    private final Widget parent;
+    private final ImageRegistry registry;
+    private final IDependencyChecker checker;
 
-	public String getText(Object element) {
-		if ( element instanceof ISigilBundle ) {
-			ISigilBundle bundle = (ISigilBundle) element;
-			return bundle.getBundleInfo().getSymbolicName(); 
-		}
 
-		if ( element instanceof IRequiredBundle ) {
-			IRequiredBundle req = (IRequiredBundle) element;
-			return req.getSymbolicName() + " " + req.getVersions();
-		}
-		
-		if ( element instanceof IPackageImport ) {
-			IPackageImport req = (IPackageImport) element;
-			return req.getPackageName() + " " + req.getVersions();
-		}
-		
-		if ( element instanceof IPackageExport ) {
-			IPackageExport pe = (IPackageExport) element;
-			return pe.getPackageName() + " " + pe.getVersion();
-		}
-		
-		if ( element instanceof IResource ) {
-			IResource resource = (IResource) element;
-			return resource.getName();
-		}
-		
-		if ( element instanceof IPackageFragment )  {
-			IPackageFragment f = (IPackageFragment) element;
-			return f.getElementName();
-		}
-		
-		if ( element instanceof IPackageFragmentRoot ) {
-			IPackageFragmentRoot f = (IPackageFragmentRoot) element;
-			try {
-				return f.getUnderlyingResource().getName();
-			} catch (JavaModelException e) {
-				return "unknown";
-			}
-		}
-		
-		if ( element instanceof IClasspathEntry ) {
-			IClasspathEntry cp = (IClasspathEntry) element;
-			return cp.getPath().toString();
-		}
-		
-		return element.toString();
-	}
+    public ProjectLabelProvider( Widget parent, ImageRegistry registry )
+    {
+        this( parent, registry, null );
+    }
 
-	private Image findPackage() {
-		Image image = registry.get( "package" );
-		
-		if ( image == null ) {
-			image = loadImage( "icons/package_obj.png" ); 
-			registry.put( "package", image);
-		}
-		
-		return image; 
-	}
-	
-	private Image findPackageError() {
-		Image image = registry.get("package_error");
-		if(image == null) {
-			image = loadImage("icons/package_obj_error.gif");
-			registry.put("package_error", image);
-		}
-		return image;
-	}
 
-	private Image findBundle() {
-		Image image = registry.get( "bundle" );
-		
-		if ( image == null ) {
-			image = loadImage( "icons/jar_obj.png" ); 
-			registry.put( "bundle", image);
-		}
-		
-		return image; 
-	}
-		
-	private Image loadImage(String resource) {
-		InputStream in = ProjectLabelProvider.class.getClassLoader().getResourceAsStream( resource );
-		ImageData data = new ImageData( in );
-		return new Image( parent.getDisplay(), data );
-	}
+    public ProjectLabelProvider( Widget parent, ImageRegistry registry, IDependencyChecker checker )
+    {
+        this.parent = parent;
+        this.registry = registry;
+        this.checker = checker;
+    }
+
+
+    public Image getImage( Object element )
+    {
+        Image result = null;
+        if ( element instanceof ISigilBundle || element instanceof IRequiredBundle
+            || element instanceof IBundleModelElement )
+        {
+            result = findBundle();
+        }
+        else if ( element instanceof IPackageImport )
+        {
+            if ( checker != null )
+            {
+                result = checker.isSatisfied( ( IPackageImport ) element ) ? findPackage() : findPackageError();
+            }
+            else
+            {
+                result = findPackage();
+            }
+        }
+        else if ( element instanceof IPackageExport )
+        {
+            result = findPackage();
+        }
+        else if ( element instanceof IPackageFragmentRoot )
+        {
+            IPackageFragmentRoot root = ( IPackageFragmentRoot ) element;
+            try
+            {
+                if ( root.getKind() == IPackageFragmentRoot.K_SOURCE )
+                {
+                    result = findPackage();
+                }
+                else
+                {
+                    result = findBundle();
+                }
+            }
+            catch ( JavaModelException e )
+            {
+                SigilCore.error( "Failed to inspect package fragment root", e );
+            }
+        }
+        else if ( element instanceof IClasspathEntry )
+        {
+            result = findPackage();
+        }
+
+        return result;
+    }
+
+
+    public String getText( Object element )
+    {
+        if ( element instanceof ISigilBundle )
+        {
+            ISigilBundle bundle = ( ISigilBundle ) element;
+            return bundle.getBundleInfo().getSymbolicName();
+        }
+
+        if ( element instanceof IRequiredBundle )
+        {
+            IRequiredBundle req = ( IRequiredBundle ) element;
+            return req.getSymbolicName() + " " + req.getVersions();
+        }
+
+        if ( element instanceof IPackageImport )
+        {
+            IPackageImport req = ( IPackageImport ) element;
+            return req.getPackageName() + " " + req.getVersions();
+        }
+
+        if ( element instanceof IPackageExport )
+        {
+            IPackageExport pe = ( IPackageExport ) element;
+            return pe.getPackageName() + " " + pe.getVersion();
+        }
+
+        if ( element instanceof IResource )
+        {
+            IResource resource = ( IResource ) element;
+            return resource.getName();
+        }
+
+        if ( element instanceof IPackageFragment )
+        {
+            IPackageFragment f = ( IPackageFragment ) element;
+            return f.getElementName();
+        }
+
+        if ( element instanceof IPackageFragmentRoot )
+        {
+            IPackageFragmentRoot f = ( IPackageFragmentRoot ) element;
+            try
+            {
+                return f.getUnderlyingResource().getName();
+            }
+            catch ( JavaModelException e )
+            {
+                return "unknown";
+            }
+        }
+
+        if ( element instanceof IClasspathEntry )
+        {
+            IClasspathEntry cp = ( IClasspathEntry ) element;
+            return cp.getPath().toString();
+        }
+
+        return element.toString();
+    }
+
+
+    private Image findPackage()
+    {
+        Image image = registry.get( "package" );
+
+        if ( image == null )
+        {
+            image = loadImage( "icons/package_obj.png" );
+            registry.put( "package", image );
+        }
+
+        return image;
+    }
+
+
+    private Image findPackageError()
+    {
+        Image image = registry.get( "package_error" );
+        if ( image == null )
+        {
+            image = loadImage( "icons/package_obj_error.gif" );
+            registry.put( "package_error", image );
+        }
+        return image;
+    }
+
+
+    private Image findBundle()
+    {
+        Image image = registry.get( "bundle" );
+
+        if ( image == null )
+        {
+            image = loadImage( "icons/jar_obj.png" );
+            registry.put( "bundle", image );
+        }
+
+        return image;
+    }
+
+
+    private Image loadImage( String resource )
+    {
+        InputStream in = ProjectLabelProvider.class.getClassLoader().getResourceAsStream( resource );
+        ImageData data = new ImageData( in );
+        return new Image( parent.getDisplay(), data );
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ProjectTableViewer.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ProjectTableViewer.java
index 3ba1ec5..4cf5cdf 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ProjectTableViewer.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ProjectTableViewer.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import java.util.Set;
 
 import org.apache.felix.sigil.model.IModelElement;
@@ -27,30 +28,39 @@
 import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.swt.widgets.Table;
 
-public class ProjectTableViewer extends TableViewer {
 
-	private ModelLabelProvider labelProvider;
+public class ProjectTableViewer extends TableViewer
+{
 
-	public ProjectTableViewer(Table table) {
-		super(table);
-		labelProvider = new ModelLabelProvider();
-		setLabelProvider(labelProvider);
-	}
+    private ModelLabelProvider labelProvider;
 
-	@Override
-	public void setContentProvider(IContentProvider provider) {
-		super.setContentProvider(provider);
-		setInput(getTable());
-	}
 
-	public void setUnresolvedElements(Set<? extends IModelElement> elements) {
-		labelProvider.setUnresolvedElements(elements);
-	}
+    public ProjectTableViewer( Table table )
+    {
+        super( table );
+        labelProvider = new ModelLabelProvider();
+        setLabelProvider( labelProvider );
+    }
 
-	@Override
-	public ModelLabelProvider getLabelProvider() {
-		return labelProvider;
-	}
-	
-	
+
+    @Override
+    public void setContentProvider( IContentProvider provider )
+    {
+        super.setContentProvider( provider );
+        setInput( getTable() );
+    }
+
+
+    public void setUnresolvedElements( Set<? extends IModelElement> elements )
+    {
+        labelProvider.setUnresolvedElements( elements );
+    }
+
+
+    @Override
+    public ModelLabelProvider getLabelProvider()
+    {
+        return labelProvider;
+    }
+
 }
\ No newline at end of file
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/PropertiesForm.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/PropertiesForm.java
index 4bba773..e2cadc2 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/PropertiesForm.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/PropertiesForm.java
@@ -27,23 +27,30 @@
 import org.eclipse.jdt.ui.text.JavaTextTools;
 import org.eclipse.jface.preference.IPreferenceStore;
 
+
 @SuppressWarnings("restriction")
-public class PropertiesForm extends SigilSourcePage {
+public class PropertiesForm extends SigilSourcePage
+{
 
     public static final String PAGE_ID = "properties";
-    
-	public PropertiesForm(SigilProjectEditorPart editor, ISigilProjectModel project) {
-		super(PAGE_ID);
-		JavaTextTools textTools= JavaPlugin.getDefault().getJavaTextTools();
-		IPreferenceStore store= JavaPlugin.getDefault().getCombinedPreferenceStore();
-		setPreferenceStore(store);
-		setSourceViewerConfiguration(new PropertiesFileSourceViewerConfiguration(textTools.getColorManager(), store, this, IPropertiesFilePartitions.PROPERTIES_FILE_PARTITIONING));
-        /*IFileEditorInput fileInput = (IFileEditorInput) editor.getEditorInput();
-		this.setDocumentProvider(fileInput);*/
-	}
 
-	@Override
-	public boolean isSaveAsAllowed() {
-		return false;
-	}	
+
+    public PropertiesForm( SigilProjectEditorPart editor, ISigilProjectModel project )
+    {
+        super( PAGE_ID );
+        JavaTextTools textTools = JavaPlugin.getDefault().getJavaTextTools();
+        IPreferenceStore store = JavaPlugin.getDefault().getCombinedPreferenceStore();
+        setPreferenceStore( store );
+        setSourceViewerConfiguration( new PropertiesFileSourceViewerConfiguration( textTools.getColorManager(), store,
+            this, IPropertiesFilePartitions.PROPERTIES_FILE_PARTITIONING ) );
+        /*IFileEditorInput fileInput = (IFileEditorInput) editor.getEditorInput();
+        this.setDocumentProvider(fileInput);*/
+    }
+
+
+    @Override
+    public boolean isSaveAsAllowed()
+    {
+        return false;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/RequiresBundleSection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/RequiresBundleSection.java
index 0c45b5e..c0c1d00 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/RequiresBundleSection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/RequiresBundleSection.java
@@ -42,94 +42,127 @@
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.ui.forms.widgets.FormToolkit;
 
-public class RequiresBundleSection extends BundleDependencySection {
-	
-	public RequiresBundleSection(SigilPage page, Composite parent, ISigilProjectModel project, Set<IModelElement> unresolvedElements) throws CoreException {
-		super( page, parent, project, unresolvedElements );
-	}
-	
-	@Override
-	protected String getTitle() {
-		return "Requires Bundles";
-	}
-	
-	@Override
-	protected Label createLabel(Composite parent, FormToolkit toolkit) {
-		return toolkit.createLabel( parent, "Specify which bundles this bundle depends on." );
-	}
-	
-	@Override
-	protected IContentProvider getContentProvider() {
-		return new DefaultTableProvider() {
-			public Object[] getElements(Object inputElement) {
-				return getBundle().getBundleInfo().getRequiredBundles().toArray();
-			}
-		};
-	}
 
-	protected ISigilBundle getBundle() {
-		return getProjectModel().getBundle();
-	}
+public class RequiresBundleSection extends BundleDependencySection
+{
 
-	@Override
-	protected void handleAdd() {
-		try {
-			NewResourceSelectionDialog<IBundleModelElement> dialog = ResourcesDialogHelper.createRequiredBundleDialog( getSection().getShell(), "Add Required Bundle", getProjectModel(), null, getBundle().getBundleInfo().getRequiredBundles() );
-			
-			if (dialog.open() == Window.OK) {
-				IRequiredBundle required = ModelElementFactory.getInstance().newModelElement( IRequiredBundle.class );
-				required.setSymbolicName(dialog.getSelectedName());
-				required.setVersions(dialog.getSelectedVersions());
-				required.setOptional(dialog.isOptional());
-				
-				getBundle().getBundleInfo().addRequiredBundle(required);
-				refresh();
-				markDirty();
-			}
-		}
-		catch (ModelElementFactoryException e) {
-			SigilCore.error( "Failed to build required bundle", e );
-		}
-	}
+    public RequiresBundleSection( SigilPage page, Composite parent, ISigilProjectModel project,
+        Set<IModelElement> unresolvedElements ) throws CoreException
+    {
+        super( page, parent, project, unresolvedElements );
+    }
 
-	@SuppressWarnings("unchecked")
-	@Override
-	protected void handleEdit() {
-		IStructuredSelection selection = (IStructuredSelection) getSelection();
-		
-		boolean changed = false;
-		
-		if ( !selection.isEmpty() ) {
-			for ( Iterator<IRequiredBundle> i = selection.iterator(); i.hasNext(); ) {	
-				IRequiredBundle requiredBundle = i.next();
-				NewResourceSelectionDialog<IBundleModelElement> dialog = ResourcesDialogHelper.createRequiredBundleDialog(getSection().getShell(), "Edit Imported Package", getProjectModel(), requiredBundle, getBundle().getBundleInfo().getRequiredBundles() );
-				if ( dialog.open() == Window.OK ) {
-					changed = true;
-					requiredBundle.setSymbolicName(dialog.getSelectedName());
-					requiredBundle.setVersions(dialog.getSelectedVersions());
-					requiredBundle.setOptional(dialog.isOptional());
-				}
-			}					
-		}
-		
-		if ( changed ) {
-			refresh();
-			markDirty();
-		}
-	}
-	
-	@SuppressWarnings("unchecked")
-	@Override
-	protected void handleRemoved() {
-		IStructuredSelection selection = (IStructuredSelection) getSelection();
 
-		if ( !selection.isEmpty() ) {
-			for ( Iterator<IRequiredBundle> i = selection.iterator(); i.hasNext(); ) {			
-				getBundle().getBundleInfo().removeRequiredBundle( i.next() );
-			}		
-			
-			refresh();
-			markDirty();
-		}
-	}
+    @Override
+    protected String getTitle()
+    {
+        return "Requires Bundles";
+    }
+
+
+    @Override
+    protected Label createLabel( Composite parent, FormToolkit toolkit )
+    {
+        return toolkit.createLabel( parent, "Specify which bundles this bundle depends on." );
+    }
+
+
+    @Override
+    protected IContentProvider getContentProvider()
+    {
+        return new DefaultTableProvider()
+        {
+            public Object[] getElements( Object inputElement )
+            {
+                return getBundle().getBundleInfo().getRequiredBundles().toArray();
+            }
+        };
+    }
+
+
+    protected ISigilBundle getBundle()
+    {
+        return getProjectModel().getBundle();
+    }
+
+
+    @Override
+    protected void handleAdd()
+    {
+        try
+        {
+            NewResourceSelectionDialog<IBundleModelElement> dialog = ResourcesDialogHelper.createRequiredBundleDialog(
+                getSection().getShell(), "Add Required Bundle", getProjectModel(), null, getBundle().getBundleInfo()
+                    .getRequiredBundles() );
+
+            if ( dialog.open() == Window.OK )
+            {
+                IRequiredBundle required = ModelElementFactory.getInstance().newModelElement( IRequiredBundle.class );
+                required.setSymbolicName( dialog.getSelectedName() );
+                required.setVersions( dialog.getSelectedVersions() );
+                required.setOptional( dialog.isOptional() );
+
+                getBundle().getBundleInfo().addRequiredBundle( required );
+                refresh();
+                markDirty();
+            }
+        }
+        catch ( ModelElementFactoryException e )
+        {
+            SigilCore.error( "Failed to build required bundle", e );
+        }
+    }
+
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected void handleEdit()
+    {
+        IStructuredSelection selection = ( IStructuredSelection ) getSelection();
+
+        boolean changed = false;
+
+        if ( !selection.isEmpty() )
+        {
+            for ( Iterator<IRequiredBundle> i = selection.iterator(); i.hasNext(); )
+            {
+                IRequiredBundle requiredBundle = i.next();
+                NewResourceSelectionDialog<IBundleModelElement> dialog = ResourcesDialogHelper
+                    .createRequiredBundleDialog( getSection().getShell(), "Edit Imported Package", getProjectModel(),
+                        requiredBundle, getBundle().getBundleInfo().getRequiredBundles() );
+                if ( dialog.open() == Window.OK )
+                {
+                    changed = true;
+                    requiredBundle.setSymbolicName( dialog.getSelectedName() );
+                    requiredBundle.setVersions( dialog.getSelectedVersions() );
+                    requiredBundle.setOptional( dialog.isOptional() );
+                }
+            }
+        }
+
+        if ( changed )
+        {
+            refresh();
+            markDirty();
+        }
+    }
+
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected void handleRemoved()
+    {
+        IStructuredSelection selection = ( IStructuredSelection ) getSelection();
+
+        if ( !selection.isEmpty() )
+        {
+            for ( Iterator<IRequiredBundle> i = selection.iterator(); i.hasNext(); )
+            {
+                getBundle().getBundleInfo().removeRequiredBundle( i.next() );
+            }
+
+            refresh();
+            markDirty();
+        }
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ResourceBuildSection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ResourceBuildSection.java
index ea1d3bb..5c54bab 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ResourceBuildSection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ResourceBuildSection.java
@@ -20,7 +20,6 @@
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
 
-
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
@@ -47,120 +46,151 @@
 import org.eclipse.ui.forms.widgets.Section;
 import org.eclipse.ui.forms.widgets.TableWrapData;
 
+
 /**
  * @author dave
  *
  */
-public class ResourceBuildSection extends AbstractResourceSection implements ICheckStateListener, IResourceChangeListener, IPropertyChangeListener {
+public class ResourceBuildSection extends AbstractResourceSection implements ICheckStateListener,
+    IResourceChangeListener, IPropertyChangeListener
+{
 
-	private ExcludedResourcesFilter resourcesFilter;
+    private ExcludedResourcesFilter resourcesFilter;
 
-	/**
-	 * @param page
-	 * @param parent
-	 * @param project
-	 * @throws CoreException 
-	 */
-	public ResourceBuildSection(SigilPage page, Composite parent, ISigilProjectModel project) throws CoreException {
-		super( page, parent, project );
-	}
 
-	@Override
-	protected void createSection(Section section, FormToolkit toolkit) {
-		setTitle( "Resources" );
-		
-		Composite body = createTableWrapBody(1, toolkit);
+    /**
+     * @param page
+     * @param parent
+     * @param project
+     * @throws CoreException 
+     */
+    public ResourceBuildSection( SigilPage page, Composite parent, ISigilProjectModel project ) throws CoreException
+    {
+        super( page, parent, project );
+    }
+
+
+    @Override
+    protected void createSection( Section section, FormToolkit toolkit )
+    {
+        setTitle( "Resources" );
+
+        Composite body = createTableWrapBody( 1, toolkit );
 
         toolkit.createLabel( body, "Specify which resources are included in the bundle." );
-		
-		tree = toolkit.createTree( body, SWT.CHECK | SWT.BORDER );
-		Link link = new Link(body, SWT.WRAP);
-		link.setText("Some resources may be filtered according to preferences. <a href=\"excludedResourcePrefs\">Click here</a> to edit the list of exclusions.");
-		
-		TableWrapData data = new TableWrapData( TableWrapData.FILL_GRAB);
-		data.heightHint = 200;
-		tree.setLayoutData( data );
-		
-		viewer = new CheckboxTreeViewer( tree );
-		IProject base = getProjectModel().getProject();
-		viewer.setContentProvider( new ContainerTreeProvider() );
-		viewer.setLabelProvider( new ModelLabelProvider() );
-		viewer.addCheckStateListener( this );
-		resourcesFilter = new ExcludedResourcesFilter();
-		viewer.addFilter(resourcesFilter);
-		viewer.setInput(base);
-		
-		link.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event event) {
-				if("excludedResourcePrefs".equals(event.text)) {
-					PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn(getPage().getEditorSite().getShell(), SigilCore.EXCLUDED_RESOURCES_PREFERENCES_ID, null, null);
-					dialog.open();
-				}
-			}
-		});
-		
-		SigilCore.getDefault().getPreferenceStore().addPropertyChangeListener(this);
-		
-		startWorkspaceListener(base.getWorkspace());
-	}
 
-	@Override
-	public void commit(boolean onSave) {
-		ISigilBundle bundle = getProjectModel().getBundle();
-		
-		bundle.clearSourcePaths();
-		
-		SigilUI.runInUISync( new Runnable() {
-			public void run() {
-				for ( Object o : viewer.getCheckedElements() ) {
-					if ( !viewer.getGrayed(o) ) {
-						IResource r = (IResource) o;
-						getProjectModel().getBundle().addSourcePath( r.getProjectRelativePath() );
-					}
-				}
-			}			
-		});
-		
-		super.commit(onSave);
-	}
+        tree = toolkit.createTree( body, SWT.CHECK | SWT.BORDER );
+        Link link = new Link( body, SWT.WRAP );
+        link
+            .setText( "Some resources may be filtered according to preferences. <a href=\"excludedResourcePrefs\">Click here</a> to edit the list of exclusions." );
 
-	@Override
-	protected void refreshSelections()  {
-		// zero the state
-		for ( IPath path : getProjectModel().getBundle().getSourcePaths() ) {
-			IResource r = findResource( path );
-			if ( r != null ) {
-				viewer.expandToLevel(r, 0);
-				viewer.setChecked( r, true );
-				viewer.setGrayed( r, false );
-				handleStateChanged(r, true, false, false);
-			}
-			else {
-				SigilCore.error( "Unknown path " + path );
-			}
-		}
-	}
-	
-	@Override
-	protected void syncResourceModel(IResource element, boolean checked) {
-		if ( checked ) {
-			getProjectModel().getBundle().addSourcePath( element.getProjectRelativePath() );
-		}
-		else {
-			getProjectModel().getBundle().removeSourcePath( element.getProjectRelativePath() );
-		}
-		
-		markDirty();
-	}
-	
-	@Override
-	public void dispose() {
-		super.dispose();
-		SigilCore.getDefault().getPreferenceStore().removePropertyChangeListener(this);
-	}
+        TableWrapData data = new TableWrapData( TableWrapData.FILL_GRAB );
+        data.heightHint = 200;
+        tree.setLayoutData( data );
 
-	public void propertyChange(PropertyChangeEvent event) {
-		resourcesFilter.loadExclusions();
-		viewer.refresh();
-	}
+        viewer = new CheckboxTreeViewer( tree );
+        IProject base = getProjectModel().getProject();
+        viewer.setContentProvider( new ContainerTreeProvider() );
+        viewer.setLabelProvider( new ModelLabelProvider() );
+        viewer.addCheckStateListener( this );
+        resourcesFilter = new ExcludedResourcesFilter();
+        viewer.addFilter( resourcesFilter );
+        viewer.setInput( base );
+
+        link.addListener( SWT.Selection, new Listener()
+        {
+            public void handleEvent( Event event )
+            {
+                if ( "excludedResourcePrefs".equals( event.text ) )
+                {
+                    PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn( getPage().getEditorSite()
+                        .getShell(), SigilCore.EXCLUDED_RESOURCES_PREFERENCES_ID, null, null );
+                    dialog.open();
+                }
+            }
+        } );
+
+        SigilCore.getDefault().getPreferenceStore().addPropertyChangeListener( this );
+
+        startWorkspaceListener( base.getWorkspace() );
+    }
+
+
+    @Override
+    public void commit( boolean onSave )
+    {
+        ISigilBundle bundle = getProjectModel().getBundle();
+
+        bundle.clearSourcePaths();
+
+        SigilUI.runInUISync( new Runnable()
+        {
+            public void run()
+            {
+                for ( Object o : viewer.getCheckedElements() )
+                {
+                    if ( !viewer.getGrayed( o ) )
+                    {
+                        IResource r = ( IResource ) o;
+                        getProjectModel().getBundle().addSourcePath( r.getProjectRelativePath() );
+                    }
+                }
+            }
+        } );
+
+        super.commit( onSave );
+    }
+
+
+    @Override
+    protected void refreshSelections()
+    {
+        // zero the state
+        for ( IPath path : getProjectModel().getBundle().getSourcePaths() )
+        {
+            IResource r = findResource( path );
+            if ( r != null )
+            {
+                viewer.expandToLevel( r, 0 );
+                viewer.setChecked( r, true );
+                viewer.setGrayed( r, false );
+                handleStateChanged( r, true, false, false );
+            }
+            else
+            {
+                SigilCore.error( "Unknown path " + path );
+            }
+        }
+    }
+
+
+    @Override
+    protected void syncResourceModel( IResource element, boolean checked )
+    {
+        if ( checked )
+        {
+            getProjectModel().getBundle().addSourcePath( element.getProjectRelativePath() );
+        }
+        else
+        {
+            getProjectModel().getBundle().removeSourcePath( element.getProjectRelativePath() );
+        }
+
+        markDirty();
+    }
+
+
+    @Override
+    public void dispose()
+    {
+        super.dispose();
+        SigilCore.getDefault().getPreferenceStore().removePropertyChangeListener( this );
+    }
+
+
+    public void propertyChange( PropertyChangeEvent event )
+    {
+        resourcesFilter.loadExclusions();
+        viewer.refresh();
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ResourceImportDialog.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ResourceImportDialog.java
index 68fd401..6bab7da 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ResourceImportDialog.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ResourceImportDialog.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import org.apache.felix.sigil.model.ModelElementFactory;
 import org.apache.felix.sigil.model.common.VersionRange;
 import org.apache.felix.sigil.model.osgi.IPackageImport;
@@ -30,60 +31,81 @@
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Shell;
 
-public class ResourceImportDialog extends ResourceSelectDialog implements VersionsChangeListener {
 
-	private VersionRangeComponent versions;
-	private VersionRange range;
-	
-	public ResourceImportDialog(Shell parentShell, String title, String label, IContentProvider content, ViewerFilter filter, Object scope ) {
-		super(parentShell, content, filter, scope, title, label, true);
-	}
+public class ResourceImportDialog extends ResourceSelectDialog implements VersionsChangeListener
+{
 
-	public VersionRange getVersions() {
-		return range;
-	}
+    private VersionRangeComponent versions;
+    private VersionRange range;
 
-	@Override
-	protected void createCustom(Composite body) {
-		versions = new VersionRangeComponent(body, SWT.BORDER );
-		versions.addVersionChangeListener(this);
-		versions.setVersions(range);
-		
-		GridData data = new GridData( SWT.LEFT, SWT.TOP, true, true );
-		data.horizontalSpan = 2;
-		data.widthHint = 300;
-		data.heightHint = 200;
-		versions.setLayoutData(data);
-	}
 
-	@Override
-	protected void selectionChanged(SelectionChangedEvent event) {
-		if ( event.getSelection().isEmpty() ) {
-			versions.setEnabled(false);
-		}
-		else {
-			versions.setEnabled(true);
-		}
-	}
+    public ResourceImportDialog( Shell parentShell, String title, String label, IContentProvider content,
+        ViewerFilter filter, Object scope )
+    {
+        super( parentShell, content, filter, scope, title, label, true );
+    }
 
-	public void versionsChanged(VersionRange range) {
-		this.range = range; 
-		if ( range == null ) {
-			setErrorMessage( "Invalid version" );
-		}
-		else {
-			setErrorMessage( null );
-		}
-	}
 
-	public void setVersions(VersionRange range) {
-		this.range = range;
-	}
+    public VersionRange getVersions()
+    {
+        return range;
+    }
 
-	public IPackageImport getImport() {
-		IPackageImport packageImport = ModelElementFactory.getInstance().newModelElement( IPackageImport.class );
-		packageImport.setPackageName( (String) getSelected()[0] );
-		packageImport.setVersions( getVersions() );
-		return packageImport;
-	}
+
+    @Override
+    protected void createCustom( Composite body )
+    {
+        versions = new VersionRangeComponent( body, SWT.BORDER );
+        versions.addVersionChangeListener( this );
+        versions.setVersions( range );
+
+        GridData data = new GridData( SWT.LEFT, SWT.TOP, true, true );
+        data.horizontalSpan = 2;
+        data.widthHint = 300;
+        data.heightHint = 200;
+        versions.setLayoutData( data );
+    }
+
+
+    @Override
+    protected void selectionChanged( SelectionChangedEvent event )
+    {
+        if ( event.getSelection().isEmpty() )
+        {
+            versions.setEnabled( false );
+        }
+        else
+        {
+            versions.setEnabled( true );
+        }
+    }
+
+
+    public void versionsChanged( VersionRange range )
+    {
+        this.range = range;
+        if ( range == null )
+        {
+            setErrorMessage( "Invalid version" );
+        }
+        else
+        {
+            setErrorMessage( null );
+        }
+    }
+
+
+    public void setVersions( VersionRange range )
+    {
+        this.range = range;
+    }
+
+
+    public IPackageImport getImport()
+    {
+        IPackageImport packageImport = ModelElementFactory.getInstance().newModelElement( IPackageImport.class );
+        packageImport.setPackageName( ( String ) getSelected()[0] );
+        packageImport.setVersions( getVersions() );
+        return packageImport;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ResourceSelectDialog.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ResourceSelectDialog.java
index c923377..6847cd6 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ResourceSelectDialog.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ResourceSelectDialog.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -57,316 +58,403 @@
 import org.eclipse.swt.widgets.Table;
 import org.eclipse.swt.widgets.Text;
 
-public class ResourceSelectDialog extends Dialog {
 
-	private AtomicInteger keyCheck = new AtomicInteger();
-	private ScheduledExecutorService background = Executors.newSingleThreadScheduledExecutor();
-	
-	private class UpdateViewerRunnable implements Runnable {
-		private int check;
-		public UpdateViewerRunnable(int check) {
-			this.check = check;
-		}
+public class ResourceSelectDialog extends Dialog
+{
 
-		public void run() {
-			if ( check == keyCheck.get() ) {
-				try {
-					viewer.refresh();
-				}
-				catch (SWTException e) {
-					// discard
-				}
-			}
-		}
-	}
+    private AtomicInteger keyCheck = new AtomicInteger();
+    private ScheduledExecutorService background = Executors.newSingleThreadScheduledExecutor();
 
-	private static final ISelection EMPTY_SELECTION = new ISelection() {
-		public boolean isEmpty() {
-			return true;
-		}
-	};
-	
-	private Job job;
-	
-	private boolean isCombo;
-	private String title;
-	private String selectionText;
+    private class UpdateViewerRunnable implements Runnable
+    {
+        private int check;
 
-	private StructuredViewer viewer;
-	private Combo resourceNameCombo;
-	private Table resourceNameTable;
-	private Text errorMessageText;
-	private String errorMessage;
-	
-	private ViewerFilter filter;
-	private Object[] selected;
-	
-	private Object scope;	
-	private IContentProvider content;
-	private ILabelProvider labelProvider;
 
-	public ResourceSelectDialog(Shell parentShell, IContentProvider content, ViewerFilter filter, Object scope, String title, String selectionText, boolean isCombo) {
-		super(parentShell);
-		this.title = title;
-		this.selectionText = selectionText;
-		this.content = content;
-		this.filter = filter;
-		this.scope = scope;
-		this.isCombo = isCombo;
-	}
-	
-	public void setJob(Job job) {
-		this.job = job;
-	}
-	
-	public void refreshResources() {
-		try {
-			getShell().getDisplay().asyncExec( new Runnable() {
-				public void run() {
-					try {
-						viewer.refresh();
-					}
-					catch (SWTException e) {
-						// attempt to exec after dialog closed - discard
-					}
-				}
-			});
-		}
-		catch (NullPointerException e) {
-			// attempt to exec after dialog closed - discard
-		}
-		catch (SWTException e) {
-			// attempt to exec after dialog closed - discard
-		}
-	}
+        public UpdateViewerRunnable( int check )
+        {
+            this.check = check;
+        }
 
-	/*
+
+        public void run()
+        {
+            if ( check == keyCheck.get() )
+            {
+                try
+                {
+                    viewer.refresh();
+                }
+                catch ( SWTException e )
+                {
+                    // discard
+                }
+            }
+        }
+    }
+
+    private static final ISelection EMPTY_SELECTION = new ISelection()
+    {
+        public boolean isEmpty()
+        {
+            return true;
+        }
+    };
+
+    private Job job;
+
+    private boolean isCombo;
+    private String title;
+    private String selectionText;
+
+    private StructuredViewer viewer;
+    private Combo resourceNameCombo;
+    private Table resourceNameTable;
+    private Text errorMessageText;
+    private String errorMessage;
+
+    private ViewerFilter filter;
+    private Object[] selected;
+
+    private Object scope;
+    private IContentProvider content;
+    private ILabelProvider labelProvider;
+
+
+    public ResourceSelectDialog( Shell parentShell, IContentProvider content, ViewerFilter filter, Object scope,
+        String title, String selectionText, boolean isCombo )
+    {
+        super( parentShell );
+        this.title = title;
+        this.selectionText = selectionText;
+        this.content = content;
+        this.filter = filter;
+        this.scope = scope;
+        this.isCombo = isCombo;
+    }
+
+
+    public void setJob( Job job )
+    {
+        this.job = job;
+    }
+
+
+    public void refreshResources()
+    {
+        try
+        {
+            getShell().getDisplay().asyncExec( new Runnable()
+            {
+                public void run()
+                {
+                    try
+                    {
+                        viewer.refresh();
+                    }
+                    catch ( SWTException e )
+                    {
+                        // attempt to exec after dialog closed - discard
+                    }
+                }
+            } );
+        }
+        catch ( NullPointerException e )
+        {
+            // attempt to exec after dialog closed - discard
+        }
+        catch ( SWTException e )
+        {
+            // attempt to exec after dialog closed - discard
+        }
+    }
+
+
+    /*
      * (non-Javadoc)
      * 
      * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
      */
-    protected void configureShell(Shell shell) {
-        super.configureShell(shell);
-        if (title != null) {
-			shell.setText(title);
-		}        
+    protected void configureShell( Shell shell )
+    {
+        super.configureShell( shell );
+        if ( title != null )
+        {
+            shell.setText( title );
+        }
     }
 
-	@Override
-	public void create() {
-		super.create();
-		if ( getItemCount() == 0 ) {
-			setErrorMessage( "No resources available" );
-			getButton(IDialogConstants.OK_ID).setEnabled(false);
-		}
-		else {
-			ISelection selection = selected == null ? EMPTY_SELECTION : new SingletonSelection( selected );
-			setSelected( new SelectionChangedEvent( viewer, selection ), true );
-		}
-		
-		if ( job != null ) {
-			job.schedule();
-		}
-	}
 
-	@Override
-	public boolean close() {
-		if ( job != null ) {
-			job.cancel();
-		}
-		background.shutdownNow();
-		return super.close();
-	}
+    @Override
+    public void create()
+    {
+        super.create();
+        if ( getItemCount() == 0 )
+        {
+            setErrorMessage( "No resources available" );
+            getButton( IDialogConstants.OK_ID ).setEnabled( false );
+        }
+        else
+        {
+            ISelection selection = selected == null ? EMPTY_SELECTION : new SingletonSelection( selected );
+            setSelected( new SelectionChangedEvent( viewer, selection ), true );
+        }
 
-	private int getItemCount() {
-		if ( isCombo ) {
-			return resourceNameCombo.getItemCount();
-		}
-		else {
-			return resourceNameTable.getItemCount();
-		}
-	}
-
-	@Override
-	protected Control createDialogArea(Composite parent) {
-		Composite body = (Composite) super.createDialogArea(parent);
-		
-		GridLayout layout = (GridLayout) body.getLayout();
-		layout.numColumns = 2;
-		GridData data;
-		
-		labelProvider = new ModelLabelProvider();
-		
-		Label l = new Label( body, SWT.LEFT );
-		l.setText( selectionText );
-		data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-		if ( !isCombo ) {
-			data.horizontalSpan = 2;
-		}
-		l.setLayoutData( data );
-	
-		if ( isCombo ) {
-			createCombo( body );
-		}
-		else {
-			createTable( body );
-		}
-		
-		viewer.addFilter( filter );
-		viewer.setContentProvider(content);
-		viewer.setLabelProvider( getLabelProvider() );
-		viewer.setComparator( new ViewerComparator() );
-		viewer.setInput( scope );
-		
-		viewer.addSelectionChangedListener( new ISelectionChangedListener() {
-			public void selectionChanged(SelectionChangedEvent event) {
-				setSelected(event, false);
-			}			
-		});
-	    createCustom( body );
-	    
-		errorMessageText = new Text(body, SWT.READ_ONLY | SWT.WRAP);
-		data = new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL);
-		data.horizontalSpan = 2;
-	    errorMessageText.setLayoutData(data);
-	    errorMessageText.setBackground(errorMessageText.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
-	    setErrorMessage(errorMessage);
-	    
-		return body;
-	}
-	
-    protected void createCustom(Composite body) {
-	}
-
-	private void createCombo(Composite body) {
-		resourceNameCombo = new Combo( body, SWT.SINGLE | SWT.BORDER );
-		GridData data = new GridData( GridData.HORIZONTAL_ALIGN_END);
-		data.widthHint = 200;
-		resourceNameCombo.setLayoutData( data );
-		
-		viewer = new ComboViewer(resourceNameCombo);
-	}
-
-	private void createTable(Composite body) {
-		final Text txtFilter = new Text(body, SWT.BORDER);
-		GridData data = new GridData( GridData.HORIZONTAL_ALIGN_END);
-		data.horizontalSpan = 2;
-		data.widthHint = 400;
-		txtFilter.setLayoutData(data);
-		
-		resourceNameTable = new Table( body, SWT.MULTI | SWT.BORDER );
-		data = new GridData( GridData.HORIZONTAL_ALIGN_END);
-		data.widthHint = 400;
-		data.heightHint = 400;
-		resourceNameTable.setLayoutData( data );
-		
-		viewer = new TableViewer(resourceNameTable);
-
-		txtFilter.addKeyListener( new KeyAdapter() {
-			@Override
-			public void keyReleased(KeyEvent e) {
-				switch ( e.keyCode ) {
-				case SWT.ARROW_UP:
-					scrollTable(-1);
-					break;
-				case SWT.ARROW_DOWN:
-					scrollTable(+1);
-					break;
-				default:
-					Runnable r = new UpdateViewerRunnable(keyCheck.incrementAndGet());
-					background.schedule(r, 100, TimeUnit.MILLISECONDS);
-					break;
-				}
-			}
-		});
-		
-		ViewerFilter filter = new ViewerFilter() {
-			@Override
-			public boolean select(Viewer viewer, Object parentElement,
-					Object element) {
-				return getLabelProvider().getText(element).startsWith( txtFilter.getText() );
-			}
-		};
-		
-		viewer.addFilter(filter);
-	}
-	
-	private void scrollTable(int delta) {
-		int i = resourceNameTable.getSelectionIndex();
-		
-		if ( i == -1 ) {
-			if ( delta < 0 ) { 
-				i = resourceNameTable.getItemCount() - 1;
-			}
-			else {
-				i = 0;
-			}
-		}
-		else {
-			i+=delta;
-		}
-		
-		if ( i > -1 && i < resourceNameTable.getItemCount() ) {
-			Item item = resourceNameTable.getItem(i);
-			resourceNameTable.select(i);
-			selected = new Object[] { item.getData() };
-			ISelection selection = new SingletonSelection( selected );
-			selectionChanged(new SelectionChangedEvent(viewer, selection));
-			viewer.reveal(selected);
-		}
-	}
-
-	private void setSelected(SelectionChangedEvent event, boolean reveal) {
-		if ( event.getSelection().isEmpty() ) {
-			selected = null;
-			setErrorMessage( "No resource selected" );
-		}
-		else {
-			selected = ((IStructuredSelection) event.getSelection()).toArray();
-			setErrorMessage( null );
-		}
-		
-		selectionChanged(event);
-		
-		if ( reveal && !event.getSelection().isEmpty() ) {
-			if ( resourceNameCombo != null ) {
-				IStructuredSelection sel = (IStructuredSelection) event.getSelection();
-				resourceNameCombo.select(resourceNameCombo.indexOf((String) sel.getFirstElement()));
-			}
-			else {
-				viewer.setSelection(event.getSelection(), true);
-			}
-		}
-	}
-
-	protected ILabelProvider getLabelProvider() {
-		return labelProvider;
-	}
-
-	public Object[] getSelected() {
-    	return selected;
+        if ( job != null )
+        {
+            job.schedule();
+        }
     }
-	
-	public void setSelected(Object[] selected) {
-		this.selected = selected;
-	}
-	
-	protected void selectionChanged(SelectionChangedEvent event) {
-	}
 
-	public void setErrorMessage(String errorMessage) {
-		this.errorMessage = errorMessage;
-		if (errorMessageText != null && !errorMessageText.isDisposed()) {
-			errorMessageText.setText(errorMessage == null ? " \n " : errorMessage); 
-			boolean hasError = errorMessage != null && (StringConverter.removeWhiteSpaces(errorMessage)).length() > 0;
-			errorMessageText.setEnabled(hasError);
-			errorMessageText.setVisible(hasError);
-			errorMessageText.getParent().update();
-			Control ok = getButton(IDialogConstants.OK_ID);
-			if (ok != null) {
-				ok.setEnabled(!hasError);
-			}
-		}
-	}
+
+    @Override
+    public boolean close()
+    {
+        if ( job != null )
+        {
+            job.cancel();
+        }
+        background.shutdownNow();
+        return super.close();
+    }
+
+
+    private int getItemCount()
+    {
+        if ( isCombo )
+        {
+            return resourceNameCombo.getItemCount();
+        }
+        else
+        {
+            return resourceNameTable.getItemCount();
+        }
+    }
+
+
+    @Override
+    protected Control createDialogArea( Composite parent )
+    {
+        Composite body = ( Composite ) super.createDialogArea( parent );
+
+        GridLayout layout = ( GridLayout ) body.getLayout();
+        layout.numColumns = 2;
+        GridData data;
+
+        labelProvider = new ModelLabelProvider();
+
+        Label l = new Label( body, SWT.LEFT );
+        l.setText( selectionText );
+        data = new GridData( GridData.HORIZONTAL_ALIGN_BEGINNING );
+        if ( !isCombo )
+        {
+            data.horizontalSpan = 2;
+        }
+        l.setLayoutData( data );
+
+        if ( isCombo )
+        {
+            createCombo( body );
+        }
+        else
+        {
+            createTable( body );
+        }
+
+        viewer.addFilter( filter );
+        viewer.setContentProvider( content );
+        viewer.setLabelProvider( getLabelProvider() );
+        viewer.setComparator( new ViewerComparator() );
+        viewer.setInput( scope );
+
+        viewer.addSelectionChangedListener( new ISelectionChangedListener()
+        {
+            public void selectionChanged( SelectionChangedEvent event )
+            {
+                setSelected( event, false );
+            }
+        } );
+        createCustom( body );
+
+        errorMessageText = new Text( body, SWT.READ_ONLY | SWT.WRAP );
+        data = new GridData( GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL );
+        data.horizontalSpan = 2;
+        errorMessageText.setLayoutData( data );
+        errorMessageText.setBackground( errorMessageText.getDisplay().getSystemColor( SWT.COLOR_WIDGET_BACKGROUND ) );
+        setErrorMessage( errorMessage );
+
+        return body;
+    }
+
+
+    protected void createCustom( Composite body )
+    {
+    }
+
+
+    private void createCombo( Composite body )
+    {
+        resourceNameCombo = new Combo( body, SWT.SINGLE | SWT.BORDER );
+        GridData data = new GridData( GridData.HORIZONTAL_ALIGN_END );
+        data.widthHint = 200;
+        resourceNameCombo.setLayoutData( data );
+
+        viewer = new ComboViewer( resourceNameCombo );
+    }
+
+
+    private void createTable( Composite body )
+    {
+        final Text txtFilter = new Text( body, SWT.BORDER );
+        GridData data = new GridData( GridData.HORIZONTAL_ALIGN_END );
+        data.horizontalSpan = 2;
+        data.widthHint = 400;
+        txtFilter.setLayoutData( data );
+
+        resourceNameTable = new Table( body, SWT.MULTI | SWT.BORDER );
+        data = new GridData( GridData.HORIZONTAL_ALIGN_END );
+        data.widthHint = 400;
+        data.heightHint = 400;
+        resourceNameTable.setLayoutData( data );
+
+        viewer = new TableViewer( resourceNameTable );
+
+        txtFilter.addKeyListener( new KeyAdapter()
+        {
+            @Override
+            public void keyReleased( KeyEvent e )
+            {
+                switch ( e.keyCode )
+                {
+                    case SWT.ARROW_UP:
+                        scrollTable( -1 );
+                        break;
+                    case SWT.ARROW_DOWN:
+                        scrollTable( +1 );
+                        break;
+                    default:
+                        Runnable r = new UpdateViewerRunnable( keyCheck.incrementAndGet() );
+                        background.schedule( r, 100, TimeUnit.MILLISECONDS );
+                        break;
+                }
+            }
+        } );
+
+        ViewerFilter filter = new ViewerFilter()
+        {
+            @Override
+            public boolean select( Viewer viewer, Object parentElement, Object element )
+            {
+                return getLabelProvider().getText( element ).startsWith( txtFilter.getText() );
+            }
+        };
+
+        viewer.addFilter( filter );
+    }
+
+
+    private void scrollTable( int delta )
+    {
+        int i = resourceNameTable.getSelectionIndex();
+
+        if ( i == -1 )
+        {
+            if ( delta < 0 )
+            {
+                i = resourceNameTable.getItemCount() - 1;
+            }
+            else
+            {
+                i = 0;
+            }
+        }
+        else
+        {
+            i += delta;
+        }
+
+        if ( i > -1 && i < resourceNameTable.getItemCount() )
+        {
+            Item item = resourceNameTable.getItem( i );
+            resourceNameTable.select( i );
+            selected = new Object[]
+                { item.getData() };
+            ISelection selection = new SingletonSelection( selected );
+            selectionChanged( new SelectionChangedEvent( viewer, selection ) );
+            viewer.reveal( selected );
+        }
+    }
+
+
+    private void setSelected( SelectionChangedEvent event, boolean reveal )
+    {
+        if ( event.getSelection().isEmpty() )
+        {
+            selected = null;
+            setErrorMessage( "No resource selected" );
+        }
+        else
+        {
+            selected = ( ( IStructuredSelection ) event.getSelection() ).toArray();
+            setErrorMessage( null );
+        }
+
+        selectionChanged( event );
+
+        if ( reveal && !event.getSelection().isEmpty() )
+        {
+            if ( resourceNameCombo != null )
+            {
+                IStructuredSelection sel = ( IStructuredSelection ) event.getSelection();
+                resourceNameCombo.select( resourceNameCombo.indexOf( ( String ) sel.getFirstElement() ) );
+            }
+            else
+            {
+                viewer.setSelection( event.getSelection(), true );
+            }
+        }
+    }
+
+
+    protected ILabelProvider getLabelProvider()
+    {
+        return labelProvider;
+    }
+
+
+    public Object[] getSelected()
+    {
+        return selected;
+    }
+
+
+    public void setSelected( Object[] selected )
+    {
+        this.selected = selected;
+    }
+
+
+    protected void selectionChanged( SelectionChangedEvent event )
+    {
+    }
+
+
+    public void setErrorMessage( String errorMessage )
+    {
+        this.errorMessage = errorMessage;
+        if ( errorMessageText != null && !errorMessageText.isDisposed() )
+        {
+            errorMessageText.setText( errorMessage == null ? " \n " : errorMessage );
+            boolean hasError = errorMessage != null
+                && ( StringConverter.removeWhiteSpaces( errorMessage ) ).length() > 0;
+            errorMessageText.setEnabled( hasError );
+            errorMessageText.setVisible( hasError );
+            errorMessageText.getParent().update();
+            Control ok = getButton( IDialogConstants.OK_ID );
+            if ( ok != null )
+            {
+                ok.setEnabled( !hasError );
+            }
+        }
+    }
 
 }
\ No newline at end of file
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/SigilProjectEditorPart.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/SigilProjectEditorPart.java
index 308a2ab..6800ac1 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/SigilProjectEditorPart.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/SigilProjectEditorPart.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import java.lang.reflect.InvocationTargetException;
 import java.util.Collections;
 import java.util.HashSet;
@@ -58,242 +59,324 @@
 import org.eclipse.ui.forms.editor.FormEditor;
 import org.eclipse.ui.forms.editor.IFormPage;
 
-public class SigilProjectEditorPart extends FormEditor implements IResourceChangeListener {
 
-	private final Set<IModelElement> unresolvedElements = Collections.synchronizedSet(new HashSet<IModelElement>());
-	private ISigilProjectModel project;
-	private volatile boolean saving = false;
-	private int dependenciesPageIndex;
-	
-	// XXX-FIXME-XXX
-	private Image errorImage = null; //SigilUI.imageDescriptorFromPlugin(SigilUI.PLUGIN_ID, "icons/error.gif").createImage();
-	private PropertiesForm textPage;
-	
-    public IProject getProject() {
-        IFileEditorInput fileInput = (IFileEditorInput) getEditorInput();
+public class SigilProjectEditorPart extends FormEditor implements IResourceChangeListener
+{
+
+    private final Set<IModelElement> unresolvedElements = Collections.synchronizedSet( new HashSet<IModelElement>() );
+    private ISigilProjectModel project;
+    private volatile boolean saving = false;
+    private int dependenciesPageIndex;
+
+    // XXX-FIXME-XXX
+    private Image errorImage = null; //SigilUI.imageDescriptorFromPlugin(SigilUI.PLUGIN_ID, "icons/error.gif").createImage();
+    private PropertiesForm textPage;
+
+
+    public IProject getProject()
+    {
+        IFileEditorInput fileInput = ( IFileEditorInput ) getEditorInput();
         return fileInput.getFile().getProject();
     }
-    
+
+
     /* (non-Javadoc)
      * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
      */
     @Override
-    public void doSave(IProgressMonitor monitor) {
-		monitor.beginTask("Saving", IProgressMonitor.UNKNOWN);
-		try {
-			saving = true;
-			new ProgressMonitorDialog(getSite().getShell()).run(true, true, new IRunnableWithProgress() {
-				public void run(final IProgressMonitor monitor) throws InvocationTargetException,
-						InterruptedException {
-					try {
-						if ( textPage.isDirty() ) {
-							SigilUI.runInUISync(new Runnable() {
-								public void run() {
-									textPage.doSave(monitor);
-								}								
-							});
-							project.setBundle(null);
-						}
-						else if ( isDirty() ) {
-							commitPages(true);
-							project.save(monitor);
-							SigilUI.runInUISync(new Runnable() {
-								public void run() {
-									editorDirtyStateChanged();
-								}								
-							});
-						}
-						
-						monitor.done();
-					} catch (CoreException e) {
-						throw new InvocationTargetException(e);
-					}
-				}
-			});
-		} catch (InvocationTargetException e) {
-			SigilCore.error("Failed to save " + project, e.getTargetException());
-		} catch (InterruptedException e) {
-			monitor.setCanceled(true);
-			return;
-		} finally {
-			saving = false;
-		}
-		monitor.done();		
+    public void doSave( IProgressMonitor monitor )
+    {
+        monitor.beginTask( "Saving", IProgressMonitor.UNKNOWN );
+        try
+        {
+            saving = true;
+            new ProgressMonitorDialog( getSite().getShell() ).run( true, true, new IRunnableWithProgress()
+            {
+                public void run( final IProgressMonitor monitor ) throws InvocationTargetException,
+                    InterruptedException
+                {
+                    try
+                    {
+                        if ( textPage.isDirty() )
+                        {
+                            SigilUI.runInUISync( new Runnable()
+                            {
+                                public void run()
+                                {
+                                    textPage.doSave( monitor );
+                                }
+                            } );
+                            project.setBundle( null );
+                        }
+                        else if ( isDirty() )
+                        {
+                            commitPages( true );
+                            project.save( monitor );
+                            SigilUI.runInUISync( new Runnable()
+                            {
+                                public void run()
+                                {
+                                    editorDirtyStateChanged();
+                                }
+                            } );
+                        }
+
+                        monitor.done();
+                    }
+                    catch ( CoreException e )
+                    {
+                        throw new InvocationTargetException( e );
+                    }
+                }
+            } );
+        }
+        catch ( InvocationTargetException e )
+        {
+            SigilCore.error( "Failed to save " + project, e.getTargetException() );
+        }
+        catch ( InterruptedException e )
+        {
+            monitor.setCanceled( true );
+            return;
+        }
+        finally
+        {
+            saving = false;
+        }
+        monitor.done();
     }
-    
-	/* (non-Javadoc)
+
+
+    /* (non-Javadoc)
      * @see org.eclipse.ui.forms.editor.FormEditor#addPages()
      */
     @Override
-    protected void addPages() {
-        try {
-            addPage(new OverviewForm(this, project));
-			addPage(new ContentsForm(this, project));
-			dependenciesPageIndex = addPage(new DependenciesForm(this, project, unresolvedElements));
-			addPage(new ExportsForm(this, project));
-			textPage = new PropertiesForm(this, project);
-			addPage(textPage, getEditorInput());
-			setPartName(project.getSymbolicName());
-			
-			refreshTabImages();
+    protected void addPages()
+    {
+        try
+        {
+            addPage( new OverviewForm( this, project ) );
+            addPage( new ContentsForm( this, project ) );
+            dependenciesPageIndex = addPage( new DependenciesForm( this, project, unresolvedElements ) );
+            addPage( new ExportsForm( this, project ) );
+            textPage = new PropertiesForm( this, project );
+            addPage( textPage, getEditorInput() );
+            setPartName( project.getSymbolicName() );
+
+            refreshTabImages();
         }
-        catch (PartInitException e) {
-        	SigilCore.error( "Failed to build " + this, e );
-		}
+        catch ( PartInitException e )
+        {
+            SigilCore.error( "Failed to build " + this, e );
+        }
     }
-    
-    protected void refreshTabImages() {
-	    if(unresolvedElements.isEmpty()) {
-	    	setPageImage(dependenciesPageIndex, null);
-	    } else {
-	    	setPageImage(dependenciesPageIndex, errorImage);
-	    }
+
+
+    protected void refreshTabImages()
+    {
+        if ( unresolvedElements.isEmpty() )
+        {
+            setPageImage( dependenciesPageIndex, null );
+        }
+        else
+        {
+            setPageImage( dependenciesPageIndex, errorImage );
+        }
     }
-    
+
+
     /* (non-Javadoc)
      * @see org.eclipse.ui.part.EditorPart#doSaveAs()
      */
     @Override
-    public void doSaveAs() {
-    	// save as not allowed
+    public void doSaveAs()
+    {
+        // save as not allowed
     }
 
+
     /* (non-Javadoc)
      * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
      */
     @Override
-    public boolean isSaveAsAllowed() {
+    public boolean isSaveAsAllowed()
+    {
         return false;
     }
-    
+
+
     @Override
-    public void dispose() {
-    	ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
-    	errorImage.dispose();
-    	super.dispose();
+    public void dispose()
+    {
+        ResourcesPlugin.getWorkspace().removeResourceChangeListener( this );
+        errorImage.dispose();
+        super.dispose();
     }
 
-	public void resourceChanged(IResourceChangeEvent event) {
-		IResourceDelta delta = event.getDelta();
-		final IFile editorFile = ((IFileEditorInput) getEditorInput()).getFile();
-		try {
-			delta.accept(new IResourceDeltaVisitor() {
-				public boolean visit(IResourceDelta delta) throws CoreException {
-					int kind = delta.getKind();
-					IResource resource = delta.getResource();
-					if(resource instanceof IProject) {
-						if(!editorFile.getProject().equals(resource)) {
-							return false;
-						}
-						if(kind == IResourceDelta.CHANGED && (delta.getFlags() & IResourceDelta.MARKERS) > 0) {
-							loadUnresolvedDependencies();
-							refreshAllPages();
-						}
-						return true;
-					}
-					
-					if(resource instanceof IFile) {
-						IFile affectedFile = (IFile) resource;
-							if(affectedFile.equals(editorFile)) {
-							switch (kind) {
-							case IResourceDelta.REMOVED:
-								close(false);
-								break;
-							case IResourceDelta.CHANGED:
-								if(!saving) {
-									reload();
-								}
-								SigilUI.runInUISync( new Runnable() {
-									public void run() {
-										setPartName(project.getSymbolicName());								
-									} 									
-								} );
-								break;
-							}
-						}
-						// Recurse no more
-						return false;
-					}
-					
-					return true;
-				}
-			});
-		} catch (CoreException e) {
-			ErrorDialog.openError(getSite().getShell(), "Error", null, e.getStatus());
-		}
-	}
-	
-	protected void refreshAllPages() {
-		Runnable op = new Runnable() {
-			public void run() {
-				for(Iterator<?> iter = pages.iterator(); iter.hasNext(); ) {
-					IFormPage page = (IFormPage) iter.next();
-					if(page != null) {
-						IManagedForm managedForm = page.getManagedForm();
-						if(managedForm != null) {
-							managedForm.refresh();
-							IFormPart[] parts = managedForm.getParts();
-							for (IFormPart part : parts) {
-								part.refresh();
-							}
-						}
-					}
-				}
-				firePropertyChange(IEditorPart.PROP_DIRTY);
-				setPartName(project.getSymbolicName());
-				refreshTabImages();
-			}
-		};
-		getSite().getShell().getDisplay().syncExec(op);
-	}
-	
-	protected void reload() {
-		project.setBundle(null);
-		refreshAllPages();
-	}
-	
-	@Override
-	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
-		super.init(site, input);
-		
-        try {
-			this.project = SigilCore.create(getProject());
-		} catch (CoreException e) {
-			throw new PartInitException("Error creating Sigil project", e);
-		}
-		
-    	ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
-		
-		if(input instanceof IFileEditorInput) {
-			try {
-				loadUnresolvedDependencies();
-			} catch (CoreException e) {
-				throw new PartInitException("Error retrieving dependency markers", e);
-			}
-		}
-	}
 
-	private void loadUnresolvedDependencies() throws CoreException {
-		ModelElementFactory factory = ModelElementFactory.getInstance();
-		IMarker[] markers = getProject().findMarkers(SigilCore.MARKER_UNRESOLVED_DEPENDENCY, true, IResource.DEPTH_ONE);
-		unresolvedElements.clear();
-		
-		for (IMarker marker : markers) {
-			String elementName = (String) marker.getAttribute("element");
-			String versionRangeStr = (String) marker.getAttribute("versionRange");
-			if(elementName != null && versionRangeStr != null) {
-				if(marker.getType().equals(SigilCore.MARKER_UNRESOLVED_IMPORT_PACKAGE)) {
-					IPackageImport pkgImport = factory.newModelElement(IPackageImport.class);
-					pkgImport.setPackageName(elementName);
-					pkgImport.setVersions(VersionRange.parseVersionRange(versionRangeStr));
-					unresolvedElements.add(pkgImport);
-				} else if(marker.getType().equals(SigilCore.MARKER_UNRESOLVED_REQUIRE_BUNDLE)) {
-					IRequiredBundle req = factory.newModelElement(IRequiredBundle.class);
-					req.setSymbolicName(elementName);
-					req.setVersions(VersionRange.parseVersionRange(versionRangeStr));
-					unresolvedElements.add(req);
-				}
-			}
-		}
-	}
+    public void resourceChanged( IResourceChangeEvent event )
+    {
+        IResourceDelta delta = event.getDelta();
+        final IFile editorFile = ( ( IFileEditorInput ) getEditorInput() ).getFile();
+        try
+        {
+            delta.accept( new IResourceDeltaVisitor()
+            {
+                public boolean visit( IResourceDelta delta ) throws CoreException
+                {
+                    int kind = delta.getKind();
+                    IResource resource = delta.getResource();
+                    if ( resource instanceof IProject )
+                    {
+                        if ( !editorFile.getProject().equals( resource ) )
+                        {
+                            return false;
+                        }
+                        if ( kind == IResourceDelta.CHANGED && ( delta.getFlags() & IResourceDelta.MARKERS ) > 0 )
+                        {
+                            loadUnresolvedDependencies();
+                            refreshAllPages();
+                        }
+                        return true;
+                    }
+
+                    if ( resource instanceof IFile )
+                    {
+                        IFile affectedFile = ( IFile ) resource;
+                        if ( affectedFile.equals( editorFile ) )
+                        {
+                            switch ( kind )
+                            {
+                                case IResourceDelta.REMOVED:
+                                    close( false );
+                                    break;
+                                case IResourceDelta.CHANGED:
+                                    if ( !saving )
+                                    {
+                                        reload();
+                                    }
+                                    SigilUI.runInUISync( new Runnable()
+                                    {
+                                        public void run()
+                                        {
+                                            setPartName( project.getSymbolicName() );
+                                        }
+                                    } );
+                                    break;
+                            }
+                        }
+                        // Recurse no more
+                        return false;
+                    }
+
+                    return true;
+                }
+            } );
+        }
+        catch ( CoreException e )
+        {
+            ErrorDialog.openError( getSite().getShell(), "Error", null, e.getStatus() );
+        }
+    }
+
+
+    protected void refreshAllPages()
+    {
+        Runnable op = new Runnable()
+        {
+            public void run()
+            {
+                for ( Iterator<?> iter = pages.iterator(); iter.hasNext(); )
+                {
+                    IFormPage page = ( IFormPage ) iter.next();
+                    if ( page != null )
+                    {
+                        IManagedForm managedForm = page.getManagedForm();
+                        if ( managedForm != null )
+                        {
+                            managedForm.refresh();
+                            IFormPart[] parts = managedForm.getParts();
+                            for ( IFormPart part : parts )
+                            {
+                                part.refresh();
+                            }
+                        }
+                    }
+                }
+                firePropertyChange( IEditorPart.PROP_DIRTY );
+                setPartName( project.getSymbolicName() );
+                refreshTabImages();
+            }
+        };
+        getSite().getShell().getDisplay().syncExec( op );
+    }
+
+
+    protected void reload()
+    {
+        project.setBundle( null );
+        refreshAllPages();
+    }
+
+
+    @Override
+    public void init( IEditorSite site, IEditorInput input ) throws PartInitException
+    {
+        super.init( site, input );
+
+        try
+        {
+            this.project = SigilCore.create( getProject() );
+        }
+        catch ( CoreException e )
+        {
+            throw new PartInitException( "Error creating Sigil project", e );
+        }
+
+        ResourcesPlugin.getWorkspace().addResourceChangeListener( this, IResourceChangeEvent.POST_CHANGE );
+
+        if ( input instanceof IFileEditorInput )
+        {
+            try
+            {
+                loadUnresolvedDependencies();
+            }
+            catch ( CoreException e )
+            {
+                throw new PartInitException( "Error retrieving dependency markers", e );
+            }
+        }
+    }
+
+
+    private void loadUnresolvedDependencies() throws CoreException
+    {
+        ModelElementFactory factory = ModelElementFactory.getInstance();
+        IMarker[] markers = getProject()
+            .findMarkers( SigilCore.MARKER_UNRESOLVED_DEPENDENCY, true, IResource.DEPTH_ONE );
+        unresolvedElements.clear();
+
+        for ( IMarker marker : markers )
+        {
+            String elementName = ( String ) marker.getAttribute( "element" );
+            String versionRangeStr = ( String ) marker.getAttribute( "versionRange" );
+            if ( elementName != null && versionRangeStr != null )
+            {
+                if ( marker.getType().equals( SigilCore.MARKER_UNRESOLVED_IMPORT_PACKAGE ) )
+                {
+                    IPackageImport pkgImport = factory.newModelElement( IPackageImport.class );
+                    pkgImport.setPackageName( elementName );
+                    pkgImport.setVersions( VersionRange.parseVersionRange( versionRangeStr ) );
+                    unresolvedElements.add( pkgImport );
+                }
+                else if ( marker.getType().equals( SigilCore.MARKER_UNRESOLVED_REQUIRE_BUNDLE ) )
+                {
+                    IRequiredBundle req = factory.newModelElement( IRequiredBundle.class );
+                    req.setSymbolicName( elementName );
+                    req.setVersions( VersionRange.parseVersionRange( versionRangeStr ) );
+                    unresolvedElements.add( req );
+                }
+            }
+        }
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/SigilSourcePage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/SigilSourcePage.java
index 8391f37..266da0e 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/SigilSourcePage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/SigilSourcePage.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jface.text.IDocument;
@@ -33,83 +34,117 @@
 import org.eclipse.ui.forms.editor.IFormPage;
 import org.eclipse.ui.ide.IDE;
 
-public class SigilSourcePage extends TextEditor implements IFormPage {
-	private final String id;
-	private int index;
-	private SigilProjectEditorPart editor;
-	private boolean active;
-	private Control control;
-	
-	public SigilSourcePage(String id) {
-		this.id = id;
-	}
 
-	@Override
-	public void createPartControl(Composite parent) {
-		super.createPartControl(parent);
-		Control[] children = parent.getChildren();
-		control = children[children.length - 1];
-		getSourceViewer().addTextListener( new ITextListener() {
-			public void textChanged(TextEvent event) {
-				if ( editor != null ) {
-					editor.refreshAllPages();
-				}
-			}
-		});
-		//PlatformUI.getWorkbench().getHelpSystem().setHelp(fControl, IHelpContextIds.MANIFEST_SOURCE_PAGE);
-	}
+public class SigilSourcePage extends TextEditor implements IFormPage
+{
+    private final String id;
+    private int index;
+    private SigilProjectEditorPart editor;
+    private boolean active;
+    private Control control;
 
-	public void initialize(FormEditor editor) {
-		this.editor = (SigilProjectEditorPart) editor;
-	}
 
-	public FormEditor getEditor() {
-		return editor;
-	}
+    public SigilSourcePage( String id )
+    {
+        this.id = id;
+    }
 
-	public String getId() {
-		return id;
-	}
 
-	public int getIndex() {
-		return index;
-	}
-	
-	public void setIndex(int index) {
-		this.index = index;
-	}	
+    @Override
+    public void createPartControl( Composite parent )
+    {
+        super.createPartControl( parent );
+        Control[] children = parent.getChildren();
+        control = children[children.length - 1];
+        getSourceViewer().addTextListener( new ITextListener()
+        {
+            public void textChanged( TextEvent event )
+            {
+                if ( editor != null )
+                {
+                    editor.refreshAllPages();
+                }
+            }
+        } );
+        //PlatformUI.getWorkbench().getHelpSystem().setHelp(fControl, IHelpContextIds.MANIFEST_SOURCE_PAGE);
+    }
 
-	public boolean isActive() {
-		return active;
-	}
 
-	public void setActive(boolean active) {
-		this.active = active;
-	}
-	
-	public Control getPartControl() {
-		return control;
-	}
+    public void initialize( FormEditor editor )
+    {
+        this.editor = ( SigilProjectEditorPart ) editor;
+    }
 
-	public boolean selectReveal(Object object) {
-		if (object instanceof IMarker) {
-			IDE.gotoMarker(this, (IMarker) object);
-			return true;
-		}
-		return false;
-	}
 
-	// static impls
-	public boolean isEditor() {
-		return true;
-	}
+    public FormEditor getEditor()
+    {
+        return editor;
+    }
 
-	public boolean canLeaveThePage() {
-		return true;
-	}
 
-	public IManagedForm getManagedForm() {
-		// this is not a form
-		return null;
-	}
+    public String getId()
+    {
+        return id;
+    }
+
+
+    public int getIndex()
+    {
+        return index;
+    }
+
+
+    public void setIndex( int index )
+    {
+        this.index = index;
+    }
+
+
+    public boolean isActive()
+    {
+        return active;
+    }
+
+
+    public void setActive( boolean active )
+    {
+        this.active = active;
+    }
+
+
+    public Control getPartControl()
+    {
+        return control;
+    }
+
+
+    public boolean selectReveal( Object object )
+    {
+        if ( object instanceof IMarker )
+        {
+            IDE.gotoMarker( this, ( IMarker ) object );
+            return true;
+        }
+        return false;
+    }
+
+
+    // static impls
+    public boolean isEditor()
+    {
+        return true;
+    }
+
+
+    public boolean canLeaveThePage()
+    {
+        return true;
+    }
+
+
+    public IManagedForm getManagedForm()
+    {
+        // this is not a form
+        return null;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/TestingSection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/TestingSection.java
index ae751e0..8fb685c 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/TestingSection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/TestingSection.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.apache.felix.sigil.ui.eclipse.ui.form.SigilPage;
 import org.apache.felix.sigil.ui.eclipse.ui.form.SigilSection;
@@ -35,62 +36,80 @@
 import org.eclipse.ui.forms.widgets.Hyperlink;
 import org.eclipse.ui.forms.widgets.Section;
 
-public class TestingSection extends SigilSection {
-	
-	public TestingSection(SigilPage page, Composite parent, ISigilProjectModel project) throws CoreException {
-		super( page, parent, project );
-	}    
 
-    protected void createSection(Section section,FormToolkit toolkit ) {
-        setTitle("Testing");
-        
-		Composite body = createTableWrapBody(1, toolkit);
+public class TestingSection extends SigilSection
+{
 
-        toolkit.createLabel( body, "Test this project by launching a separate Newton application:" );
-        
-        Hyperlink launch = toolkit.createHyperlink( body, "Launch a newton container", SWT.NULL );
-        launch.setHref( "launchShortcut.run.org.cauldron.sigil.launching.shortcut" );
-        launch.addHyperlinkListener(this);
-        
-        Hyperlink debug = toolkit.createHyperlink( body, "Debug a newton container", SWT.NULL );
-        debug.setHref( "launchShortcut.debug.org.cauldron.sigil.launching.shortcut" );
-        debug.addHyperlinkListener(this);
+    public TestingSection( SigilPage page, Composite parent, ISigilProjectModel project ) throws CoreException
+    {
+        super( page, parent, project );
     }
 
-	public void linkActivated(HyperlinkEvent e) {
-		String href = (String) e.getHref();
-		if (href.startsWith("launchShortcut.")) { //$NON-NLS-1$
-			href = href.substring(15);
-			int index = href.indexOf('.');
-			if (index < 0)
-				return;  // error.  Format of href should be launchShortcut.<mode>.<launchShortcutId>
-			String mode = href.substring(0, index);
-			String id = href.substring(index + 1); 
 
-			//getEditor().doSave(null);
-			
-			IExtensionRegistry registry = Platform.getExtensionRegistry();
-			IConfigurationElement[] elements = registry.getConfigurationElementsFor("org.eclipse.debug.ui.launchShortcuts"); //$NON-NLS-1$
-			for (int i = 0; i < elements.length; i++) {
-				if (id.equals(elements[i].getAttribute("id"))) //$NON-NLS-1$
-					try {
-						ILaunchShortcut shortcut = (ILaunchShortcut)elements[i].createExecutableExtension("class"); //$NON-NLS-1$
-						// preLaunch();
-						shortcut.launch(new StructuredSelection(getLaunchObject()), mode);
-					} catch (CoreException e1) {
-						e1.printStackTrace();
-					}
-			}
-		}
-	}
+    protected void createSection( Section section, FormToolkit toolkit )
+    {
+        setTitle( "Testing" );
 
-	private Object getLaunchObject() {
-		return getProjectModel().getProject();
-	}
+        Composite body = createTableWrapBody( 1, toolkit );
 
-	public void linkEntered(HyperlinkEvent e) {
-	}
+        toolkit.createLabel( body, "Test this project by launching a separate Newton application:" );
 
-	public void linkExited(HyperlinkEvent e) {
-	}
+        Hyperlink launch = toolkit.createHyperlink( body, "Launch a newton container", SWT.NULL );
+        launch.setHref( "launchShortcut.run.org.cauldron.sigil.launching.shortcut" );
+        launch.addHyperlinkListener( this );
+
+        Hyperlink debug = toolkit.createHyperlink( body, "Debug a newton container", SWT.NULL );
+        debug.setHref( "launchShortcut.debug.org.cauldron.sigil.launching.shortcut" );
+        debug.addHyperlinkListener( this );
+    }
+
+
+    public void linkActivated( HyperlinkEvent e )
+    {
+        String href = ( String ) e.getHref();
+        if ( href.startsWith( "launchShortcut." ) ) { //$NON-NLS-1$
+            href = href.substring( 15 );
+            int index = href.indexOf( '.' );
+            if ( index < 0 )
+                return; // error.  Format of href should be launchShortcut.<mode>.<launchShortcutId>
+            String mode = href.substring( 0, index );
+            String id = href.substring( index + 1 );
+
+            //getEditor().doSave(null);
+
+            IExtensionRegistry registry = Platform.getExtensionRegistry();
+            IConfigurationElement[] elements = registry
+                .getConfigurationElementsFor( "org.eclipse.debug.ui.launchShortcuts" ); //$NON-NLS-1$
+            for ( int i = 0; i < elements.length; i++ )
+            {
+                if ( id.equals( elements[i].getAttribute( "id" ) ) ) //$NON-NLS-1$
+                    try
+                    {
+                        ILaunchShortcut shortcut = ( ILaunchShortcut ) elements[i].createExecutableExtension( "class" ); //$NON-NLS-1$
+                        // preLaunch();
+                        shortcut.launch( new StructuredSelection( getLaunchObject() ), mode );
+                    }
+                    catch ( CoreException e1 )
+                    {
+                        e1.printStackTrace();
+                    }
+            }
+        }
+    }
+
+
+    private Object getLaunchObject()
+    {
+        return getProjectModel().getProject();
+    }
+
+
+    public void linkEntered( HyperlinkEvent e )
+    {
+    }
+
+
+    public void linkExited( HyperlinkEvent e )
+    {
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ToolsSection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ToolsSection.java
index 7068562..8b0cd4b 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ToolsSection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/ToolsSection.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.apache.felix.sigil.ui.eclipse.actions.PruneProjectDependenciesAction;
 import org.apache.felix.sigil.ui.eclipse.actions.ResolveProjectDependenciesAction;
@@ -32,51 +33,68 @@
 import org.eclipse.ui.forms.widgets.Hyperlink;
 import org.eclipse.ui.forms.widgets.Section;
 
-public class ToolsSection extends SigilSection {
-	
-	public ToolsSection(SigilPage page, Composite parent, ISigilProjectModel project) throws CoreException {
-		super( page, parent, project );
-	}    
 
-    protected void createSection(Section section,FormToolkit toolkit ) {
-        setTitle("Tools");
-        
-		Composite body = createTableWrapBody(1, toolkit);
+public class ToolsSection extends SigilSection
+{
 
-        toolkit.createLabel( body, "Tools to help manage this project:" );
-        
-        Hyperlink launch = toolkit.createHyperlink( body, "Resolve missing dependencies", SWT.NULL );
-        launch.setHref( "resolve" );
-        launch.addHyperlinkListener(this);
-        
-        Hyperlink debug = toolkit.createHyperlink( body, "Prune unused dependencies", SWT.NULL );
-        debug.setHref( "prune" );
-        debug.addHyperlinkListener(this);
+    public ToolsSection( SigilPage page, Composite parent, ISigilProjectModel project ) throws CoreException
+    {
+        super( page, parent, project );
     }
 
-	public void linkActivated(HyperlinkEvent e) {
-		String href = (String) e.getHref();
-		if ( "resolve".equals( href ) ) {
-			handleResolve();
-		}
-		else if ( "prune".equals( href ) ) {
-			handlePrune();
-		}
-	}
 
-	private void handlePrune() {
-		new PruneProjectDependenciesAction(getProjectModel()).run();
-	}
+    protected void createSection( Section section, FormToolkit toolkit )
+    {
+        setTitle( "Tools" );
 
-	private void handleResolve() {
-		final ISigilProjectModel project = getProjectModel();
-		new ResolveProjectDependenciesAction(project, true).run();
-	}
+        Composite body = createTableWrapBody( 1, toolkit );
 
-	public void linkEntered(HyperlinkEvent e) {
-	}
+        toolkit.createLabel( body, "Tools to help manage this project:" );
 
-	public void linkExited(HyperlinkEvent e) {
-	}
-	
+        Hyperlink launch = toolkit.createHyperlink( body, "Resolve missing dependencies", SWT.NULL );
+        launch.setHref( "resolve" );
+        launch.addHyperlinkListener( this );
+
+        Hyperlink debug = toolkit.createHyperlink( body, "Prune unused dependencies", SWT.NULL );
+        debug.setHref( "prune" );
+        debug.addHyperlinkListener( this );
+    }
+
+
+    public void linkActivated( HyperlinkEvent e )
+    {
+        String href = ( String ) e.getHref();
+        if ( "resolve".equals( href ) )
+        {
+            handleResolve();
+        }
+        else if ( "prune".equals( href ) )
+        {
+            handlePrune();
+        }
+    }
+
+
+    private void handlePrune()
+    {
+        new PruneProjectDependenciesAction( getProjectModel() ).run();
+    }
+
+
+    private void handleResolve()
+    {
+        final ISigilProjectModel project = getProjectModel();
+        new ResolveProjectDependenciesAction( project, true ).run();
+    }
+
+
+    public void linkEntered( HyperlinkEvent e )
+    {
+    }
+
+
+    public void linkExited( HyperlinkEvent e )
+    {
+    }
+
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/VersionRangeComponent.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/VersionRangeComponent.java
index f07d3c1..3f1cd60 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/VersionRangeComponent.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/VersionRangeComponent.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import java.util.HashSet;
 import java.util.Set;
 
@@ -38,214 +39,275 @@
 import org.eclipse.swt.widgets.Text;
 import org.osgi.framework.Version;
 
-public class VersionRangeComponent extends Composite {
-	private VersionRange versions = VersionRange.ANY_VERSION;
-	
-	private Button specificButton;
-	
-	private Text specificText;
-	private Button rangeButton;
-	private Text minimumText;
-	private Text maximumText;
-	private Button minInclusiveButton;
-	private Button maxInclusiveButton;
-	
-	private Set<VersionsChangeListener> listeners = new HashSet<VersionsChangeListener>();
-	private Set<IValidationListener> validationListeners = new HashSet<IValidationListener>();
-	
-	public VersionRangeComponent(Composite parent, int style) {
-		super( parent, style );
-		createComponents(this);
-	}
-	
-	public void addVersionChangeListener(VersionsChangeListener listener) {
-		synchronized(listeners) {
-			listeners.add( listener );
-		}
-	}
-	
-	public void removeVersionChangeListener(VersionsChangeListener listener) {
-		synchronized(listeners) {
-			listeners.remove( listener );
-		}
-	}
-	
-	public void addValidationListener(IValidationListener listener) {
-		validationListeners.add(listener);
-	}
-	
-	public void removeValidationListener(IValidationListener listener) {
-		validationListeners.remove(listener);
-	}
-	
-	@Override
-	public void setEnabled(boolean enabled) {
-		super.setEnabled(enabled);
-		specificButton.setEnabled(enabled);
-		rangeButton.setEnabled(enabled);
-		if ( enabled ) {
-			specificButton.setSelection(versions.isPointVersion());
-			setSpecific();
-		}
-		else {
-			minimumText.setEnabled(enabled);
-			maximumText.setEnabled(enabled);
-			minInclusiveButton.setEnabled(enabled);
-			maxInclusiveButton.setEnabled(enabled);
-		}
-	}
+
+public class VersionRangeComponent extends Composite
+{
+    private VersionRange versions = VersionRange.ANY_VERSION;
+
+    private Button specificButton;
+
+    private Text specificText;
+    private Button rangeButton;
+    private Text minimumText;
+    private Text maximumText;
+    private Button minInclusiveButton;
+    private Button maxInclusiveButton;
+
+    private Set<VersionsChangeListener> listeners = new HashSet<VersionsChangeListener>();
+    private Set<IValidationListener> validationListeners = new HashSet<IValidationListener>();
 
 
-	public VersionRange getVersions() {
-		return versions;
-	}
-	
-	public void setVersions(VersionRange versions) {
-		this.versions = versions == null ? VersionRange.ANY_VERSION : versions;
-		updateFields();
-	}
+    public VersionRangeComponent( Composite parent, int style )
+    {
+        super( parent, style );
+        createComponents( this );
+    }
 
-	private void updateFields() {
-		if ( versions.isPointVersion() ) {
-			specificButton.setSelection(true);
-			specificText.setText( versions.getCeiling() == VersionRange.INFINITE_VERSION ? "*" : versions.getFloor().toString() );
-		}
-		else {
-			rangeButton.setSelection( true );
-			minimumText.setText( versions.getFloor().toString() );
-			minInclusiveButton.setSelection( !versions.isOpenFloor() );
-			maximumText.setText( versions.getCeiling() == VersionRange.INFINITE_VERSION ? "*" : versions.getCeiling().toString() );
-			maxInclusiveButton.setSelection( !versions.isOpenCeiling() );
-		}
-		
-		setSpecific();		
-	}
 
-	private void createComponents(Composite body) {
-		setLayout( new GridLayout( 3, false ) );
-		
-		specificButton = new Button( body, SWT.RADIO );
-		specificButton.setText( "Specific:" );
-		specificButton.addSelectionListener( new SelectionAdapter() {
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				setSpecific();
-			}			
-		});
-		
-		new Label( body, SWT.NONE ).setText("Version:");
-		
-		specificText = new Text( body, SWT.BORDER );
-		specificText.addKeyListener( new KeyAdapter() {
-			@Override
-			public void keyReleased(KeyEvent e) {
-				setVersions();
-			}			
-		});
-		
-		rangeButton = new Button( body, SWT.RADIO );
-		rangeButton.setText( "Range:" );
-		
-		new Label(body, SWT.NONE).setText("Minimum:");
-		
-		minimumText = new Text( body, SWT.BORDER );
-		minimumText.addKeyListener( new KeyAdapter() {
-			@Override
-			public void keyReleased(KeyEvent e) {
-				setVersions();
-			}			
-		});
-		
-		minInclusiveButton = new Button( body, SWT.CHECK );
-		minInclusiveButton.setText( "inclusive" );
-		minInclusiveButton.setSelection(true);
-		minInclusiveButton.addSelectionListener( new SelectionAdapter() {
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				setVersions();
-			}
-		});
-		
-		new Label( body, SWT.NONE ).setText("Maximum:");
-		maximumText = new Text( body, SWT.BORDER );
-		maximumText.addKeyListener( new KeyAdapter() {
-			@Override
-			public void keyReleased(KeyEvent e) {
-				setVersions();
-			}			
-		});
+    public void addVersionChangeListener( VersionsChangeListener listener )
+    {
+        synchronized ( listeners )
+        {
+            listeners.add( listener );
+        }
+    }
 
-		maxInclusiveButton = new Button( body, SWT.CHECK );
-		maxInclusiveButton.setText( "inclusive" );
-		maxInclusiveButton.setSelection(false);
-		maxInclusiveButton.addSelectionListener( new SelectionAdapter() {
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				setVersions();
-			}
-		});
-		
-		// Layout
-		specificButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));
-		specificText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
-		rangeButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));
-		minimumText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		maximumText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
 
-		updateFields();
-	}
-	
-	private void setVersions() {
-		try {
-			if ( specificButton.getSelection() ) {
-				if ( "*".equals( specificText.getText() ) ) {
-					versions = VersionRange.ANY_VERSION;
-				}
-				else if ( specificText.getText().trim().length() == 0 ) {
-					versions = null;
-				}
-				else {
-					Version v = Version.parseVersion( specificText.getText().trim() );
-					versions = new VersionRange( false, v, v, false);
-				}
-			}
-			else {
-				Version min = Version.parseVersion( minimumText.getText() );
-				Version max = "*".equals( maximumText.getText() ) ? VersionRange.INFINITE_VERSION : Version.parseVersion( maximumText.getText() );
-				versions = new VersionRange( !minInclusiveButton.getSelection(), min, max, !maxInclusiveButton.getSelection() );
-			}
-			fireValidationMessage(null, IMessageProvider.NONE);
-		}
-		catch (IllegalArgumentException e) {
-			versions = null;
-			fireValidationMessage("Invalid version", IMessageProvider.ERROR);
-		}
+    public void removeVersionChangeListener( VersionsChangeListener listener )
+    {
+        synchronized ( listeners )
+        {
+            listeners.remove( listener );
+        }
+    }
 
-		fireVersionChange();
-	}
-	
-	private void fireVersionChange() {
-		synchronized( listeners ) {
-			for ( VersionsChangeListener l : listeners ) {
-				l.versionsChanged(versions);
-			}
-		}
-	}
 
-	private void fireValidationMessage(String message, int level) {
-		for (IValidationListener validationListener : validationListeners) {
-			validationListener.validationMessage(message, level);
-		}
-	}
+    public void addValidationListener( IValidationListener listener )
+    {
+        validationListeners.add( listener );
+    }
 
-	private void setSpecific() {
-		boolean specific = specificButton.getSelection();
-		specificButton.setSelection(specific);
-		specificText.setEnabled(specific);
-		minimumText.setEnabled(!specific);
-		maximumText.setEnabled(!specific);
-		minInclusiveButton.setEnabled(!specific);
-		maxInclusiveButton.setEnabled(!specific);
-		setVersions();
-	}
+
+    public void removeValidationListener( IValidationListener listener )
+    {
+        validationListeners.remove( listener );
+    }
+
+
+    @Override
+    public void setEnabled( boolean enabled )
+    {
+        super.setEnabled( enabled );
+        specificButton.setEnabled( enabled );
+        rangeButton.setEnabled( enabled );
+        if ( enabled )
+        {
+            specificButton.setSelection( versions.isPointVersion() );
+            setSpecific();
+        }
+        else
+        {
+            minimumText.setEnabled( enabled );
+            maximumText.setEnabled( enabled );
+            minInclusiveButton.setEnabled( enabled );
+            maxInclusiveButton.setEnabled( enabled );
+        }
+    }
+
+
+    public VersionRange getVersions()
+    {
+        return versions;
+    }
+
+
+    public void setVersions( VersionRange versions )
+    {
+        this.versions = versions == null ? VersionRange.ANY_VERSION : versions;
+        updateFields();
+    }
+
+
+    private void updateFields()
+    {
+        if ( versions.isPointVersion() )
+        {
+            specificButton.setSelection( true );
+            specificText.setText( versions.getCeiling() == VersionRange.INFINITE_VERSION ? "*" : versions.getFloor()
+                .toString() );
+        }
+        else
+        {
+            rangeButton.setSelection( true );
+            minimumText.setText( versions.getFloor().toString() );
+            minInclusiveButton.setSelection( !versions.isOpenFloor() );
+            maximumText.setText( versions.getCeiling() == VersionRange.INFINITE_VERSION ? "*" : versions.getCeiling()
+                .toString() );
+            maxInclusiveButton.setSelection( !versions.isOpenCeiling() );
+        }
+
+        setSpecific();
+    }
+
+
+    private void createComponents( Composite body )
+    {
+        setLayout( new GridLayout( 3, false ) );
+
+        specificButton = new Button( body, SWT.RADIO );
+        specificButton.setText( "Specific:" );
+        specificButton.addSelectionListener( new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected( SelectionEvent e )
+            {
+                setSpecific();
+            }
+        } );
+
+        new Label( body, SWT.NONE ).setText( "Version:" );
+
+        specificText = new Text( body, SWT.BORDER );
+        specificText.addKeyListener( new KeyAdapter()
+        {
+            @Override
+            public void keyReleased( KeyEvent e )
+            {
+                setVersions();
+            }
+        } );
+
+        rangeButton = new Button( body, SWT.RADIO );
+        rangeButton.setText( "Range:" );
+
+        new Label( body, SWT.NONE ).setText( "Minimum:" );
+
+        minimumText = new Text( body, SWT.BORDER );
+        minimumText.addKeyListener( new KeyAdapter()
+        {
+            @Override
+            public void keyReleased( KeyEvent e )
+            {
+                setVersions();
+            }
+        } );
+
+        minInclusiveButton = new Button( body, SWT.CHECK );
+        minInclusiveButton.setText( "inclusive" );
+        minInclusiveButton.setSelection( true );
+        minInclusiveButton.addSelectionListener( new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected( SelectionEvent e )
+            {
+                setVersions();
+            }
+        } );
+
+        new Label( body, SWT.NONE ).setText( "Maximum:" );
+        maximumText = new Text( body, SWT.BORDER );
+        maximumText.addKeyListener( new KeyAdapter()
+        {
+            @Override
+            public void keyReleased( KeyEvent e )
+            {
+                setVersions();
+            }
+        } );
+
+        maxInclusiveButton = new Button( body, SWT.CHECK );
+        maxInclusiveButton.setText( "inclusive" );
+        maxInclusiveButton.setSelection( false );
+        maxInclusiveButton.addSelectionListener( new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected( SelectionEvent e )
+            {
+                setVersions();
+            }
+        } );
+
+        // Layout
+        specificButton.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false, 3, 1 ) );
+        specificText.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false, 2, 1 ) );
+        rangeButton.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false, 3, 1 ) );
+        minimumText.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        maximumText.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+
+        updateFields();
+    }
+
+
+    private void setVersions()
+    {
+        try
+        {
+            if ( specificButton.getSelection() )
+            {
+                if ( "*".equals( specificText.getText() ) )
+                {
+                    versions = VersionRange.ANY_VERSION;
+                }
+                else if ( specificText.getText().trim().length() == 0 )
+                {
+                    versions = null;
+                }
+                else
+                {
+                    Version v = Version.parseVersion( specificText.getText().trim() );
+                    versions = new VersionRange( false, v, v, false );
+                }
+            }
+            else
+            {
+                Version min = Version.parseVersion( minimumText.getText() );
+                Version max = "*".equals( maximumText.getText() ) ? VersionRange.INFINITE_VERSION : Version
+                    .parseVersion( maximumText.getText() );
+                versions = new VersionRange( !minInclusiveButton.getSelection(), min, max, !maxInclusiveButton
+                    .getSelection() );
+            }
+            fireValidationMessage( null, IMessageProvider.NONE );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            versions = null;
+            fireValidationMessage( "Invalid version", IMessageProvider.ERROR );
+        }
+
+        fireVersionChange();
+    }
+
+
+    private void fireVersionChange()
+    {
+        synchronized ( listeners )
+        {
+            for ( VersionsChangeListener l : listeners )
+            {
+                l.versionsChanged( versions );
+            }
+        }
+    }
+
+
+    private void fireValidationMessage( String message, int level )
+    {
+        for ( IValidationListener validationListener : validationListeners )
+        {
+            validationListener.validationMessage( message, level );
+        }
+    }
+
+
+    private void setSpecific()
+    {
+        boolean specific = specificButton.getSelection();
+        specificButton.setSelection( specific );
+        specificText.setEnabled( specific );
+        minimumText.setEnabled( !specific );
+        maximumText.setEnabled( !specific );
+        minInclusiveButton.setEnabled( !specific );
+        maxInclusiveButton.setEnabled( !specific );
+        setVersions();
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/VersionsChangeListener.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/VersionsChangeListener.java
index a59cbad..2c2ee5c 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/VersionsChangeListener.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/VersionsChangeListener.java
@@ -19,8 +19,11 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import org.apache.felix.sigil.model.common.VersionRange;
 
-public interface VersionsChangeListener {
-	void versionsChanged(VersionRange range);
+
+public interface VersionsChangeListener
+{
+    void versionsChanged( VersionRange range );
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/WrappedContentProposal.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/WrappedContentProposal.java
index 3242a70..fccfa94 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/WrappedContentProposal.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/editors/project/WrappedContentProposal.java
@@ -19,44 +19,63 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.editors.project;
 
+
 import org.eclipse.jface.fieldassist.IContentProposal;
 
-public class WrappedContentProposal<T> implements IContentProposal {
-	
-	private final T element;
-	private final IElementDescriptor<? super T> descriptor;
 
-	private WrappedContentProposal(T element, IElementDescriptor<? super T> descriptor) {
-		this.element = element;
-		this.descriptor = descriptor;
-	}
-	
-	public static <T> WrappedContentProposal<T> newInstance(T element, IElementDescriptor<? super T> descriptor) {
-		return new WrappedContentProposal<T>(element, descriptor);
-	}
+public class WrappedContentProposal<T> implements IContentProposal
+{
 
-	public String getContent() {
-		return descriptor.getName(element);
-	}
+    private final T element;
+    private final IElementDescriptor<? super T> descriptor;
 
-	public int getCursorPosition() {
-		return 0;
-	}
 
-	public String getDescription() {
-		return null;
-	}
+    private WrappedContentProposal( T element, IElementDescriptor<? super T> descriptor )
+    {
+        this.element = element;
+        this.descriptor = descriptor;
+    }
 
-	public String getLabel() {
-		return descriptor.getLabel(element);
-	}
 
-	public T getElement() {
-		return element;
-	}
+    public static <T> WrappedContentProposal<T> newInstance( T element, IElementDescriptor<? super T> descriptor )
+    {
+        return new WrappedContentProposal<T>( element, descriptor );
+    }
 
-	@Override
-	public String toString() {
-		return getLabel();
-	}
+
+    public String getContent()
+    {
+        return descriptor.getName( element );
+    }
+
+
+    public int getCursorPosition()
+    {
+        return 0;
+    }
+
+
+    public String getDescription()
+    {
+        return null;
+    }
+
+
+    public String getLabel()
+    {
+        return descriptor.getLabel( element );
+    }
+
+
+    public T getElement()
+    {
+        return element;
+    }
+
+
+    @Override
+    public String toString()
+    {
+        return getLabel();
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/IFormValueConverter.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/IFormValueConverter.java
index 19f8ff2..8cec28e 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/IFormValueConverter.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/IFormValueConverter.java
@@ -19,7 +19,11 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.form;
 
-public interface IFormValueConverter {
-	String getLabel(Object value);
-	Object getValue(String label);
+
+public interface IFormValueConverter
+{
+    String getLabel( Object value );
+
+
+    Object getValue( String label );
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/ISigilFormEntryListener.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/ISigilFormEntryListener.java
index 73934df..cfd790d 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/ISigilFormEntryListener.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/ISigilFormEntryListener.java
@@ -19,7 +19,11 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.form;
 
-public interface ISigilFormEntryListener {
-	void browseButtonSelected(SigilFormEntry form);
-	void textValueChanged(SigilFormEntry form);
+
+public interface ISigilFormEntryListener
+{
+    void browseButtonSelected( SigilFormEntry form );
+
+
+    void textValueChanged( SigilFormEntry form );
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilFormEntry.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilFormEntry.java
index f307672..c739bbb 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilFormEntry.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilFormEntry.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.form;
 
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.FocusAdapter;
 import org.eclipse.swt.events.FocusEvent;
@@ -35,139 +36,188 @@
 import org.eclipse.ui.forms.IFormColors;
 import org.eclipse.ui.forms.widgets.FormToolkit;
 
-public class SigilFormEntry {
-	private static final IFormValueConverter NULL_DESCRIPTOR = new IFormValueConverter() {
-		public String getLabel(Object value) {
-			return (String) value;
-		}
 
-		public Object getValue(String label) {
-			return label;
-		}
-	};
-	
-	private Label lbl;
-	private Text txt;
-	private Button btn;
-	private IFormValueConverter descriptor;
-	private boolean freeText = true;
-	
-	private Object value;
-	private ISigilFormEntryListener listener;
-	
-	public SigilFormEntry(Composite parent, FormToolkit toolkit, String title) {
-		this(parent, toolkit, title, null, null);
-	}
-	
-	public SigilFormEntry(Composite parent, FormToolkit toolkit, String title, String browse, IFormValueConverter descriptor) {
-		this.descriptor = descriptor == null ? NULL_DESCRIPTOR : descriptor;
-		createComponent(parent, title, browse, toolkit);
-	}
-	
-	public void setFormEntryListener(ISigilFormEntryListener listener) {
-		this.listener = listener;
-	}
-	
-	public void setValue(Object value) {
-		this.value = value;
-		String text = descriptor.getLabel(value);
-		if ( text == null ) {
-			text = "";
-		}
-		txt.setText(text);
-		handleValueChanged();
-	}
-	
-	public Object getValue() {
-		return value;
-	}
+public class SigilFormEntry
+{
+    private static final IFormValueConverter NULL_DESCRIPTOR = new IFormValueConverter()
+    {
+        public String getLabel( Object value )
+        {
+            return ( String ) value;
+        }
 
-	public void setFreeText(boolean freeText) {
-		this.freeText = freeText;
-	}
-	
-	public void setEditable(boolean editable) {
-		lbl.setEnabled(editable);
-		txt.setEditable(editable);
-		if ( btn != null ) {
-			btn.setEnabled(editable);
-		}
-	}	
-		
-	private void createComponent(Composite parent, String title, String browse, FormToolkit toolkit) {
-		lbl = toolkit.createLabel(parent, title);
-		lbl.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
-		
-		txt = toolkit.createText(parent, "", SWT.SINGLE | SWT.BORDER);
-		txt.addKeyListener( new KeyAdapter() {
-			@Override
-			public void keyPressed(KeyEvent e) {
-				if ( freeText ) {
-					switch ( e.character ) {
-					case '\r': handleValueChanged(); 
-					}
-				}
-				else {
-					switch ( e.character ) {
-					case '\b': 
-						setValue(null); 
-						handleValueChanged(); 
-					default:
-						e.doit = false;
-						break;
-					}
-				}
-			}
-		});
-		txt.addFocusListener( new FocusAdapter() {
-			@Override
-			public void focusLost(FocusEvent e) {
-				handleValueChanged();
-			}
-		});
-		
-		if ( browse != null ) {
-			btn = toolkit.createButton(parent, browse, SWT.PUSH);
-			btn.addSelectionListener( new SelectionAdapter() {
-				@Override
-				public void widgetSelected(SelectionEvent e) {
-					handleBrowseSelected();
-				}
-			});
-		}
-		
-		fillIntoGrid(parent);
-	}
 
-	private void handleBrowseSelected() {
-		if ( listener != null ) {
-			listener.browseButtonSelected(this);
-		}
-	}
+        public Object getValue( String label )
+        {
+            return label;
+        }
+    };
 
-	private void handleValueChanged() {
-		if ( freeText ) {
-			this.value = descriptor.getValue(txt.getText());
-		}
-		if ( listener != null ) {
-			listener.textValueChanged(this);
-		}
-	}
+    private Label lbl;
+    private Text txt;
+    private Button btn;
+    private IFormValueConverter descriptor;
+    private boolean freeText = true;
 
-	private void fillIntoGrid(Composite parent) {
-		if ( parent.getLayout() instanceof GridLayout ) {
-			GridLayout layout = (GridLayout) parent.getLayout();
-			
-			int cols = layout.numColumns;
-			
-			lbl.setLayoutData( new GridData(SWT.LEFT, SWT.CENTER, false, false) );
-			
-			if ( btn == null ) {
-				txt.setLayoutData( new GridData(SWT.FILL, SWT.CENTER, true, false, Math.max(1, cols - 1), 1 ) );
-			}
-			else {
-				txt.setLayoutData( new GridData(SWT.FILL, SWT.CENTER, true, false, Math.max(1, cols - 2), 1 ) );
-			}
-		}
-	}
+    private Object value;
+    private ISigilFormEntryListener listener;
+
+
+    public SigilFormEntry( Composite parent, FormToolkit toolkit, String title )
+    {
+        this( parent, toolkit, title, null, null );
+    }
+
+
+    public SigilFormEntry( Composite parent, FormToolkit toolkit, String title, String browse,
+        IFormValueConverter descriptor )
+    {
+        this.descriptor = descriptor == null ? NULL_DESCRIPTOR : descriptor;
+        createComponent( parent, title, browse, toolkit );
+    }
+
+
+    public void setFormEntryListener( ISigilFormEntryListener listener )
+    {
+        this.listener = listener;
+    }
+
+
+    public void setValue( Object value )
+    {
+        this.value = value;
+        String text = descriptor.getLabel( value );
+        if ( text == null )
+        {
+            text = "";
+        }
+        txt.setText( text );
+        handleValueChanged();
+    }
+
+
+    public Object getValue()
+    {
+        return value;
+    }
+
+
+    public void setFreeText( boolean freeText )
+    {
+        this.freeText = freeText;
+    }
+
+
+    public void setEditable( boolean editable )
+    {
+        lbl.setEnabled( editable );
+        txt.setEditable( editable );
+        if ( btn != null )
+        {
+            btn.setEnabled( editable );
+        }
+    }
+
+
+    private void createComponent( Composite parent, String title, String browse, FormToolkit toolkit )
+    {
+        lbl = toolkit.createLabel( parent, title );
+        lbl.setForeground( toolkit.getColors().getColor( IFormColors.TITLE ) );
+
+        txt = toolkit.createText( parent, "", SWT.SINGLE | SWT.BORDER );
+        txt.addKeyListener( new KeyAdapter()
+        {
+            @Override
+            public void keyPressed( KeyEvent e )
+            {
+                if ( freeText )
+                {
+                    switch ( e.character )
+                    {
+                        case '\r':
+                            handleValueChanged();
+                    }
+                }
+                else
+                {
+                    switch ( e.character )
+                    {
+                        case '\b':
+                            setValue( null );
+                            handleValueChanged();
+                        default:
+                            e.doit = false;
+                            break;
+                    }
+                }
+            }
+        } );
+        txt.addFocusListener( new FocusAdapter()
+        {
+            @Override
+            public void focusLost( FocusEvent e )
+            {
+                handleValueChanged();
+            }
+        } );
+
+        if ( browse != null )
+        {
+            btn = toolkit.createButton( parent, browse, SWT.PUSH );
+            btn.addSelectionListener( new SelectionAdapter()
+            {
+                @Override
+                public void widgetSelected( SelectionEvent e )
+                {
+                    handleBrowseSelected();
+                }
+            } );
+        }
+
+        fillIntoGrid( parent );
+    }
+
+
+    private void handleBrowseSelected()
+    {
+        if ( listener != null )
+        {
+            listener.browseButtonSelected( this );
+        }
+    }
+
+
+    private void handleValueChanged()
+    {
+        if ( freeText )
+        {
+            this.value = descriptor.getValue( txt.getText() );
+        }
+        if ( listener != null )
+        {
+            listener.textValueChanged( this );
+        }
+    }
+
+
+    private void fillIntoGrid( Composite parent )
+    {
+        if ( parent.getLayout() instanceof GridLayout )
+        {
+            GridLayout layout = ( GridLayout ) parent.getLayout();
+
+            int cols = layout.numColumns;
+
+            lbl.setLayoutData( new GridData( SWT.LEFT, SWT.CENTER, false, false ) );
+
+            if ( btn == null )
+            {
+                txt.setLayoutData( new GridData( SWT.FILL, SWT.CENTER, true, false, Math.max( 1, cols - 1 ), 1 ) );
+            }
+            else
+            {
+                txt.setLayoutData( new GridData( SWT.FILL, SWT.CENTER, true, false, Math.max( 1, cols - 2 ), 1 ) );
+            }
+        }
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilFormEntryAdapter.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilFormEntryAdapter.java
index 188a823..7db0549 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilFormEntryAdapter.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilFormEntryAdapter.java
@@ -19,10 +19,15 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.form;
 
-public class SigilFormEntryAdapter implements ISigilFormEntryListener{
-	public void browseButtonSelected(SigilFormEntry form) {
-	}
 
-	public void textValueChanged(SigilFormEntry form) {
-	}
+public class SigilFormEntryAdapter implements ISigilFormEntryListener
+{
+    public void browseButtonSelected( SigilFormEntry form )
+    {
+    }
+
+
+    public void textValueChanged( SigilFormEntry form )
+    {
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilPage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilPage.java
index 23ef4cf..ad6eae6 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilPage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilPage.java
@@ -19,13 +19,17 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.form;
 
+
 import org.eclipse.ui.forms.editor.FormEditor;
 import org.eclipse.ui.forms.editor.FormPage;
 
-public class SigilPage extends FormPage {
 
-	public SigilPage(FormEditor editor, String id, String title) {
-		super(editor, id, title);
-	}
-	
+public class SigilPage extends FormPage
+{
+
+    public SigilPage( FormEditor editor, String id, String title )
+    {
+        super( editor, id, title );
+    }
+
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilSection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilSection.java
index 513a555..5a1c072 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilSection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/form/SigilSection.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.form;
 
+
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.resources.IResource;
@@ -41,110 +42,150 @@
 import org.eclipse.ui.forms.widgets.TableWrapData;
 import org.eclipse.ui.forms.widgets.TableWrapLayout;
 
+
 @SuppressWarnings("restriction")
-public abstract class SigilSection extends SectionPart implements IFormEntryListener, IPartSelectionListener {
+public abstract class SigilSection extends SectionPart implements IFormEntryListener, IPartSelectionListener
+{
 
-	private SigilPage page;
-	private ISigilProjectModel project;
-	
-	public SigilSection(SigilPage page, Composite parent, ISigilProjectModel project) throws CoreException {
-		super(parent, page.getManagedForm().getToolkit(), ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED );
-		this.project = project;
-		this.page = page;
-		createSection( getSection(), page.getManagedForm().getToolkit() );		
-	}
+    private SigilPage page;
+    private ISigilProjectModel project;
 
-	public ISigilProjectModel getProjectModel() {
-		return project;
-	}
-	
-	public SigilPage getPage() {
-		return page;
-	}
-	
-	public void setExpanded( boolean expanded ) {
-		getSection().setExpanded(expanded);
-	}
-	
-	protected abstract void createSection(Section section,FormToolkit toolkit ) throws CoreException;
-	
-	protected void setTitle( String title ) {
-			Section section = getSection();
-	        section.setText( title );
-			section.setLayout(FormLayoutFactory.createClearTableWrapLayout(false, 1));
-			TableWrapData data = new TableWrapData(TableWrapData.FILL_GRAB);
-			section.setLayoutData(data);				
-	}
-	
-	protected void setMarker(String type, String message, int priority, int severity) throws CoreException {
-		IFileEditorInput file = (IFileEditorInput) getPage().getEditor().getEditorInput();
-		IMarker marker = file.getFile().createMarker(type);
-		marker.setAttribute( IMarker.MESSAGE, message );
-		marker.setAttribute(IMarker.PRIORITY, priority);
-		marker.setAttribute( IMarker.SEVERITY, severity );
-	}
-	
-	protected void clearMarkers() throws CoreException {
-		IFileEditorInput file = (IFileEditorInput) getPage().getEditor().getEditorInput();
-		file.getFile().deleteMarkers(null, true, IResource.DEPTH_INFINITE );
-	}
-	
-	protected Composite createTableWrapBody( int columns, FormToolkit toolkit ) {
-		Section section = getSection();
-        Composite client = toolkit.createComposite(section);
-        
+
+    public SigilSection( SigilPage page, Composite parent, ISigilProjectModel project ) throws CoreException
+    {
+        super( parent, page.getManagedForm().getToolkit(), ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE
+            | ExpandableComposite.EXPANDED );
+        this.project = project;
+        this.page = page;
+        createSection( getSection(), page.getManagedForm().getToolkit() );
+    }
+
+
+    public ISigilProjectModel getProjectModel()
+    {
+        return project;
+    }
+
+
+    public SigilPage getPage()
+    {
+        return page;
+    }
+
+
+    public void setExpanded( boolean expanded )
+    {
+        getSection().setExpanded( expanded );
+    }
+
+
+    protected abstract void createSection( Section section, FormToolkit toolkit ) throws CoreException;
+
+
+    protected void setTitle( String title )
+    {
+        Section section = getSection();
+        section.setText( title );
+        section.setLayout( FormLayoutFactory.createClearTableWrapLayout( false, 1 ) );
+        TableWrapData data = new TableWrapData( TableWrapData.FILL_GRAB );
+        section.setLayoutData( data );
+    }
+
+
+    protected void setMarker( String type, String message, int priority, int severity ) throws CoreException
+    {
+        IFileEditorInput file = ( IFileEditorInput ) getPage().getEditor().getEditorInput();
+        IMarker marker = file.getFile().createMarker( type );
+        marker.setAttribute( IMarker.MESSAGE, message );
+        marker.setAttribute( IMarker.PRIORITY, priority );
+        marker.setAttribute( IMarker.SEVERITY, severity );
+    }
+
+
+    protected void clearMarkers() throws CoreException
+    {
+        IFileEditorInput file = ( IFileEditorInput ) getPage().getEditor().getEditorInput();
+        file.getFile().deleteMarkers( null, true, IResource.DEPTH_INFINITE );
+    }
+
+
+    protected Composite createTableWrapBody( int columns, FormToolkit toolkit )
+    {
+        Section section = getSection();
+        Composite client = toolkit.createComposite( section );
+
         TableWrapLayout layout = new TableWrapLayout();
         layout.leftMargin = layout.rightMargin = toolkit.getBorderStyle() != SWT.NULL ? 0 : 2;
         layout.numColumns = columns;
-        client.setLayout(layout);
-        client.setLayoutData( new TableWrapData( TableWrapData.FILL_GRAB) );
-		
-        section.setClient(client);
-        
+        client.setLayout( layout );
+        client.setLayoutData( new TableWrapData( TableWrapData.FILL_GRAB ) );
+
+        section.setClient( client );
+
         return client;
-	}
-	
-	protected Composite createGridBody( int columns, boolean columnsSameWidth, FormToolkit toolkit ) {
-		Section section = getSection();
-        Composite client = toolkit.createComposite(section);
-        
-		GridLayout layout = new GridLayout();
-		
-		layout.makeColumnsEqualWidth = columnsSameWidth;
-		layout.numColumns = columns;
-        client.setLayout(layout);
-        
-        client.setLayoutData( new TableWrapData( TableWrapData.FILL_GRAB) );
-		
-        section.setClient(client);
-        
+    }
+
+
+    protected Composite createGridBody( int columns, boolean columnsSameWidth, FormToolkit toolkit )
+    {
+        Section section = getSection();
+        Composite client = toolkit.createComposite( section );
+
+        GridLayout layout = new GridLayout();
+
+        layout.makeColumnsEqualWidth = columnsSameWidth;
+        layout.numColumns = columns;
+        client.setLayout( layout );
+
+        client.setLayoutData( new TableWrapData( TableWrapData.FILL_GRAB ) );
+
+        section.setClient( client );
+
         return client;
-	}
-	
-	public void browseButtonSelected(FormEntry entry) {
-	}
+    }
 
-	public void focusGained(FormEntry entry) {
-	}
 
-	public void selectionChanged(FormEntry entry) {
-	}
+    public void browseButtonSelected( FormEntry entry )
+    {
+    }
 
-	public void textDirty(FormEntry entry) {
-	}
 
-	public void textValueChanged(FormEntry entry) {
-	}
+    public void focusGained( FormEntry entry )
+    {
+    }
 
-	public void linkActivated(HyperlinkEvent e) {
-	}
 
-	public void linkEntered(HyperlinkEvent e) {
-	}
+    public void selectionChanged( FormEntry entry )
+    {
+    }
 
-	public void linkExited(HyperlinkEvent e) {
-	}
 
-	public void selectionChanged(IFormPart part, ISelection selection) {
-	}
+    public void textDirty( FormEntry entry )
+    {
+    }
+
+
+    public void textValueChanged( FormEntry entry )
+    {
+    }
+
+
+    public void linkActivated( HyperlinkEvent e )
+    {
+    }
+
+
+    public void linkEntered( HyperlinkEvent e )
+    {
+    }
+
+
+    public void linkExited( HyperlinkEvent e )
+    {
+    }
+
+
+    public void selectionChanged( IFormPart part, ISelection selection )
+    {
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/FileSystemRepositoryWizard.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/FileSystemRepositoryWizard.java
index fecdc3b..4a393cd 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/FileSystemRepositoryWizard.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/FileSystemRepositoryWizard.java
@@ -19,11 +19,15 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.internal.repository;
 
+
 import org.apache.felix.sigil.ui.eclipse.ui.wizard.repository.RepositoryWizard;
 
-public class FileSystemRepositoryWizard extends RepositoryWizard {
-	@Override
-	public void addPages() {
-		addPage( new FileSystemRepositoryWizardPage(this) );
-	}
+
+public class FileSystemRepositoryWizard extends RepositoryWizard
+{
+    @Override
+    public void addPages()
+    {
+        addPage( new FileSystemRepositoryWizardPage( this ) );
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/FileSystemRepositoryWizardPage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/FileSystemRepositoryWizardPage.java
index 1169e10..ae03dc4 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/FileSystemRepositoryWizardPage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/FileSystemRepositoryWizardPage.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.internal.repository;
 
+
 import java.io.File;
 
 import org.apache.felix.sigil.ui.eclipse.ui.wizard.repository.RepositoryWizard;
@@ -29,43 +30,56 @@
 import org.eclipse.swt.events.ModifyEvent;
 import org.eclipse.swt.events.ModifyListener;
 
-public class FileSystemRepositoryWizardPage extends RepositoryWizardPage
-		implements IWizardPage {
 
-	private DirectoryFieldEditor dirEditor;
+public class FileSystemRepositoryWizardPage extends RepositoryWizardPage implements IWizardPage
+{
 
-	protected FileSystemRepositoryWizardPage(RepositoryWizard parent) {
-		super("File System Repository", parent);
-	}
+    private DirectoryFieldEditor dirEditor;
 
-	@Override
-	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() ) );
-	}
 
-	@Override
-	protected void checkPageComplete() {
-		super.checkPageComplete();
-		if ( isPageComplete() ) {
-			setPageComplete(dirEditor.getStringValue().length() > 0);
-			if ( isPageComplete() ) {
-				if ( new File( dirEditor.getStringValue()).isDirectory() ) {
-					setPageComplete(true);
-					setErrorMessage(null);
-				}
-				else {
-					setPageComplete(false);
-					setErrorMessage("Invalid directory");
-				}
-			}
-		}
-	}
+    protected FileSystemRepositoryWizardPage( RepositoryWizard parent )
+    {
+        super( "File System Repository", parent );
+    }
+
+
+    @Override
+    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() ) );
+    }
+
+
+    @Override
+    protected void checkPageComplete()
+    {
+        super.checkPageComplete();
+        if ( isPageComplete() )
+        {
+            setPageComplete( dirEditor.getStringValue().length() > 0 );
+            if ( isPageComplete() )
+            {
+                if ( new File( dirEditor.getStringValue() ).isDirectory() )
+                {
+                    setPageComplete( true );
+                    setErrorMessage( null );
+                }
+                else
+                {
+                    setPageComplete( false );
+                    setErrorMessage( "Invalid directory" );
+                }
+            }
+        }
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/OSGiInstallRepositoryWizard.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/OSGiInstallRepositoryWizard.java
index b6a205e..35f0d8e 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/OSGiInstallRepositoryWizard.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/OSGiInstallRepositoryWizard.java
@@ -19,11 +19,15 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.internal.repository;
 
+
 import org.apache.felix.sigil.ui.eclipse.ui.wizard.repository.RepositoryWizard;
 
-public class OSGiInstallRepositoryWizard extends RepositoryWizard {
-	@Override
-	public void addPages() {
-		addPage( new OSGiInstallRepositoryWizardPage(this) );
-	}
+
+public class OSGiInstallRepositoryWizard extends RepositoryWizard
+{
+    @Override
+    public void addPages()
+    {
+        addPage( new OSGiInstallRepositoryWizardPage( this ) );
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/OSGiInstallRepositoryWizardPage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/OSGiInstallRepositoryWizardPage.java
index 8c5dc0d..8e782d2 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/OSGiInstallRepositoryWizardPage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/internal/repository/OSGiInstallRepositoryWizardPage.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.internal.repository;
 
+
 import java.util.ArrayList;
 
 import org.apache.felix.sigil.eclipse.SigilCore;
@@ -27,27 +28,31 @@
 import org.apache.felix.sigil.ui.eclipse.ui.wizard.repository.RepositoryWizardPage;
 import org.eclipse.jface.preference.RadioGroupFieldEditor;
 
-public class OSGiInstallRepositoryWizardPage extends RepositoryWizardPage {
 
-	protected OSGiInstallRepositoryWizardPage(RepositoryWizard parent) {
-		super("OSGi Install Repository", parent);
-	}
+public class OSGiInstallRepositoryWizardPage extends RepositoryWizardPage
+{
 
-	@Override
-	public void createFieldEditors() {
-		ArrayList<String[]> installs = new ArrayList<String[]>();
-		for ( String id : SigilCore.getInstallManager().getInstallIDs() ) {
-			IOSGiInstall i = SigilCore.getInstallManager().findInstall(id);
-			installs.add( new String[] { i.getType().getName(), id } );
-		}
-		String[][] strs = installs.toArray( new String[installs.size()][] );
-		
-		RadioGroupFieldEditor editor = new RadioGroupFieldEditor(
-				"id", 
-				"Install", 
-				1, strs, getFieldEditorParent() );
-		
-		addField(editor);
-	}
+    protected OSGiInstallRepositoryWizardPage( RepositoryWizard parent )
+    {
+        super( "OSGi Install Repository", parent );
+    }
+
+
+    @Override
+    public void createFieldEditors()
+    {
+        ArrayList<String[]> installs = new ArrayList<String[]>();
+        for ( String id : SigilCore.getInstallManager().getInstallIDs() )
+        {
+            IOSGiInstall i = SigilCore.getInstallManager().findInstall( id );
+            installs.add( new String[]
+                { i.getType().getName(), id } );
+        }
+        String[][] strs = installs.toArray( new String[installs.size()][] );
+
+        RadioGroupFieldEditor editor = new RadioGroupFieldEditor( "id", "Install", 1, strs, getFieldEditorParent() );
+
+        addField( editor );
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/perspective/SigilPerspectiveFactory.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/perspective/SigilPerspectiveFactory.java
index f6e2083..a38d27d 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/perspective/SigilPerspectiveFactory.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/perspective/SigilPerspectiveFactory.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.perspective;
 
+
 import org.apache.felix.sigil.ui.eclipse.ui.SigilUI;
 import org.eclipse.debug.ui.IDebugUIConstants;
 import org.eclipse.jdt.ui.JavaUI;
@@ -27,85 +28,88 @@
 import org.eclipse.ui.IPerspectiveFactory;
 import org.eclipse.ui.progress.IProgressConstants;
 
-public class SigilPerspectiveFactory implements IPerspectiveFactory {
-	
-	private static final String ID_PROJECT_EXPLORER= "org.eclipse.ui.navigator.ProjectExplorer"; //$NON-NLS-1$
-	private static final String ID_SEARCH_VIEW = "org.eclipse.search.ui.views.SearchView"; //$NON-NLS-1$
-	private static final String ID_CONSOLE_VIEW = "org.eclipse.ui.console.ConsoleView"; //$NON-NLS-1$
-	private static final String ID_TEMPLATES_VIEW = "org.eclipse.ui.texteditor.TemplatesView"; //$NON-NLS-N$
-	
 
-	public void createInitialLayout(IPageLayout layout) {
-		/*
-		 * Use ProjectExplorer vs PackageExplorer due to a bug with Drag and Drop on Mac OS X which affects PackageExplorer
-		 * but not ProjectExplorer. https://bugs.eclipse.org/bugs/show_bug.cgi?id=243529
-		 */
- 		String editorArea = layout.getEditorArea();
-		
-		IFolderLayout folder= layout.createFolder("left", IPageLayout.LEFT, (float)0.25, editorArea); //$NON-NLS-1$
-		folder.addView(ID_PROJECT_EXPLORER);
-		folder.addView(JavaUI.ID_TYPE_HIERARCHY);
-		folder.addPlaceholder(IPageLayout.ID_RES_NAV);
-		folder.addPlaceholder(SigilUI.ID_REPOSITORY_VIEW);
-		folder.addView(IPageLayout.ID_OUTLINE);		
-		
-		IFolderLayout outputfolder= layout.createFolder("bottom", IPageLayout.BOTTOM, (float)0.75, editorArea); //$NON-NLS-1$
-		outputfolder.addView(IPageLayout.ID_PROBLEM_VIEW);
-		outputfolder.addView(JavaUI.ID_JAVADOC_VIEW);
-		outputfolder.addView(JavaUI.ID_SOURCE_VIEW);
-		outputfolder.addPlaceholder(ID_SEARCH_VIEW);
-		outputfolder.addPlaceholder(ID_CONSOLE_VIEW);
-		outputfolder.addPlaceholder(IPageLayout.ID_BOOKMARKS);
-		outputfolder.addPlaceholder(IProgressConstants.PROGRESS_VIEW_ID);
-		outputfolder.addPlaceholder(SigilUI.ID_DEPENDENCY_VIEW);
-		outputfolder.addPlaceholder(SigilUI.ID_INSTANCES_VIEW);
-		
-		layout.addActionSet(IDebugUIConstants.LAUNCH_ACTION_SET);
-		layout.addActionSet(JavaUI.ID_ACTION_SET);
-		layout.addActionSet(JavaUI.ID_ELEMENT_CREATION_ACTION_SET);
-		layout.addActionSet(IPageLayout.ID_NAVIGATE_ACTION_SET);
-		
-		// views - sigil
-		layout.addShowViewShortcut(SigilUI.ID_REPOSITORY_VIEW);
-		layout.addShowViewShortcut(SigilUI.ID_DEPENDENCY_VIEW);
-		layout.addShowViewShortcut(SigilUI.ID_INSTANCES_VIEW);
-		
-		// views - java
-		layout.addShowViewShortcut(JavaUI.ID_PACKAGES);
-		layout.addShowViewShortcut(JavaUI.ID_TYPE_HIERARCHY);
-		layout.addShowViewShortcut(JavaUI.ID_SOURCE_VIEW);
-		layout.addShowViewShortcut(JavaUI.ID_JAVADOC_VIEW);
+public class SigilPerspectiveFactory implements IPerspectiveFactory
+{
 
-		// views - search
-		layout.addShowViewShortcut(ID_SEARCH_VIEW);
-		
-		// views - debugging
-		layout.addShowViewShortcut(ID_CONSOLE_VIEW);
+    private static final String ID_PROJECT_EXPLORER = "org.eclipse.ui.navigator.ProjectExplorer"; //$NON-NLS-1$
+    private static final String ID_SEARCH_VIEW = "org.eclipse.search.ui.views.SearchView"; //$NON-NLS-1$
+    private static final String ID_CONSOLE_VIEW = "org.eclipse.ui.console.ConsoleView"; //$NON-NLS-1$
+    private static final String ID_TEMPLATES_VIEW = "org.eclipse.ui.texteditor.TemplatesView"; //$NON-NLS-N$
 
-		// views - standard workbench
-		layout.addShowViewShortcut(IPageLayout.ID_OUTLINE);
-		layout.addShowViewShortcut(IPageLayout.ID_PROBLEM_VIEW);
-		layout.addShowViewShortcut(IPageLayout.ID_RES_NAV);
-		layout.addShowViewShortcut(IPageLayout.ID_TASK_LIST);
-		layout.addShowViewShortcut(IProgressConstants.PROGRESS_VIEW_ID);
-		layout.addShowViewShortcut(ID_PROJECT_EXPLORER);
-				
-		// new actions - Java project creation wizard
-		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewPackageCreationWizard"); //$NON-NLS-1$
-		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewClassCreationWizard"); //$NON-NLS-1$
-		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewInterfaceCreationWizard"); //$NON-NLS-1$
-		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewEnumCreationWizard"); //$NON-NLS-1$
-		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewAnnotationCreationWizard"); //$NON-NLS-1$
-		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewSourceFolderCreationWizard");	 //$NON-NLS-1$
-		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewSnippetFileCreationWizard"); //$NON-NLS-1$
-		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewJavaWorkingSetWizard"); //$NON-NLS-1$
-		layout.addNewWizardShortcut("org.eclipse.ui.wizards.new.folder");//$NON-NLS-1$
-		layout.addNewWizardShortcut("org.eclipse.ui.wizards.new.file");//$NON-NLS-1$
-		layout.addNewWizardShortcut("org.eclipse.ui.editors.wizards.UntitledTextFileWizard");//$NON-NLS-1$
-		
-		layout.addNewWizardShortcut("org.cauldron.sigil.editors.newCompositeWizard");
-		layout.addNewWizardShortcut("org.cauldron.sigil.editors.newSystemWizard");
-		layout.addNewWizardShortcut("org.cauldron.sigil.editors.newProjectWizard");
-	}
+
+    public void createInitialLayout( IPageLayout layout )
+    {
+        /*
+         * Use ProjectExplorer vs PackageExplorer due to a bug with Drag and Drop on Mac OS X which affects PackageExplorer
+         * but not ProjectExplorer. https://bugs.eclipse.org/bugs/show_bug.cgi?id=243529
+         */
+        String editorArea = layout.getEditorArea();
+
+        IFolderLayout folder = layout.createFolder( "left", IPageLayout.LEFT, ( float ) 0.25, editorArea ); //$NON-NLS-1$
+        folder.addView( ID_PROJECT_EXPLORER );
+        folder.addView( JavaUI.ID_TYPE_HIERARCHY );
+        folder.addPlaceholder( IPageLayout.ID_RES_NAV );
+        folder.addPlaceholder( SigilUI.ID_REPOSITORY_VIEW );
+        folder.addView( IPageLayout.ID_OUTLINE );
+
+        IFolderLayout outputfolder = layout.createFolder( "bottom", IPageLayout.BOTTOM, ( float ) 0.75, editorArea ); //$NON-NLS-1$
+        outputfolder.addView( IPageLayout.ID_PROBLEM_VIEW );
+        outputfolder.addView( JavaUI.ID_JAVADOC_VIEW );
+        outputfolder.addView( JavaUI.ID_SOURCE_VIEW );
+        outputfolder.addPlaceholder( ID_SEARCH_VIEW );
+        outputfolder.addPlaceholder( ID_CONSOLE_VIEW );
+        outputfolder.addPlaceholder( IPageLayout.ID_BOOKMARKS );
+        outputfolder.addPlaceholder( IProgressConstants.PROGRESS_VIEW_ID );
+        outputfolder.addPlaceholder( SigilUI.ID_DEPENDENCY_VIEW );
+        outputfolder.addPlaceholder( SigilUI.ID_INSTANCES_VIEW );
+
+        layout.addActionSet( IDebugUIConstants.LAUNCH_ACTION_SET );
+        layout.addActionSet( JavaUI.ID_ACTION_SET );
+        layout.addActionSet( JavaUI.ID_ELEMENT_CREATION_ACTION_SET );
+        layout.addActionSet( IPageLayout.ID_NAVIGATE_ACTION_SET );
+
+        // views - sigil
+        layout.addShowViewShortcut( SigilUI.ID_REPOSITORY_VIEW );
+        layout.addShowViewShortcut( SigilUI.ID_DEPENDENCY_VIEW );
+        layout.addShowViewShortcut( SigilUI.ID_INSTANCES_VIEW );
+
+        // views - java
+        layout.addShowViewShortcut( JavaUI.ID_PACKAGES );
+        layout.addShowViewShortcut( JavaUI.ID_TYPE_HIERARCHY );
+        layout.addShowViewShortcut( JavaUI.ID_SOURCE_VIEW );
+        layout.addShowViewShortcut( JavaUI.ID_JAVADOC_VIEW );
+
+        // views - search
+        layout.addShowViewShortcut( ID_SEARCH_VIEW );
+
+        // views - debugging
+        layout.addShowViewShortcut( ID_CONSOLE_VIEW );
+
+        // views - standard workbench
+        layout.addShowViewShortcut( IPageLayout.ID_OUTLINE );
+        layout.addShowViewShortcut( IPageLayout.ID_PROBLEM_VIEW );
+        layout.addShowViewShortcut( IPageLayout.ID_RES_NAV );
+        layout.addShowViewShortcut( IPageLayout.ID_TASK_LIST );
+        layout.addShowViewShortcut( IProgressConstants.PROGRESS_VIEW_ID );
+        layout.addShowViewShortcut( ID_PROJECT_EXPLORER );
+
+        // new actions - Java project creation wizard
+        layout.addNewWizardShortcut( "org.eclipse.jdt.ui.wizards.NewPackageCreationWizard" ); //$NON-NLS-1$
+        layout.addNewWizardShortcut( "org.eclipse.jdt.ui.wizards.NewClassCreationWizard" ); //$NON-NLS-1$
+        layout.addNewWizardShortcut( "org.eclipse.jdt.ui.wizards.NewInterfaceCreationWizard" ); //$NON-NLS-1$
+        layout.addNewWizardShortcut( "org.eclipse.jdt.ui.wizards.NewEnumCreationWizard" ); //$NON-NLS-1$
+        layout.addNewWizardShortcut( "org.eclipse.jdt.ui.wizards.NewAnnotationCreationWizard" ); //$NON-NLS-1$
+        layout.addNewWizardShortcut( "org.eclipse.jdt.ui.wizards.NewSourceFolderCreationWizard" ); //$NON-NLS-1$
+        layout.addNewWizardShortcut( "org.eclipse.jdt.ui.wizards.NewSnippetFileCreationWizard" ); //$NON-NLS-1$
+        layout.addNewWizardShortcut( "org.eclipse.jdt.ui.wizards.NewJavaWorkingSetWizard" ); //$NON-NLS-1$
+        layout.addNewWizardShortcut( "org.eclipse.ui.wizards.new.folder" );//$NON-NLS-1$
+        layout.addNewWizardShortcut( "org.eclipse.ui.wizards.new.file" );//$NON-NLS-1$
+        layout.addNewWizardShortcut( "org.eclipse.ui.editors.wizards.UntitledTextFileWizard" );//$NON-NLS-1$
+
+        layout.addNewWizardShortcut( "org.cauldron.sigil.editors.newCompositeWizard" );
+        layout.addNewWizardShortcut( "org.cauldron.sigil.editors.newSystemWizard" );
+        layout.addNewWizardShortcut( "org.cauldron.sigil.editors.newProjectWizard" );
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/ExcludedResourcesPrefsPage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/ExcludedResourcesPrefsPage.java
index af1e4de..53f8eed 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/ExcludedResourcesPrefsPage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/ExcludedResourcesPrefsPage.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences;
 
+
 import java.util.ArrayList;
 import java.util.Iterator;
 
@@ -48,122 +49,153 @@
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferencePage;
 
-public class ExcludedResourcesPrefsPage extends PreferencePage implements IWorkbenchPreferencePage {
-	
-	private TableViewer viewer;
-	private IWorkbench workbench;
-	private ArrayList<String> resources;
 
-	public ExcludedResourcesPrefsPage() {
-		super();
-		setDescription("Specify resources that should not be offered for inclusion in a generated bundle.");
-	}
+public class ExcludedResourcesPrefsPage extends PreferencePage implements IWorkbenchPreferencePage
+{
 
-	@Override
-	protected Control createContents(Composite parent) {
-		// Create controls
-		Composite composite = new Composite(parent, SWT.NONE);
-		Table table = new Table(composite, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);
-		
-		Button btnAdd = new Button(composite, SWT.PUSH);
-		btnAdd.setText("Add");
-		
-		final Button btnRemove = new Button(composite, SWT.PUSH);
-		btnRemove.setText("Remove");
-		btnRemove.setEnabled(false);
-		
-		// Create viewer
-		viewer = new TableViewer(table);
-		viewer.setContentProvider(new ArrayContentProvider());
-		
-		// Load data
-		loadPreferences(false);
-		viewer.setInput(resources);
-		
-		// Listeners
-		viewer.addSelectionChangedListener(new ISelectionChangedListener() {
-			public void selectionChanged(SelectionChangedEvent event) {
-				btnRemove.setEnabled(!viewer.getSelection().isEmpty());
-			}
-		});
-		
-		btnRemove.addSelectionListener(new SelectionAdapter() {
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
-				Object[] deleted = selection.toArray();
-				for(Object delete : deleted) {
-					resources.remove(delete);
-				}
-				viewer.remove(deleted);
-			}
-		});
-		
-		btnAdd.addSelectionListener(new SelectionAdapter() {
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				InputDialog dialog = new InputDialog(getShell(), "Add Resource", "Enter resource name", "", new IInputValidator() {
-					public String isValid(String newText) {
-						String error = null;
-						if(newText == null || newText.length() == 0) {
-							error = "Name must not be empty.";
-						} else if(resources.contains(newText)) {
-							error = "Specified resource name is already on the list.";
-						}
-						return error;
-					}
-				});
-				
-				if(dialog.open() == Window.OK) {
-					String value = dialog.getValue();
-					resources.add(value);
-					viewer.add(value);
-				}
-			}
-		});
-		
-		// Layout
-		composite.setLayout(new GridLayout(2, false));
-		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 3));
-		btnAdd.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-		btnRemove.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-		
-		return composite;
-	}
+    private TableViewer viewer;
+    private IWorkbench workbench;
+    private ArrayList<String> resources;
 
-	private void loadPreferences(boolean useDefaults) {
-		String resourcesListStr = useDefaults
-				? getPreferenceStore().getDefaultString(SigilCore.DEFAULT_EXCLUDED_RESOURCES)
-				: getPreferenceStore().getString(SigilCore.DEFAULT_EXCLUDED_RESOURCES);
-		String[] resourcesArray = PrefsUtils.stringToArray(resourcesListStr);
-		
-		resources = new ArrayList<String>(resourcesArray.length);
-		for (String resource : resourcesArray) {
-			resources.add(resource);
-		}
-	}
 
-	public void init(IWorkbench workbench) {
-		this.workbench = workbench;
-	}
-	
-	@Override
-	protected IPreferenceStore doGetPreferenceStore() {
-		return SigilCore.getDefault().getPreferenceStore();
-	}
-	
-	@Override
-	public boolean performOk() {
-		String resourcesStr = PrefsUtils.arrayToString(resources.toArray(new String[resources.size()]));
-		getPreferenceStore().setValue(SigilCore.DEFAULT_EXCLUDED_RESOURCES, resourcesStr);
-		return true;
-	}
-	
-	@Override
-	protected void performDefaults() {
-		super.performDefaults();
-		loadPreferences(true);
-		viewer.setInput(resources);
-	}
+    public ExcludedResourcesPrefsPage()
+    {
+        super();
+        setDescription( "Specify resources that should not be offered for inclusion in a generated bundle." );
+    }
+
+
+    @Override
+    protected Control createContents( Composite parent )
+    {
+        // Create controls
+        Composite composite = new Composite( parent, SWT.NONE );
+        Table table = new Table( composite, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION );
+
+        Button btnAdd = new Button( composite, SWT.PUSH );
+        btnAdd.setText( "Add" );
+
+        final Button btnRemove = new Button( composite, SWT.PUSH );
+        btnRemove.setText( "Remove" );
+        btnRemove.setEnabled( false );
+
+        // Create viewer
+        viewer = new TableViewer( table );
+        viewer.setContentProvider( new ArrayContentProvider() );
+
+        // Load data
+        loadPreferences( false );
+        viewer.setInput( resources );
+
+        // Listeners
+        viewer.addSelectionChangedListener( new ISelectionChangedListener()
+        {
+            public void selectionChanged( SelectionChangedEvent event )
+            {
+                btnRemove.setEnabled( !viewer.getSelection().isEmpty() );
+            }
+        } );
+
+        btnRemove.addSelectionListener( new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected( SelectionEvent e )
+            {
+                IStructuredSelection selection = ( IStructuredSelection ) viewer.getSelection();
+                Object[] deleted = selection.toArray();
+                for ( Object delete : deleted )
+                {
+                    resources.remove( delete );
+                }
+                viewer.remove( deleted );
+            }
+        } );
+
+        btnAdd.addSelectionListener( new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected( SelectionEvent e )
+            {
+                InputDialog dialog = new InputDialog( getShell(), "Add Resource", "Enter resource name", "",
+                    new IInputValidator()
+                    {
+                        public String isValid( String newText )
+                        {
+                            String error = null;
+                            if ( newText == null || newText.length() == 0 )
+                            {
+                                error = "Name must not be empty.";
+                            }
+                            else if ( resources.contains( newText ) )
+                            {
+                                error = "Specified resource name is already on the list.";
+                            }
+                            return error;
+                        }
+                    } );
+
+                if ( dialog.open() == Window.OK )
+                {
+                    String value = dialog.getValue();
+                    resources.add( value );
+                    viewer.add( value );
+                }
+            }
+        } );
+
+        // Layout
+        composite.setLayout( new GridLayout( 2, false ) );
+        table.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true, 1, 3 ) );
+        btnAdd.setLayoutData( new GridData( SWT.FILL, SWT.FILL, false, false ) );
+        btnRemove.setLayoutData( new GridData( SWT.FILL, SWT.FILL, false, false ) );
+
+        return composite;
+    }
+
+
+    private void loadPreferences( boolean useDefaults )
+    {
+        String resourcesListStr = useDefaults ? getPreferenceStore().getDefaultString(
+            SigilCore.DEFAULT_EXCLUDED_RESOURCES ) : getPreferenceStore().getString(
+            SigilCore.DEFAULT_EXCLUDED_RESOURCES );
+        String[] resourcesArray = PrefsUtils.stringToArray( resourcesListStr );
+
+        resources = new ArrayList<String>( resourcesArray.length );
+        for ( String resource : resourcesArray )
+        {
+            resources.add( resource );
+        }
+    }
+
+
+    public void init( IWorkbench workbench )
+    {
+        this.workbench = workbench;
+    }
+
+
+    @Override
+    protected IPreferenceStore doGetPreferenceStore()
+    {
+        return SigilCore.getDefault().getPreferenceStore();
+    }
+
+
+    @Override
+    public boolean performOk()
+    {
+        String resourcesStr = PrefsUtils.arrayToString( resources.toArray( new String[resources.size()] ) );
+        getPreferenceStore().setValue( SigilCore.DEFAULT_EXCLUDED_RESOURCES, resourcesStr );
+        return true;
+    }
+
+
+    @Override
+    protected void performDefaults()
+    {
+        super.performDefaults();
+        loadPreferences( true );
+        viewer.setInput( resources );
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/LibraryConfigurationDialog.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/LibraryConfigurationDialog.java
index 265322e..6cf9db7 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/LibraryConfigurationDialog.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/LibraryConfigurationDialog.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences;
 
+
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.TreeSet;
@@ -57,244 +58,294 @@
 import org.eclipse.swt.widgets.Text;
 import org.osgi.framework.Version;
 
-public class LibraryConfigurationDialog extends TitleAreaDialog {
 
-	private static final Comparator<IPackageImport> COMPARATOR = new Comparator<IPackageImport>() {
-		public int compare(IPackageImport o1, IPackageImport o2) {
-			return o1.getPackageName().compareTo(o2.getPackageName());
-		}
-	};
-	
-	private String name;
-	private Version version;
-	private TreeSet<IPackageImport> packageImports = new TreeSet<IPackageImport>(COMPARATOR);
-	
-	private boolean editOnly;
+public class LibraryConfigurationDialog extends TitleAreaDialog
+{
 
-	private TableViewer viewer;
-	private Text txtName;
-	private Text txtVersion;
-	
-	public LibraryConfigurationDialog(Shell parentShell) {
-		super(parentShell);
-		name = "";
-		version = Version.emptyVersion;
-	}
+    private static final Comparator<IPackageImport> COMPARATOR = new Comparator<IPackageImport>()
+    {
+        public int compare( IPackageImport o1, IPackageImport o2 )
+        {
+            return o1.getPackageName().compareTo( o2.getPackageName() );
+        }
+    };
 
-	public LibraryConfigurationDialog(Shell parentShell, ILibrary lib) {
-		super(parentShell);
-		editOnly = true;
-		name = lib.getName();
-		version = lib.getVersion();
-		packageImports.addAll(  lib.getImports() );
-	}
-	
-	@Override
-	protected Control createDialogArea(Composite par) {
-		setTitle("Add Library");
-		Composite container = (Composite) super.createDialogArea(par);
-		
-		Composite topPanel = new Composite(container, SWT.NONE);
-				
-		new Label(topPanel, SWT.NONE).setText("Name");
-		
-		txtName = new Text(topPanel, SWT.BORDER);
-		txtName.setEditable( !editOnly );
-		if(name != null) txtName.setText(name);
-		
-		new Label(topPanel, SWT.NONE).setText("Version");
-		
-		txtVersion = new Text(topPanel, SWT.BORDER);
-		txtVersion.setText( version.toString() );
-		txtVersion.setEditable( !editOnly );
-		
-		Composite bottomPanel = new Composite(container, SWT.NONE);
-		
-		Table table = new Table(bottomPanel, SWT.BORDER);
-		table.setSize( new Point( 300, 200 ) );
-		
-		Button add = new Button(bottomPanel, SWT.PUSH);
-		add.setText("Add...");
-		
-		final Button edit = new Button(bottomPanel, SWT.PUSH);
-		edit.setText("Edit...");
-		edit.setEnabled(false);
-		
-		final Button remove = new Button(bottomPanel, SWT.PUSH);
-		remove.setText("Remove");
-		remove.setEnabled(false);
-		
-		updateState();
-		
-		// Hookup Listeners
-		txtName.addModifyListener(new ModifyListener() {
-			public void modifyText(ModifyEvent e) {
-				updateState();
-			}
-		});
-		txtVersion.addModifyListener(new ModifyListener() {
-			public void modifyText(ModifyEvent e) {
-				updateState();
-			}
-		});
-		add.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleAdd();
-			}
-		});
-		edit.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleEdit();
-			}
-		});
-		remove.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleRemove();
-			}
-		});
-		
-		// Layout
-		topPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		topPanel.setLayout(new GridLayout(2, false));
-		txtName.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		txtVersion.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		
-		bottomPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-		bottomPanel.setLayout(new GridLayout(2, false));
-		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 4));
-		add.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-		edit.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-		remove.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-		
-		// Table Viewer
-		viewer = new TableViewer(table);
-		viewer.setLabelProvider(new LabelProvider() {
-			@Override
-			public String getText(Object element) {
-				IPackageImport pi = (IPackageImport) element;
-				return pi.getPackageName() + " " + pi.getVersions();
-			}			
-		});
-		viewer.addSelectionChangedListener( new ISelectionChangedListener() {
-			public void selectionChanged(SelectionChangedEvent event) {
-				edit.setEnabled(!event.getSelection().isEmpty());
-				remove.setEnabled(!event.getSelection().isEmpty());
-			}
-		});
-		viewer.setContentProvider( new DefaultTableProvider() {
-			public Object[] getElements(Object inputElement) {
-				return toArray(inputElement);
-			}
-		} );
+    private String name;
+    private Version version;
+    private TreeSet<IPackageImport> packageImports = new TreeSet<IPackageImport>( COMPARATOR );
 
-		viewer.setInput(packageImports);
-		return container;
-	}
-	
-	private void updateState() {
-		String error = null;
-		String warning = null;
-		
-		name = txtName.getText();
-		
-		try {
-			version = new Version(txtVersion.getText());
-			if(version.getQualifier().indexOf('_') > -1) {
-				warning = "The use of underscores in a version qualifier is discouraged.";
-			}
-		} catch (IllegalArgumentException e) {
-			version = null;
-			error = "Invalid version format";
-		}
-		
-		Button okButton = getButton(IDialogConstants.OK_ID);
-		if(okButton != null && !okButton.isDisposed()) okButton.setEnabled(allowOkay());
-		
-		setErrorMessage(error);
-		setMessage(warning, IMessageProvider.WARNING);
-	}
-	
-	private boolean allowOkay() {
-		return name != null && name.length() > 0 && version != null;
-	}
-	
-	@Override
-	protected Button createButton(Composite parent, int id, String label, boolean defaultButton) {
-		Button button = super.createButton(parent, id, label, defaultButton);
-		if(id == IDialogConstants.OK_ID) {
-			button.setEnabled(allowOkay());
-		}
-		return button;
-	}
-	
-	private void handleAdd() {
-		/*NewResourceSelectionDialog<? extends IPackageModelElement> dialog = ResourcesDialogHelper.createImportDialog(getShell(), "Add Imported Package", null, packageImports);
-		if ( dialog.open() == Window.OK ) {
-			IPackageImport pi = ModelElementFactory.getInstance().newModelElement(IPackageImport.class);
-			pi.setPackageName(dialog.getSelectedName());
-			pi.setVersions(dialog.getSelectedVersions());
-			pi.setOptional(dialog.isOptional());
-			
-			packageImports.add(pi);
-			viewer.refresh();
-		}*/
-	}
+    private boolean editOnly;
 
-	private void handleEdit() {
-		/*IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
-		
-		boolean changed = false;
-		
-		if ( !selection.isEmpty() ) {
-			for ( Iterator<IPackageImport> i = selection.iterator(); i.hasNext(); ) {	
-				IPackageImport packageImport = i.next();
-				NewResourceSelectionDialog<? extends IPackageModelElement> dialog = ResourcesDialogHelper.createImportDialog( getShell(), "Edit Imported Package", packageImport, packageImports );
-				dialog.setVersions( packageImport.getVersions() );
-				dialog.setOptional(packageImport.isOptional());
-				if ( dialog.open() == Window.OK ) {
-					changed = true;
-					String packageName = dialog.getSelectedName();
-					VersionRange versionRange = dialog.getSelectedVersions();
-					
-					IPackageImport newImport = ModelElementFactory.getInstance().newModelElement(IPackageImport.class);
-					newImport.setPackageName(packageName);
-					newImport.setVersions(versionRange);
-					newImport.setOptional(dialog.isOptional());
-					
-					packageImports.remove(packageImport);
-					packageImports.add(newImport);
-				}
-			}
-		}
-		
-		if ( changed ) {
-			viewer.refresh();
-		} */
-	}
+    private TableViewer viewer;
+    private Text txtName;
+    private Text txtVersion;
 
-	private void handleRemove() {
-		IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
 
-		if ( !selection.isEmpty() ) {
-			for ( Iterator<IPackageImport> i = selection.iterator(); i.hasNext(); ) {			
-				packageImports.remove( i.next() );
-			}		
-			
-			viewer.refresh();
-		}
-	}
+    public LibraryConfigurationDialog( Shell parentShell )
+    {
+        super( parentShell );
+        name = "";
+        version = Version.emptyVersion;
+    }
 
-	public ILibrary getLibrary() {
-		ILibrary library = ModelElementFactory.getInstance().newModelElement(ILibrary.class);
-		
-		library.setName(name);
-		library.setVersion(version);
-		
-		for (IPackageImport pi : packageImports) {
-			library.addImport(pi);
-		}
-		
-		return library;
-	}
+
+    public LibraryConfigurationDialog( Shell parentShell, ILibrary lib )
+    {
+        super( parentShell );
+        editOnly = true;
+        name = lib.getName();
+        version = lib.getVersion();
+        packageImports.addAll( lib.getImports() );
+    }
+
+
+    @Override
+    protected Control createDialogArea( Composite par )
+    {
+        setTitle( "Add Library" );
+        Composite container = ( Composite ) super.createDialogArea( par );
+
+        Composite topPanel = new Composite( container, SWT.NONE );
+
+        new Label( topPanel, SWT.NONE ).setText( "Name" );
+
+        txtName = new Text( topPanel, SWT.BORDER );
+        txtName.setEditable( !editOnly );
+        if ( name != null )
+            txtName.setText( name );
+
+        new Label( topPanel, SWT.NONE ).setText( "Version" );
+
+        txtVersion = new Text( topPanel, SWT.BORDER );
+        txtVersion.setText( version.toString() );
+        txtVersion.setEditable( !editOnly );
+
+        Composite bottomPanel = new Composite( container, SWT.NONE );
+
+        Table table = new Table( bottomPanel, SWT.BORDER );
+        table.setSize( new Point( 300, 200 ) );
+
+        Button add = new Button( bottomPanel, SWT.PUSH );
+        add.setText( "Add..." );
+
+        final Button edit = new Button( bottomPanel, SWT.PUSH );
+        edit.setText( "Edit..." );
+        edit.setEnabled( false );
+
+        final Button remove = new Button( bottomPanel, SWT.PUSH );
+        remove.setText( "Remove" );
+        remove.setEnabled( false );
+
+        updateState();
+
+        // Hookup Listeners
+        txtName.addModifyListener( new ModifyListener()
+        {
+            public void modifyText( ModifyEvent e )
+            {
+                updateState();
+            }
+        } );
+        txtVersion.addModifyListener( new ModifyListener()
+        {
+            public void modifyText( ModifyEvent e )
+            {
+                updateState();
+            }
+        } );
+        add.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                handleAdd();
+            }
+        } );
+        edit.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                handleEdit();
+            }
+        } );
+        remove.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                handleRemove();
+            }
+        } );
+
+        // Layout
+        topPanel.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        topPanel.setLayout( new GridLayout( 2, false ) );
+        txtName.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        txtVersion.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+
+        bottomPanel.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
+        bottomPanel.setLayout( new GridLayout( 2, false ) );
+        table.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true, 1, 4 ) );
+        add.setLayoutData( new GridData( SWT.FILL, SWT.FILL, false, false ) );
+        edit.setLayoutData( new GridData( SWT.FILL, SWT.FILL, false, false ) );
+        remove.setLayoutData( new GridData( SWT.FILL, SWT.FILL, false, false ) );
+
+        // Table Viewer
+        viewer = new TableViewer( table );
+        viewer.setLabelProvider( new LabelProvider()
+        {
+            @Override
+            public String getText( Object element )
+            {
+                IPackageImport pi = ( IPackageImport ) element;
+                return pi.getPackageName() + " " + pi.getVersions();
+            }
+        } );
+        viewer.addSelectionChangedListener( new ISelectionChangedListener()
+        {
+            public void selectionChanged( SelectionChangedEvent event )
+            {
+                edit.setEnabled( !event.getSelection().isEmpty() );
+                remove.setEnabled( !event.getSelection().isEmpty() );
+            }
+        } );
+        viewer.setContentProvider( new DefaultTableProvider()
+        {
+            public Object[] getElements( Object inputElement )
+            {
+                return toArray( inputElement );
+            }
+        } );
+
+        viewer.setInput( packageImports );
+        return container;
+    }
+
+
+    private void updateState()
+    {
+        String error = null;
+        String warning = null;
+
+        name = txtName.getText();
+
+        try
+        {
+            version = new Version( txtVersion.getText() );
+            if ( version.getQualifier().indexOf( '_' ) > -1 )
+            {
+                warning = "The use of underscores in a version qualifier is discouraged.";
+            }
+        }
+        catch ( IllegalArgumentException e )
+        {
+            version = null;
+            error = "Invalid version format";
+        }
+
+        Button okButton = getButton( IDialogConstants.OK_ID );
+        if ( okButton != null && !okButton.isDisposed() )
+            okButton.setEnabled( allowOkay() );
+
+        setErrorMessage( error );
+        setMessage( warning, IMessageProvider.WARNING );
+    }
+
+
+    private boolean allowOkay()
+    {
+        return name != null && name.length() > 0 && version != null;
+    }
+
+
+    @Override
+    protected Button createButton( Composite parent, int id, String label, boolean defaultButton )
+    {
+        Button button = super.createButton( parent, id, label, defaultButton );
+        if ( id == IDialogConstants.OK_ID )
+        {
+            button.setEnabled( allowOkay() );
+        }
+        return button;
+    }
+
+
+    private void handleAdd()
+    {
+        /*NewResourceSelectionDialog<? extends IPackageModelElement> dialog = ResourcesDialogHelper.createImportDialog(getShell(), "Add Imported Package", null, packageImports);
+        if ( dialog.open() == Window.OK ) {
+        	IPackageImport pi = ModelElementFactory.getInstance().newModelElement(IPackageImport.class);
+        	pi.setPackageName(dialog.getSelectedName());
+        	pi.setVersions(dialog.getSelectedVersions());
+        	pi.setOptional(dialog.isOptional());
+        	
+        	packageImports.add(pi);
+        	viewer.refresh();
+        }*/
+    }
+
+
+    private void handleEdit()
+    {
+        /*IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
+        
+        boolean changed = false;
+        
+        if ( !selection.isEmpty() ) {
+        	for ( Iterator<IPackageImport> i = selection.iterator(); i.hasNext(); ) {	
+        		IPackageImport packageImport = i.next();
+        		NewResourceSelectionDialog<? extends IPackageModelElement> dialog = ResourcesDialogHelper.createImportDialog( getShell(), "Edit Imported Package", packageImport, packageImports );
+        		dialog.setVersions( packageImport.getVersions() );
+        		dialog.setOptional(packageImport.isOptional());
+        		if ( dialog.open() == Window.OK ) {
+        			changed = true;
+        			String packageName = dialog.getSelectedName();
+        			VersionRange versionRange = dialog.getSelectedVersions();
+        			
+        			IPackageImport newImport = ModelElementFactory.getInstance().newModelElement(IPackageImport.class);
+        			newImport.setPackageName(packageName);
+        			newImport.setVersions(versionRange);
+        			newImport.setOptional(dialog.isOptional());
+        			
+        			packageImports.remove(packageImport);
+        			packageImports.add(newImport);
+        		}
+        	}
+        }
+        
+        if ( changed ) {
+        	viewer.refresh();
+        } */
+    }
+
+
+    private void handleRemove()
+    {
+        IStructuredSelection selection = ( IStructuredSelection ) viewer.getSelection();
+
+        if ( !selection.isEmpty() )
+        {
+            for ( Iterator<IPackageImport> i = selection.iterator(); i.hasNext(); )
+            {
+                packageImports.remove( i.next() );
+            }
+
+            viewer.refresh();
+        }
+    }
+
+
+    public ILibrary getLibrary()
+    {
+        ILibrary library = ModelElementFactory.getInstance().newModelElement( ILibrary.class );
+
+        library.setName( name );
+        library.setVersion( version );
+
+        for ( IPackageImport pi : packageImports )
+        {
+            library.addImport( pi );
+        }
+
+        return library;
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/LibraryPreferencePage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/LibraryPreferencePage.java
index fe3208a..75fd3a2 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/LibraryPreferencePage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/LibraryPreferencePage.java
@@ -17,8 +17,9 @@
  * under the License.
  */
 
-package org.apache.felix.sigil.ui.eclipse.ui.preferences;

-

+package org.apache.felix.sigil.ui.eclipse.ui.preferences;
+
+
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.TreeSet;
@@ -27,8 +28,8 @@
 import org.apache.felix.sigil.model.eclipse.ILibrary;
 import org.apache.felix.sigil.ui.eclipse.ui.util.DefaultTableProvider;
 import org.eclipse.jface.layout.GridDataFactory;
-import org.eclipse.jface.preference.IPreferenceStore;

-import org.eclipse.jface.preference.PreferencePage;

+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.LabelProvider;
@@ -36,208 +37,257 @@
 import org.eclipse.jface.viewers.SelectionChangedEvent;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;

+import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;

-import org.eclipse.swt.layout.GridLayout;

+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;

-import org.eclipse.swt.widgets.Control;

-import org.eclipse.swt.widgets.Label;

+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Table;
-import org.eclipse.ui.IWorkbench;

-import org.eclipse.ui.IWorkbenchPreferencePage;

-

-public class LibraryPreferencePage extends PreferencePage implements

-		IWorkbenchPreferencePage {

-

-	private TreeSet<ILibrary> libraries;
-	private TableViewer libraryView;
-	
-	private Table table;
-	private Button btnAdd;
-	private Button btnEdit;
-	private Button btnRemove;
-	
-	public void init(IWorkbench workbench) {

-	}

-	

-	@Override

-	protected Control createContents(Composite parent) {

-		Control control = initContents( parent );

-		loadPreferences();

-		return control;

-	}

-

-	@Override

-	protected IPreferenceStore doGetPreferenceStore() {

-		return SigilCore.getDefault().getPreferenceStore();

-	}

-

-	@Override

-	protected void performDefaults() {

-		super.performDefaults();

-	}

-

-	@Override

-	public boolean performOk() {

-		IPreferenceStore prefs = getPreferenceStore();
-		for ( String key : prefs.getString( SigilCore.LIBRARY_KEYS_PREF ).split( "," ) ) {
-			prefs.setToDefault(key);
-		}
-		
-		StringBuffer keys = new StringBuffer();
-		
-		for ( ILibrary lib : libraries ) {
-			throw new IllegalStateException( "XXX-FIXME-XXX");
-		}
-		
-		prefs.setValue( SigilCore.LIBRARY_KEYS_PREF, keys.toString() );
-		
-		return true;
-	}

-	

-	private Control initContents(Composite parent) {

-		Composite control = new Composite(parent, SWT.NONE);

-		control.setFont(parent.getFont());
-		

-		GridLayout grid = new GridLayout(3, false);

-		control.setLayout(grid);

-		

-		initRepositories(control);
-		
-		return control;

-	}
-	
-	private void initRepositories(Composite composite) {
-		// Create controls
-		new Label(composite, SWT.NONE).setText("Libraries:");
-		new Label(composite, SWT.NONE); // Spacer
-		table = new Table(composite, SWT.SINGLE | SWT.BORDER );
-		//table.setFont(control.getFont());
-		btnAdd = new Button(composite, SWT.PUSH);
-		btnAdd.setText("Add...");
-		//add.setFont(control.getFont());
-		btnEdit = new Button(composite, SWT.PUSH);
-		btnEdit.setText("Edit...");
-		//edit.setFont(control.getFont());
-		btnRemove = new Button(composite, SWT.PUSH);
-		btnRemove.setText("Remove");
-		//remove.setFont(control.getFont());
-		
-		// Table Model
-		libraries = new TreeSet<ILibrary>(new Comparator<ILibrary> () {
-			public int compare(ILibrary l1, ILibrary l2) {
-				int c = l1.getName().compareTo( l2.getName() );
-				if ( c == 0 ) {
-					c = l1.getVersion().compareTo( l2.getVersion() );
-				}
-				return c;
-			}
-		});
-		libraryView = new TableViewer(table);
-		libraryView.setLabelProvider(new LabelProvider() {
-			public String getText(Object element) {
-				ILibrary rep = (ILibrary) element;
-				return rep.getName() + " " + rep.getVersion();
-			}			
-		});
-		libraryView.setContentProvider( new DefaultTableProvider() {
-			public Object[] getElements(Object inputElement) {
-				return toArray(inputElement);
-			}
-		} );
-		libraryView.setInput(libraries);
-		
-		// Initialize controls
-		updateButtonStates();
-		
-		// Hookup Listeners
-		libraryView.addSelectionChangedListener( new ISelectionChangedListener() {
-			public void selectionChanged(SelectionChangedEvent event) {
-				updateButtonStates();
-			}
-		});
-		btnAdd.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleAdd();
-			}
-		});
-		btnEdit.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleEdit();
-			}
-		});
-		btnRemove.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleRemove();
-			}
-		});
-		
-		// Layout
-		composite.setLayout(new GridLayout(2, false));
-		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 4));
-		GridDataFactory buttonGD = GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER);
-		btnAdd.setLayoutData(buttonGD.create());
-		btnEdit.setLayoutData(buttonGD.create());
-		btnRemove.setLayoutData(buttonGD.create());
-	}
-	
-	private void updateButtonStates() {
-		ISelection sel = libraryView.getSelection();
-		btnEdit.setEnabled(!sel.isEmpty());
-		btnRemove.setEnabled(!sel.isEmpty());
-	}
-	
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
 
-	private void handleAdd() {
-		LibraryConfigurationDialog d = new LibraryConfigurationDialog(getShell());
-		if ( d.open() == Window.OK ) {
-			libraries.add(d.getLibrary());
-			libraryView.refresh();
-		}
-	}
 
-	private void handleEdit() {
-		IStructuredSelection sel = (IStructuredSelection) libraryView.getSelection();
-		boolean change = false;
-		
-		
-		for ( @SuppressWarnings("unchecked") Iterator<ILibrary> i = sel.iterator(); i.hasNext(); ) {
-			ILibrary lib = i.next();
-			LibraryConfigurationDialog d = new LibraryConfigurationDialog(getShell(), lib );
-			if ( d.open() == Window.OK ) {
-				libraries.remove(lib);
-				libraries.add(d.getLibrary());
-				change = true;
-			}
-		}
-		
-		if ( change ) {
-			libraryView.refresh();
-		}
-	}
+public class LibraryPreferencePage extends PreferencePage implements IWorkbenchPreferencePage
+{
 
-	private void handleRemove() {
-		IStructuredSelection sel = (IStructuredSelection) libraryView.getSelection();
-		for ( @SuppressWarnings("unchecked") Iterator<ILibrary> i = sel.iterator(); i.hasNext(); ) {
-			libraries.remove(i);
-		}
-		libraryView.refresh();
-	}
+    private TreeSet<ILibrary> libraries;
+    private TableViewer libraryView;
 
-	private void loadPreferences() {

-		IPreferenceStore prefs = getPreferenceStore();
-		String keys = prefs.getString( SigilCore.LIBRARY_KEYS_PREF );
-		if ( keys.trim().length() > 0 ) {
-			for ( String key : keys.split( "," ) ) {
-				String libStr = prefs.getString(key);
-				// XXX-FIXME-XXX parse library string
-				// lib = parse(libstr);
-				// libraries.add(lib);
-			}
-			libraryView.refresh();
-		}
-	}

-}

+    private Table table;
+    private Button btnAdd;
+    private Button btnEdit;
+    private Button btnRemove;
+
+
+    public void init( IWorkbench workbench )
+    {
+    }
+
+
+    @Override
+    protected Control createContents( Composite parent )
+    {
+        Control control = initContents( parent );
+        loadPreferences();
+        return control;
+    }
+
+
+    @Override
+    protected IPreferenceStore doGetPreferenceStore()
+    {
+        return SigilCore.getDefault().getPreferenceStore();
+    }
+
+
+    @Override
+    protected void performDefaults()
+    {
+        super.performDefaults();
+    }
+
+
+    @Override
+    public boolean performOk()
+    {
+        IPreferenceStore prefs = getPreferenceStore();
+        for ( String key : prefs.getString( SigilCore.LIBRARY_KEYS_PREF ).split( "," ) )
+        {
+            prefs.setToDefault( key );
+        }
+
+        StringBuffer keys = new StringBuffer();
+
+        for ( ILibrary lib : libraries )
+        {
+            throw new IllegalStateException( "XXX-FIXME-XXX" );
+        }
+
+        prefs.setValue( SigilCore.LIBRARY_KEYS_PREF, keys.toString() );
+
+        return true;
+    }
+
+
+    private Control initContents( Composite parent )
+    {
+        Composite control = new Composite( parent, SWT.NONE );
+        control.setFont( parent.getFont() );
+
+        GridLayout grid = new GridLayout( 3, false );
+        control.setLayout( grid );
+
+        initRepositories( control );
+
+        return control;
+    }
+
+
+    private void initRepositories( Composite composite )
+    {
+        // Create controls
+        new Label( composite, SWT.NONE ).setText( "Libraries:" );
+        new Label( composite, SWT.NONE ); // Spacer
+        table = new Table( composite, SWT.SINGLE | SWT.BORDER );
+        //table.setFont(control.getFont());
+        btnAdd = new Button( composite, SWT.PUSH );
+        btnAdd.setText( "Add..." );
+        //add.setFont(control.getFont());
+        btnEdit = new Button( composite, SWT.PUSH );
+        btnEdit.setText( "Edit..." );
+        //edit.setFont(control.getFont());
+        btnRemove = new Button( composite, SWT.PUSH );
+        btnRemove.setText( "Remove" );
+        //remove.setFont(control.getFont());
+
+        // Table Model
+        libraries = new TreeSet<ILibrary>( new Comparator<ILibrary>()
+        {
+            public int compare( ILibrary l1, ILibrary l2 )
+            {
+                int c = l1.getName().compareTo( l2.getName() );
+                if ( c == 0 )
+                {
+                    c = l1.getVersion().compareTo( l2.getVersion() );
+                }
+                return c;
+            }
+        } );
+        libraryView = new TableViewer( table );
+        libraryView.setLabelProvider( new LabelProvider()
+        {
+            public String getText( Object element )
+            {
+                ILibrary rep = ( ILibrary ) element;
+                return rep.getName() + " " + rep.getVersion();
+            }
+        } );
+        libraryView.setContentProvider( new DefaultTableProvider()
+        {
+            public Object[] getElements( Object inputElement )
+            {
+                return toArray( inputElement );
+            }
+        } );
+        libraryView.setInput( libraries );
+
+        // Initialize controls
+        updateButtonStates();
+
+        // Hookup Listeners
+        libraryView.addSelectionChangedListener( new ISelectionChangedListener()
+        {
+            public void selectionChanged( SelectionChangedEvent event )
+            {
+                updateButtonStates();
+            }
+        } );
+        btnAdd.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                handleAdd();
+            }
+        } );
+        btnEdit.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                handleEdit();
+            }
+        } );
+        btnRemove.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                handleRemove();
+            }
+        } );
+
+        // Layout
+        composite.setLayout( new GridLayout( 2, false ) );
+        table.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true, 1, 4 ) );
+        GridDataFactory buttonGD = GridDataFactory.swtDefaults().align( SWT.FILL, SWT.CENTER );
+        btnAdd.setLayoutData( buttonGD.create() );
+        btnEdit.setLayoutData( buttonGD.create() );
+        btnRemove.setLayoutData( buttonGD.create() );
+    }
+
+
+    private void updateButtonStates()
+    {
+        ISelection sel = libraryView.getSelection();
+        btnEdit.setEnabled( !sel.isEmpty() );
+        btnRemove.setEnabled( !sel.isEmpty() );
+    }
+
+
+    private void handleAdd()
+    {
+        LibraryConfigurationDialog d = new LibraryConfigurationDialog( getShell() );
+        if ( d.open() == Window.OK )
+        {
+            libraries.add( d.getLibrary() );
+            libraryView.refresh();
+        }
+    }
+
+
+    private void handleEdit()
+    {
+        IStructuredSelection sel = ( IStructuredSelection ) libraryView.getSelection();
+        boolean change = false;
+
+        for ( @SuppressWarnings("unchecked")
+        Iterator<ILibrary> i = sel.iterator(); i.hasNext(); )
+        {
+            ILibrary lib = i.next();
+            LibraryConfigurationDialog d = new LibraryConfigurationDialog( getShell(), lib );
+            if ( d.open() == Window.OK )
+            {
+                libraries.remove( lib );
+                libraries.add( d.getLibrary() );
+                change = true;
+            }
+        }
+
+        if ( change )
+        {
+            libraryView.refresh();
+        }
+    }
+
+
+    private void handleRemove()
+    {
+        IStructuredSelection sel = ( IStructuredSelection ) libraryView.getSelection();
+        for ( @SuppressWarnings("unchecked")
+        Iterator<ILibrary> i = sel.iterator(); i.hasNext(); )
+        {
+            libraries.remove( i );
+        }
+        libraryView.refresh();
+    }
+
+
+    private void loadPreferences()
+    {
+        IPreferenceStore prefs = getPreferenceStore();
+        String keys = prefs.getString( SigilCore.LIBRARY_KEYS_PREF );
+        if ( keys.trim().length() > 0 )
+        {
+            for ( String key : keys.split( "," ) )
+            {
+                String libStr = prefs.getString( key );
+                // XXX-FIXME-XXX parse library string
+                // lib = parse(libstr);
+                // libraries.add(lib);
+            }
+            libraryView.refresh();
+        }
+    }
+}
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/OptionalPrompt.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/OptionalPrompt.java
index 460fce3..570b195 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/OptionalPrompt.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/OptionalPrompt.java
@@ -19,58 +19,76 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences;
 
+
 import org.apache.felix.sigil.eclipse.preferences.PromptablePreference;
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.MessageDialogWithToggle;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.swt.widgets.Shell;
 
-public class OptionalPrompt {
-	public static boolean optionallyPrompt(IPreferenceStore prefStore, String prefName, String title, String text, Shell parentShell) {
-		boolean result = false;
-		
-		PromptablePreference value = PromptablePreference.valueOf(prefStore.getString(prefName));
-		switch(value) {
-		case Always:
-			result = true;
-			break;
-		case Never:
-			result = false;
-			break;
-		case Prompt:
-			MessageDialogWithToggle dialog = MessageDialogWithToggle.openYesNoQuestion(parentShell, title, text, "Do not ask this again", false, null, null);
-			result = (dialog.getReturnCode() == IDialogConstants.YES_ID);
-			if(dialog.getToggleState()) {
-				// User said don't ask again... take the current answer as the new preference
-				prefStore.setValue(prefName, result ? PromptablePreference.Always.name() : PromptablePreference.Never.name());
-			}
-		}
-		
-		return result;
-	}
-	
-	public static int optionallyPromptWithCancel(IPreferenceStore prefStore, String prefName, String title, String text, Shell parentShell) {
-		int result = IDialogConstants.NO_ID;
-		
-		PromptablePreference value = PromptablePreference.valueOf(prefStore.getString(prefName));
-		switch(value) {
-		case Always:
-			result = IDialogConstants.YES_ID;
-			break;
-		case Never:
-			result = IDialogConstants.NO_ID;
-			break;
-		case Prompt:
-			MessageDialogWithToggle dialog = MessageDialogWithToggle.openYesNoCancelQuestion(parentShell, title, text, "Do not ask this again", false, null, null);
-			result = dialog.getReturnCode();
-			if ( result != IDialogConstants.CANCEL_ID ) {
-				if(dialog.getToggleState()) {
-					// User said don't ask again... take the current answer as the new preference
-					prefStore.setValue(prefName, (result == IDialogConstants.YES_ID) ? PromptablePreference.Always.name() : PromptablePreference.Never.name());
-				}
-			}
-		}
-		
-		return result;
-	}
+
+public class OptionalPrompt
+{
+    public static boolean optionallyPrompt( IPreferenceStore prefStore, String prefName, String title, String text,
+        Shell parentShell )
+    {
+        boolean result = false;
+
+        PromptablePreference value = PromptablePreference.valueOf( prefStore.getString( prefName ) );
+        switch ( value )
+        {
+            case Always:
+                result = true;
+                break;
+            case Never:
+                result = false;
+                break;
+            case Prompt:
+                MessageDialogWithToggle dialog = MessageDialogWithToggle.openYesNoQuestion( parentShell, title, text,
+                    "Do not ask this again", false, null, null );
+                result = ( dialog.getReturnCode() == IDialogConstants.YES_ID );
+                if ( dialog.getToggleState() )
+                {
+                    // User said don't ask again... take the current answer as the new preference
+                    prefStore.setValue( prefName, result ? PromptablePreference.Always.name()
+                        : PromptablePreference.Never.name() );
+                }
+        }
+
+        return result;
+    }
+
+
+    public static int optionallyPromptWithCancel( IPreferenceStore prefStore, String prefName, String title,
+        String text, Shell parentShell )
+    {
+        int result = IDialogConstants.NO_ID;
+
+        PromptablePreference value = PromptablePreference.valueOf( prefStore.getString( prefName ) );
+        switch ( value )
+        {
+            case Always:
+                result = IDialogConstants.YES_ID;
+                break;
+            case Never:
+                result = IDialogConstants.NO_ID;
+                break;
+            case Prompt:
+                MessageDialogWithToggle dialog = MessageDialogWithToggle.openYesNoCancelQuestion( parentShell, title,
+                    text, "Do not ask this again", false, null, null );
+                result = dialog.getReturnCode();
+                if ( result != IDialogConstants.CANCEL_ID )
+                {
+                    if ( dialog.getToggleState() )
+                    {
+                        // User said don't ask again... take the current answer as the new preference
+                        prefStore.setValue( prefName,
+                            ( result == IDialogConstants.YES_ID ) ? PromptablePreference.Always.name()
+                                : PromptablePreference.Never.name() );
+                    }
+                }
+        }
+
+        return result;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/ProjectDependentPreferencesPage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/ProjectDependentPreferencesPage.java
index d7846ea..1d14b70 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/ProjectDependentPreferencesPage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/ProjectDependentPreferencesPage.java
@@ -19,31 +19,43 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences;
 
+
 import org.apache.felix.sigil.ui.eclipse.ui.util.ProjectUtils;
 import org.eclipse.jface.preference.PreferencePage;
 
-public abstract class ProjectDependentPreferencesPage extends PreferencePage {
 
-	public ProjectDependentPreferencesPage(String title) {
-		super(title);
-	}
+public abstract class ProjectDependentPreferencesPage extends PreferencePage
+{
 
-	@Override
-	public boolean performOk() {
-		if ( isDirty() ) {
-			return ProjectUtils.runTaskWithRebuildCheck(new Runnable() {
-				public void run() {
-					doSave();
-				}
-				
-			}, getShell());
-		}
-		else {
-			return true;
-		}
-	}
+    public ProjectDependentPreferencesPage( String title )
+    {
+        super( title );
+    }
 
-	protected abstract void doSave();
 
-	protected abstract boolean isDirty();
+    @Override
+    public boolean performOk()
+    {
+        if ( isDirty() )
+        {
+            return ProjectUtils.runTaskWithRebuildCheck( new Runnable()
+            {
+                public void run()
+                {
+                    doSave();
+                }
+
+            }, getShell() );
+        }
+        else
+        {
+            return true;
+        }
+    }
+
+
+    protected abstract void doSave();
+
+
+    protected abstract boolean isDirty();
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/SigilPreferencePage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/SigilPreferencePage.java
index fb717bf..24a7ec5 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/SigilPreferencePage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/SigilPreferencePage.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.preferences.PromptablePreference;
 import org.eclipse.jface.preference.FieldEditorPreferencePage;
@@ -27,33 +28,42 @@
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferencePage;
 
-public class SigilPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
 
-	@Override
-	protected void createFieldEditors() {
-		RadioGroupFieldEditor impExpField = new RadioGroupFieldEditor(SigilCore.PREFERENCES_ADD_IMPORT_FOR_EXPORT, "Add Imports for New Exports", 1, new String[][] {
-				new String[] { "Always (Recommended)", PromptablePreference.Always.toString() },
-				new String[] { "Prompt", PromptablePreference.Prompt.toString() },
-				new String[] { "Never", PromptablePreference.Never.toString() }
-		}, getFieldEditorParent(), true);
-		
-		addField(impExpField);
-		
-		RadioGroupFieldEditor rebuildExpField = new RadioGroupFieldEditor(SigilCore.PREFERENCES_REBUILD_PROJECTS, "Rebuild Projects On Install Change", 1, new String[][] {
-				new String[] { "Always (Recommended)", PromptablePreference.Always.toString() },
-				new String[] { "Prompt", PromptablePreference.Prompt.toString() },
-				new String[] { "Never", PromptablePreference.Never.toString() }
-		}, getFieldEditorParent(), true);
-		
-		addField(rebuildExpField);		
-	}
-	
-	@Override
-	protected IPreferenceStore doGetPreferenceStore() {
-		return SigilCore.getDefault().getPreferenceStore();
-	}
+public class SigilPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage
+{
 
-	public void init(IWorkbench workbench) {
-	}
+    @Override
+    protected void createFieldEditors()
+    {
+        RadioGroupFieldEditor impExpField = new RadioGroupFieldEditor( SigilCore.PREFERENCES_ADD_IMPORT_FOR_EXPORT,
+            "Add Imports for New Exports", 1, new String[][]
+                { new String[]
+                    { "Always (Recommended)", PromptablePreference.Always.toString() }, new String[]
+                    { "Prompt", PromptablePreference.Prompt.toString() }, new String[]
+                    { "Never", PromptablePreference.Never.toString() } }, getFieldEditorParent(), true );
+
+        addField( impExpField );
+
+        RadioGroupFieldEditor rebuildExpField = new RadioGroupFieldEditor( SigilCore.PREFERENCES_REBUILD_PROJECTS,
+            "Rebuild Projects On Install Change", 1, new String[][]
+                { new String[]
+                    { "Always (Recommended)", PromptablePreference.Always.toString() }, new String[]
+                    { "Prompt", PromptablePreference.Prompt.toString() }, new String[]
+                    { "Never", PromptablePreference.Never.toString() } }, getFieldEditorParent(), true );
+
+        addField( rebuildExpField );
+    }
+
+
+    @Override
+    protected IPreferenceStore doGetPreferenceStore()
+    {
+        return SigilCore.getDefault().getPreferenceStore();
+    }
+
+
+    public void init( IWorkbench workbench )
+    {
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/VersionsPreferencePage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/VersionsPreferencePage.java
index 290467f..30db1fa 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/VersionsPreferencePage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/VersionsPreferencePage.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.model.common.VersionRange;
 import org.apache.felix.sigil.model.common.VersionRangeBoundingRule;
@@ -43,326 +44,394 @@
 import org.eclipse.ui.IWorkbenchPreferencePage;
 import org.osgi.framework.Version;
 
-public class VersionsPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
 
-	private static final Version SAMPLE_VERSION = new Version(1, 2, 3, "qualifier");
+public class VersionsPreferencePage extends PreferencePage implements IWorkbenchPreferencePage
+{
 
-	private IWorkbench workbench;
+    private static final Version SAMPLE_VERSION = new Version( 1, 2, 3, "qualifier" );
 
-	private Button btnLowerBoundExact;
-	private Button btnLowerBoundMicro;
-	private Button btnLowerBoundMinor;
-	private Button btnLowerBoundMajor;
-	private Button btnLowerBoundAny;
+    private IWorkbench workbench;
 
-	private Button btnUpperBoundExact;
-	private Button btnUpperBoundMicro;
-	private Button btnUpperBoundMinor;
-	private Button btnUpperBoundMajor;
-	private Button btnUpperBoundAny;
+    private Button btnLowerBoundExact;
+    private Button btnLowerBoundMicro;
+    private Button btnLowerBoundMinor;
+    private Button btnLowerBoundMajor;
+    private Button btnLowerBoundAny;
 
-	private Text txtSampleVersion;
-	private Label lblCalculatedRange;
-	private Text txtMatchVersion;
-	private Label lblMatchResult;
-	
-	private VersionRangeBoundingRule lowerBoundRule;
-	private VersionRangeBoundingRule upperBoundRule;
+    private Button btnUpperBoundExact;
+    private Button btnUpperBoundMicro;
+    private Button btnUpperBoundMinor;
+    private Button btnUpperBoundMajor;
+    private Button btnUpperBoundAny;
 
-	private Version sampleVersion = SAMPLE_VERSION;
-	private Version matchVersion = null;
-	
-	public VersionsPreferencePage() {
-		super();
-		setDescription("Specify the Lower and Upper bounds for a default version range calculated from a point version, e.g. \"1.2.3.qualifier\"");
-	}
-	
-	@Override
-	protected Control createContents(Composite parent) {
-		// Create controls
-		Composite composite = new Composite(parent, SWT.NONE);
+    private Text txtSampleVersion;
+    private Label lblCalculatedRange;
+    private Text txtMatchVersion;
+    private Label lblMatchResult;
 
-		Group grpLowerBound = new Group(composite, SWT.NONE);
-		grpLowerBound.setText("Lower Bound");
-		btnLowerBoundExact = new Button(grpLowerBound, SWT.RADIO);
-		btnLowerBoundExact.setText("Exact e.g. [1.2.3.qualifer, ...)");
-		btnLowerBoundMicro = new Button(grpLowerBound, SWT.RADIO);
-		btnLowerBoundMicro.setText("Micro e.g. [1.2.3, ...)");
-		btnLowerBoundMinor = new Button(grpLowerBound, SWT.RADIO);
-		btnLowerBoundMinor.setText("Minor e.g. [1.2, ...)");
-		btnLowerBoundMajor = new Button(grpLowerBound, SWT.RADIO);
-		btnLowerBoundMajor.setText("Major e.g. [1, ...)");
-		btnLowerBoundAny = new Button(grpLowerBound, SWT.RADIO);
-		btnLowerBoundAny.setText("Any e.g. [0, ...)");
+    private VersionRangeBoundingRule lowerBoundRule;
+    private VersionRangeBoundingRule upperBoundRule;
 
-		Group grpUpperBound = new Group(composite, SWT.NONE);
-		grpUpperBound.setText("Upper Bound");
+    private Version sampleVersion = SAMPLE_VERSION;
+    private Version matchVersion = null;
 
-		btnUpperBoundExact = new Button(grpUpperBound, SWT.RADIO);
-		btnUpperBoundExact.setText("Exact e.g. [..., 1.2.3.qualifer]");
-		btnUpperBoundMicro = new Button(grpUpperBound, SWT.RADIO);
-		btnUpperBoundMicro.setText("Micro e.g. [..., 1.2.4)");
-		btnUpperBoundMinor = new Button(grpUpperBound, SWT.RADIO);
-		btnUpperBoundMinor.setText("Minor e.g. [..., 1.3)");
-		btnUpperBoundMajor = new Button(grpUpperBound, SWT.RADIO);
-		btnUpperBoundMajor.setText("Major e.g. [..., 2)");
-		btnUpperBoundAny = new Button(grpUpperBound, SWT.RADIO);
-		btnUpperBoundAny.setText("Any e.g. [..., \u221e)");
-		
-		Group grpRangeTest = new Group(composite, SWT.NONE);
-		grpRangeTest.setText("Range Test");
-		new Label(grpRangeTest, SWT.NONE).setText("Sample Input Version: ");
-		txtSampleVersion = new Text(grpRangeTest, SWT.BORDER);
-		new Label(grpRangeTest, SWT.NONE).setText("Calculated Version Range: ");
-		lblCalculatedRange = new Label(grpRangeTest, SWT.NONE);
-		
-		new Label(grpRangeTest, SWT.NONE).setText("Test: ");
-		txtMatchVersion = new Text(grpRangeTest, SWT.BORDER);
-		new Label(grpRangeTest, SWT.NONE).setText("Result: ");
-		lblMatchResult = new Label(grpRangeTest, SWT.NONE);
 
-		// Initialize controls
-		loadPreferences(false);
-		updateRadioButtons();
-		
-		txtSampleVersion.setText(sampleVersion.toString());
-		updateCalculatedRange();
+    public VersionsPreferencePage()
+    {
+        super();
+        setDescription( "Specify the Lower and Upper bounds for a default version range calculated from a point version, e.g. \"1.2.3.qualifier\"" );
+    }
 
-		// Add listeners
-		SelectionListener buttonListener = new SelectionListener() {
-			public void widgetSelected(SelectionEvent e) {
-				readRadioButtons();
-				updateCalculatedRange();
-			}
 
-			public void widgetDefaultSelected(SelectionEvent e) {
-				readRadioButtons();
-				updateCalculatedRange();
-			}
-		};
-		btnLowerBoundAny.addSelectionListener(buttonListener);
-		btnLowerBoundMajor.addSelectionListener(buttonListener);
-		btnLowerBoundMinor.addSelectionListener(buttonListener);
-		btnLowerBoundMicro.addSelectionListener(buttonListener);
-		btnLowerBoundExact.addSelectionListener(buttonListener);
+    @Override
+    protected Control createContents( Composite parent )
+    {
+        // Create controls
+        Composite composite = new Composite( parent, SWT.NONE );
 
-		btnUpperBoundAny.addSelectionListener(buttonListener);
-		btnUpperBoundMajor.addSelectionListener(buttonListener);
-		btnUpperBoundMinor.addSelectionListener(buttonListener);
-		btnUpperBoundMicro.addSelectionListener(buttonListener);
-		btnUpperBoundExact.addSelectionListener(buttonListener);
-		
-		txtSampleVersion.addModifyListener(new ModifyListener() {
-			public void modifyText(ModifyEvent e) {
-				try {
-					sampleVersion = new Version(txtSampleVersion.getText());
-				} catch (IllegalArgumentException x) {
-					sampleVersion = null;
-				}
-				updateCalculatedRange();
-			}
-		});
-		txtMatchVersion.addModifyListener(new ModifyListener() {
-			public void modifyText(ModifyEvent e) {
-				try {
-					matchVersion = new Version(txtMatchVersion.getText());
-				} catch (IllegalArgumentException x) {
-					matchVersion = null;
-				}
-				updateCalculatedRange();
-			}
-		});
+        Group grpLowerBound = new Group( composite, SWT.NONE );
+        grpLowerBound.setText( "Lower Bound" );
+        btnLowerBoundExact = new Button( grpLowerBound, SWT.RADIO );
+        btnLowerBoundExact.setText( "Exact e.g. [1.2.3.qualifer, ...)" );
+        btnLowerBoundMicro = new Button( grpLowerBound, SWT.RADIO );
+        btnLowerBoundMicro.setText( "Micro e.g. [1.2.3, ...)" );
+        btnLowerBoundMinor = new Button( grpLowerBound, SWT.RADIO );
+        btnLowerBoundMinor.setText( "Minor e.g. [1.2, ...)" );
+        btnLowerBoundMajor = new Button( grpLowerBound, SWT.RADIO );
+        btnLowerBoundMajor.setText( "Major e.g. [1, ...)" );
+        btnLowerBoundAny = new Button( grpLowerBound, SWT.RADIO );
+        btnLowerBoundAny.setText( "Any e.g. [0, ...)" );
 
-		// Layout
-		GridLayout layout = new GridLayout(1, false);
-		layout.verticalSpacing = 20;
-		composite.setLayout(layout);
+        Group grpUpperBound = new Group( composite, SWT.NONE );
+        grpUpperBound.setText( "Upper Bound" );
 
-		grpLowerBound.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
-		grpLowerBound.setLayout(new GridLayout(1, false));
+        btnUpperBoundExact = new Button( grpUpperBound, SWT.RADIO );
+        btnUpperBoundExact.setText( "Exact e.g. [..., 1.2.3.qualifer]" );
+        btnUpperBoundMicro = new Button( grpUpperBound, SWT.RADIO );
+        btnUpperBoundMicro.setText( "Micro e.g. [..., 1.2.4)" );
+        btnUpperBoundMinor = new Button( grpUpperBound, SWT.RADIO );
+        btnUpperBoundMinor.setText( "Minor e.g. [..., 1.3)" );
+        btnUpperBoundMajor = new Button( grpUpperBound, SWT.RADIO );
+        btnUpperBoundMajor.setText( "Major e.g. [..., 2)" );
+        btnUpperBoundAny = new Button( grpUpperBound, SWT.RADIO );
+        btnUpperBoundAny.setText( "Any e.g. [..., \u221e)" );
 
-		grpUpperBound.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
-		grpUpperBound.setLayout(new GridLayout(1, false));
-		
-		grpRangeTest.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true));
-		grpRangeTest.setLayout(new GridLayout(2, false));
-		
-		txtSampleVersion.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		lblCalculatedRange.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		txtMatchVersion.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		lblMatchResult.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+        Group grpRangeTest = new Group( composite, SWT.NONE );
+        grpRangeTest.setText( "Range Test" );
+        new Label( grpRangeTest, SWT.NONE ).setText( "Sample Input Version: " );
+        txtSampleVersion = new Text( grpRangeTest, SWT.BORDER );
+        new Label( grpRangeTest, SWT.NONE ).setText( "Calculated Version Range: " );
+        lblCalculatedRange = new Label( grpRangeTest, SWT.NONE );
 
-		return composite;
-	}
+        new Label( grpRangeTest, SWT.NONE ).setText( "Test: " );
+        txtMatchVersion = new Text( grpRangeTest, SWT.BORDER );
+        new Label( grpRangeTest, SWT.NONE ).setText( "Result: " );
+        lblMatchResult = new Label( grpRangeTest, SWT.NONE );
 
-	private void loadPreferences(boolean useDefaults) {
-		IPreferenceStore prefs = getPreferenceStore();
-		String lowerBoundStr;
-		if(useDefaults) {
-			lowerBoundStr = prefs.getDefaultString(SigilCore.DEFAULT_VERSION_LOWER_BOUND);
-		} else {
-			lowerBoundStr = prefs.getString(SigilCore.DEFAULT_VERSION_LOWER_BOUND);
-		}
-		
-		String upperBoundStr;
-		if(useDefaults) {
-			upperBoundStr = prefs.getDefaultString(SigilCore.DEFAULT_VERSION_UPPER_BOUND);
-		} else {
-			upperBoundStr = prefs.getString(SigilCore.DEFAULT_VERSION_UPPER_BOUND);
-		}
-		
-		lowerBoundRule = VersionRangeBoundingRule.valueOf(lowerBoundStr);
-		upperBoundRule = VersionRangeBoundingRule.valueOf(upperBoundStr);
-	}
+        // Initialize controls
+        loadPreferences( false );
+        updateRadioButtons();
 
-	private void updateRadioButtons() {
-		switch (lowerBoundRule) {
-		case Exact:
-			btnLowerBoundExact.setSelection(true);
-			btnLowerBoundMicro.setSelection(false);
-			btnLowerBoundMinor.setSelection(false);
-			btnLowerBoundMajor.setSelection(false);
-			btnLowerBoundAny.setSelection(false);
-			break;
-		case Micro:
-			btnLowerBoundExact.setSelection(false);
-			btnLowerBoundMicro.setSelection(true);
-			btnLowerBoundMinor.setSelection(false);
-			btnLowerBoundMajor.setSelection(false);
-			btnLowerBoundAny.setSelection(false);
-			break;
-		case Minor:
-			btnLowerBoundExact.setSelection(false);
-			btnLowerBoundMicro.setSelection(false);
-			btnLowerBoundMinor.setSelection(true);
-			btnLowerBoundMajor.setSelection(false);
-			btnLowerBoundAny.setSelection(false);
-			break;
-		case Major:
-			btnLowerBoundExact.setSelection(false);
-			btnLowerBoundMicro.setSelection(false);
-			btnLowerBoundMinor.setSelection(false);
-			btnLowerBoundMajor.setSelection(true);
-			btnLowerBoundAny.setSelection(false);
-			break;
-		case Any:
-			btnLowerBoundExact.setSelection(false);
-			btnLowerBoundMicro.setSelection(false);
-			btnLowerBoundMinor.setSelection(false);
-			btnLowerBoundMajor.setSelection(false);
-			btnLowerBoundAny.setSelection(true);
-			break;
-		}
+        txtSampleVersion.setText( sampleVersion.toString() );
+        updateCalculatedRange();
 
-		switch (upperBoundRule) {
-		case Exact:
-			btnUpperBoundExact.setSelection(true);
-			btnUpperBoundMicro.setSelection(false);
-			btnUpperBoundMinor.setSelection(false);
-			btnUpperBoundMajor.setSelection(false);
-			btnUpperBoundAny.setSelection(false);
-			break;
-		case Micro:
-			btnUpperBoundExact.setSelection(false);
-			btnUpperBoundMicro.setSelection(true);
-			btnUpperBoundMinor.setSelection(false);
-			btnUpperBoundMajor.setSelection(false);
-			btnUpperBoundAny.setSelection(false);
-			break;
-		case Minor:
-			btnUpperBoundExact.setSelection(false);
-			btnUpperBoundMicro.setSelection(false);
-			btnUpperBoundMinor.setSelection(true);
-			btnUpperBoundMajor.setSelection(false);
-			btnUpperBoundAny.setSelection(false);
-			break;
-		case Major:
-			btnUpperBoundExact.setSelection(false);
-			btnUpperBoundMicro.setSelection(false);
-			btnUpperBoundMinor.setSelection(false);
-			btnUpperBoundMajor.setSelection(true);
-			btnUpperBoundAny.setSelection(false);
-			break;
-		case Any:
-			btnUpperBoundExact.setSelection(false);
-			btnUpperBoundMicro.setSelection(false);
-			btnUpperBoundMinor.setSelection(false);
-			btnUpperBoundMajor.setSelection(false);
-			btnUpperBoundAny.setSelection(true);
-		}
-	}
+        // Add listeners
+        SelectionListener buttonListener = new SelectionListener()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                readRadioButtons();
+                updateCalculatedRange();
+            }
 
-	private void readRadioButtons() {
-		if (btnLowerBoundExact.getSelection()) {
-			lowerBoundRule = VersionRangeBoundingRule.Exact;
-		} else if (btnLowerBoundMicro.getSelection()) {
-			lowerBoundRule = VersionRangeBoundingRule.Micro;
-		} else if (btnLowerBoundMinor.getSelection()) {
-			lowerBoundRule = VersionRangeBoundingRule.Minor;
-		} else if (btnLowerBoundMajor.getSelection()) {
-			lowerBoundRule = VersionRangeBoundingRule.Major;
-		} else if(btnLowerBoundAny.getSelection()) {
-			lowerBoundRule = VersionRangeBoundingRule.Any;
-		}
 
-		if (btnUpperBoundExact.getSelection()) {
-			upperBoundRule = VersionRangeBoundingRule.Exact;
-		} else if (btnUpperBoundMicro.getSelection()) {
-			upperBoundRule = VersionRangeBoundingRule.Micro;
-		} else if (btnUpperBoundMinor.getSelection()) {
-			upperBoundRule = VersionRangeBoundingRule.Minor;
-		} else if (btnUpperBoundMajor.getSelection()) {
-			upperBoundRule = VersionRangeBoundingRule.Major;
-		} else if(btnUpperBoundAny.getSelection()) {
-			upperBoundRule = VersionRangeBoundingRule.Any;
-		}
-	}
+            public void widgetDefaultSelected( SelectionEvent e )
+            {
+                readRadioButtons();
+                updateCalculatedRange();
+            }
+        };
+        btnLowerBoundAny.addSelectionListener( buttonListener );
+        btnLowerBoundMajor.addSelectionListener( buttonListener );
+        btnLowerBoundMinor.addSelectionListener( buttonListener );
+        btnLowerBoundMicro.addSelectionListener( buttonListener );
+        btnLowerBoundExact.addSelectionListener( buttonListener );
 
-	private void updateCalculatedRange() {
-		VersionRange range;
-		String rangeStr;
-		String matchResult;
-		
-		if(sampleVersion == null) {
-			range = null;
-			rangeStr = "";
-		} else {
-			range = VersionRange.newInstance(sampleVersion, lowerBoundRule, upperBoundRule);
-			rangeStr = range.toString();
-		}
-		lblCalculatedRange.setText(rangeStr);
-		
-		if(matchVersion == null || range == null) {
-			matchResult = "";
-		} else {
-			matchResult = range.contains(matchVersion) ? "MATCH!" : "No Match";
-		}
-		lblMatchResult.setText(matchResult);
-	}
+        btnUpperBoundAny.addSelectionListener( buttonListener );
+        btnUpperBoundMajor.addSelectionListener( buttonListener );
+        btnUpperBoundMinor.addSelectionListener( buttonListener );
+        btnUpperBoundMicro.addSelectionListener( buttonListener );
+        btnUpperBoundExact.addSelectionListener( buttonListener );
 
-	public void init(IWorkbench workbench) {
-		this.workbench = workbench;
-	}
+        txtSampleVersion.addModifyListener( new ModifyListener()
+        {
+            public void modifyText( ModifyEvent e )
+            {
+                try
+                {
+                    sampleVersion = new Version( txtSampleVersion.getText() );
+                }
+                catch ( IllegalArgumentException x )
+                {
+                    sampleVersion = null;
+                }
+                updateCalculatedRange();
+            }
+        } );
+        txtMatchVersion.addModifyListener( new ModifyListener()
+        {
+            public void modifyText( ModifyEvent e )
+            {
+                try
+                {
+                    matchVersion = new Version( txtMatchVersion.getText() );
+                }
+                catch ( IllegalArgumentException x )
+                {
+                    matchVersion = null;
+                }
+                updateCalculatedRange();
+            }
+        } );
 
-	@Override
-	protected IPreferenceStore doGetPreferenceStore() {
-		return SigilCore.getDefault().getPreferenceStore();
-	}
+        // Layout
+        GridLayout layout = new GridLayout( 1, false );
+        layout.verticalSpacing = 20;
+        composite.setLayout( layout );
 
-	@Override
-	public boolean performOk() {
-		getPreferenceStore().setValue(SigilCore.DEFAULT_VERSION_LOWER_BOUND, lowerBoundRule.name());
-		getPreferenceStore().setValue(SigilCore.DEFAULT_VERSION_UPPER_BOUND, upperBoundRule.name());
+        grpLowerBound.setLayoutData( new GridData( SWT.FILL, SWT.TOP, true, false ) );
+        grpLowerBound.setLayout( new GridLayout( 1, false ) );
 
-		return true;
-	}
-	
-	@Override
-	protected void performDefaults() {
-		super.performDefaults();
-		loadPreferences(true);
-		updateRadioButtons();
-		updateCalculatedRange();
-	}
+        grpUpperBound.setLayoutData( new GridData( SWT.FILL, SWT.TOP, true, false ) );
+        grpUpperBound.setLayout( new GridLayout( 1, false ) );
+
+        grpRangeTest.setLayoutData( new GridData( SWT.FILL, SWT.TOP, true, true ) );
+        grpRangeTest.setLayout( new GridLayout( 2, false ) );
+
+        txtSampleVersion.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        lblCalculatedRange.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        txtMatchVersion.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        lblMatchResult.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+
+        return composite;
+    }
+
+
+    private void loadPreferences( boolean useDefaults )
+    {
+        IPreferenceStore prefs = getPreferenceStore();
+        String lowerBoundStr;
+        if ( useDefaults )
+        {
+            lowerBoundStr = prefs.getDefaultString( SigilCore.DEFAULT_VERSION_LOWER_BOUND );
+        }
+        else
+        {
+            lowerBoundStr = prefs.getString( SigilCore.DEFAULT_VERSION_LOWER_BOUND );
+        }
+
+        String upperBoundStr;
+        if ( useDefaults )
+        {
+            upperBoundStr = prefs.getDefaultString( SigilCore.DEFAULT_VERSION_UPPER_BOUND );
+        }
+        else
+        {
+            upperBoundStr = prefs.getString( SigilCore.DEFAULT_VERSION_UPPER_BOUND );
+        }
+
+        lowerBoundRule = VersionRangeBoundingRule.valueOf( lowerBoundStr );
+        upperBoundRule = VersionRangeBoundingRule.valueOf( upperBoundStr );
+    }
+
+
+    private void updateRadioButtons()
+    {
+        switch ( lowerBoundRule )
+        {
+            case Exact:
+                btnLowerBoundExact.setSelection( true );
+                btnLowerBoundMicro.setSelection( false );
+                btnLowerBoundMinor.setSelection( false );
+                btnLowerBoundMajor.setSelection( false );
+                btnLowerBoundAny.setSelection( false );
+                break;
+            case Micro:
+                btnLowerBoundExact.setSelection( false );
+                btnLowerBoundMicro.setSelection( true );
+                btnLowerBoundMinor.setSelection( false );
+                btnLowerBoundMajor.setSelection( false );
+                btnLowerBoundAny.setSelection( false );
+                break;
+            case Minor:
+                btnLowerBoundExact.setSelection( false );
+                btnLowerBoundMicro.setSelection( false );
+                btnLowerBoundMinor.setSelection( true );
+                btnLowerBoundMajor.setSelection( false );
+                btnLowerBoundAny.setSelection( false );
+                break;
+            case Major:
+                btnLowerBoundExact.setSelection( false );
+                btnLowerBoundMicro.setSelection( false );
+                btnLowerBoundMinor.setSelection( false );
+                btnLowerBoundMajor.setSelection( true );
+                btnLowerBoundAny.setSelection( false );
+                break;
+            case Any:
+                btnLowerBoundExact.setSelection( false );
+                btnLowerBoundMicro.setSelection( false );
+                btnLowerBoundMinor.setSelection( false );
+                btnLowerBoundMajor.setSelection( false );
+                btnLowerBoundAny.setSelection( true );
+                break;
+        }
+
+        switch ( upperBoundRule )
+        {
+            case Exact:
+                btnUpperBoundExact.setSelection( true );
+                btnUpperBoundMicro.setSelection( false );
+                btnUpperBoundMinor.setSelection( false );
+                btnUpperBoundMajor.setSelection( false );
+                btnUpperBoundAny.setSelection( false );
+                break;
+            case Micro:
+                btnUpperBoundExact.setSelection( false );
+                btnUpperBoundMicro.setSelection( true );
+                btnUpperBoundMinor.setSelection( false );
+                btnUpperBoundMajor.setSelection( false );
+                btnUpperBoundAny.setSelection( false );
+                break;
+            case Minor:
+                btnUpperBoundExact.setSelection( false );
+                btnUpperBoundMicro.setSelection( false );
+                btnUpperBoundMinor.setSelection( true );
+                btnUpperBoundMajor.setSelection( false );
+                btnUpperBoundAny.setSelection( false );
+                break;
+            case Major:
+                btnUpperBoundExact.setSelection( false );
+                btnUpperBoundMicro.setSelection( false );
+                btnUpperBoundMinor.setSelection( false );
+                btnUpperBoundMajor.setSelection( true );
+                btnUpperBoundAny.setSelection( false );
+                break;
+            case Any:
+                btnUpperBoundExact.setSelection( false );
+                btnUpperBoundMicro.setSelection( false );
+                btnUpperBoundMinor.setSelection( false );
+                btnUpperBoundMajor.setSelection( false );
+                btnUpperBoundAny.setSelection( true );
+        }
+    }
+
+
+    private void readRadioButtons()
+    {
+        if ( btnLowerBoundExact.getSelection() )
+        {
+            lowerBoundRule = VersionRangeBoundingRule.Exact;
+        }
+        else if ( btnLowerBoundMicro.getSelection() )
+        {
+            lowerBoundRule = VersionRangeBoundingRule.Micro;
+        }
+        else if ( btnLowerBoundMinor.getSelection() )
+        {
+            lowerBoundRule = VersionRangeBoundingRule.Minor;
+        }
+        else if ( btnLowerBoundMajor.getSelection() )
+        {
+            lowerBoundRule = VersionRangeBoundingRule.Major;
+        }
+        else if ( btnLowerBoundAny.getSelection() )
+        {
+            lowerBoundRule = VersionRangeBoundingRule.Any;
+        }
+
+        if ( btnUpperBoundExact.getSelection() )
+        {
+            upperBoundRule = VersionRangeBoundingRule.Exact;
+        }
+        else if ( btnUpperBoundMicro.getSelection() )
+        {
+            upperBoundRule = VersionRangeBoundingRule.Micro;
+        }
+        else if ( btnUpperBoundMinor.getSelection() )
+        {
+            upperBoundRule = VersionRangeBoundingRule.Minor;
+        }
+        else if ( btnUpperBoundMajor.getSelection() )
+        {
+            upperBoundRule = VersionRangeBoundingRule.Major;
+        }
+        else if ( btnUpperBoundAny.getSelection() )
+        {
+            upperBoundRule = VersionRangeBoundingRule.Any;
+        }
+    }
+
+
+    private void updateCalculatedRange()
+    {
+        VersionRange range;
+        String rangeStr;
+        String matchResult;
+
+        if ( sampleVersion == null )
+        {
+            range = null;
+            rangeStr = "";
+        }
+        else
+        {
+            range = VersionRange.newInstance( sampleVersion, lowerBoundRule, upperBoundRule );
+            rangeStr = range.toString();
+        }
+        lblCalculatedRange.setText( rangeStr );
+
+        if ( matchVersion == null || range == null )
+        {
+            matchResult = "";
+        }
+        else
+        {
+            matchResult = range.contains( matchVersion ) ? "MATCH!" : "No Match";
+        }
+        lblMatchResult.setText( matchResult );
+    }
+
+
+    public void init( IWorkbench workbench )
+    {
+        this.workbench = workbench;
+    }
+
+
+    @Override
+    protected IPreferenceStore doGetPreferenceStore()
+    {
+        return SigilCore.getDefault().getPreferenceStore();
+    }
+
+
+    @Override
+    public boolean performOk()
+    {
+        getPreferenceStore().setValue( SigilCore.DEFAULT_VERSION_LOWER_BOUND, lowerBoundRule.name() );
+        getPreferenceStore().setValue( SigilCore.DEFAULT_VERSION_UPPER_BOUND, upperBoundRule.name() );
+
+        return true;
+    }
+
+
+    @Override
+    protected void performDefaults()
+    {
+        super.performDefaults();
+        loadPreferences( true );
+        updateRadioButtons();
+        updateCalculatedRange();
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/installs/OSGiInstallsPreferencePage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/installs/OSGiInstallsPreferencePage.java
index 74dde4c..7221489 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/installs/OSGiInstallsPreferencePage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/installs/OSGiInstallsPreferencePage.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences.installs;
 
+
 import java.util.HashMap;
 import java.util.UUID;
 
@@ -52,250 +53,322 @@
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferencePage;
 
-public class OSGiInstallsPreferencePage extends ProjectDependentPreferencesPage implements
-		IWorkbenchPreferencePage {
 
-	private class Install {
-		private String id;
-		private String location;
-		private IOSGiInstallType type;
-		
-		private Install(String id, String location) {
-			this.id = id;
-			this.location = location;
-		}
+public class OSGiInstallsPreferencePage extends ProjectDependentPreferencesPage implements IWorkbenchPreferencePage
+{
 
-		private IOSGiInstallType getType() {
-			if ( type == null ) {
-				type = SigilCore.getInstallManager().findInstallType(location);
-			}
-			return type;
-		}
-	}
-
-	private HashMap<String, Install> installs = new HashMap<String, Install>();
-	private CheckboxTableViewer viewer;
-	private boolean changed;
-	
-	public OSGiInstallsPreferencePage() {
-		super("OSGi Installs");
-	}
-	
-	public void init(IWorkbench workbench) {
-	}
+    private class Install
+    {
+        private String id;
+        private String location;
+        private IOSGiInstallType type;
 
 
-	@Override
-	protected Control createContents(Composite parent) {
-		Composite control = new Composite(parent, SWT.NONE);
-		
-		buildComponents(control);
-		
-		load();
-		
-		checkValid();
-		
-		return control;
-	}
+        private Install( String id, String location )
+        {
+            this.id = id;
+            this.location = location;
+        }
 
-	@Override
-	protected boolean isDirty() {
-		return changed;
-	}
 
-	
-	private void buildComponents(Composite control) {
-		new Label(control, SWT.NONE).setText("Installs:");
-		new Label(control, SWT.NONE); // padding
-		
-		Table table = new Table(control, SWT.CHECK | SWT.SINGLE | SWT.BORDER);
-		
-		Button add = new Button(control, SWT.PUSH);
-		add.setText("Add");
-		add.addSelectionListener( new SelectionAdapter() {
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				add();
-			}			
-		});
-		
-		final Button remove = new Button(control, SWT.PUSH);
-		remove.setEnabled(false);
-		remove.setText("Remove");
-		remove.addSelectionListener( new SelectionAdapter() {
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				remove();
-			}			
-		});
-		
-		// viewers
-		viewer = new CheckboxTableViewer(table);
-		viewer.setContentProvider( new DefaultTableProvider() {
-			public Object[] getElements(Object inputElement) {
-				return toArray(inputElement);
-			}			
-		});
-				
-		viewer.setLabelProvider( new LabelProvider() {
-			@Override
-			public String getText(Object element) {
-				Install i = (Install) element;
-				IOSGiInstallType type = i.getType();
-				if ( type == null ) {
-					return "<invalid> [" + i.location + "]";
-				}
-				else {
-					return type.getName() + " " + type.getVersion() + " [" + i.location + "]";
-				}
-			}
+        private IOSGiInstallType getType()
+        {
+            if ( type == null )
+            {
+                type = SigilCore.getInstallManager().findInstallType( location );
+            }
+            return type;
+        }
+    }
 
-			@Override
-			public Image getImage(Object element) {
-				Install i = (Install) element;
-				IOSGiInstallType type = i.getType();
-				
-				if (type == null) {
-					return null;
-				} else {
-				return type.getIcon();
-				}
-			}			
-		});
-		
-		viewer.addSelectionChangedListener( new ISelectionChangedListener() {
-			public void selectionChanged(SelectionChangedEvent event) {
-				boolean enabled = !event.getSelection().isEmpty();
-				remove.setEnabled(enabled );
-			}
-		});
-		
-		viewer.addCheckStateListener( new ICheckStateListener () {
-			public void checkStateChanged(CheckStateChangedEvent event) {
-				if ( event.getChecked() ) {
-					changed = true;
-				}
-				viewer.setCheckedElements( new Object[] { event.getElement() } );
-			}
-		});
-		
-		viewer.setInput(installs.values());
-		
-		// layout
-		control.setLayout( new GridLayout(2, false) );
-		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 3));
-		add.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-		remove.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));		
-	}
+    private HashMap<String, Install> installs = new HashMap<String, Install>();
+    private CheckboxTableViewer viewer;
+    private boolean changed;
 
-	private void load() {
-		String pref = getPreferenceStore().getString(SigilCore.OSGI_INSTALLS);
-		if ( pref != null && pref.length() > 0 ) {
-			for ( String id : pref.split(",") ) {
-				String loc = getPreferenceStore().getString( SigilCore.OSGI_INSTALL_PREFIX + id );
-				installs.put( id, new Install( id, loc ) );
-			}
-		}
-		
-		viewer.refresh();
-		
-		if ( !installs.isEmpty() ) {
-			String defId = getPreferenceStore().getString( SigilCore.OSGI_DEFAULT_INSTALL_ID );
-			if ( defId == null || defId.trim().length() == 0 ) {
-				viewer.setCheckedElements( new Object[] { installs.values().iterator().next() } );
-			}
-			else {
-				viewer.setCheckedElements( new Object[] { installs.get( defId ) } );
-			}
-		}
-	}
-	
-	protected void doSave() {
-		// zero out old configs
-		String pref = getPreferenceStore().getString(SigilCore.OSGI_INSTALLS);
-		if ( pref != null && pref.length() > 0 ) {
-			for ( String id : pref.split(",") ) {
-				getPreferenceStore().setToDefault( SigilCore.OSGI_INSTALL_PREFIX + id );
-			}
-		}
-		
-		// store new configs
-		if ( installs.isEmpty() ) {
-			getPreferenceStore().setToDefault(SigilCore.OSGI_INSTALLS);
-			getPreferenceStore().setToDefault(SigilCore.OSGI_DEFAULT_INSTALL_ID);
-		}
-		else {
-			StringBuffer buf = new StringBuffer();
-			for (Install i : installs.values() ) {
-				if ( buf.length() > 0 ) {
-					buf.append(",");
-				}
-				buf.append( i.id );
-				getPreferenceStore().setValue( SigilCore.OSGI_INSTALL_PREFIX + i.id, i.location );
-			}
-			
-			getPreferenceStore().setValue( SigilCore.OSGI_INSTALLS, buf.toString() );
-			Install def = (Install) viewer.getCheckedElements()[0];
-			getPreferenceStore().setValue(SigilCore.OSGI_DEFAULT_INSTALL_ID, def.id);
-		}
-		changed = false;
-	}
 
-	private boolean isOK() {
-		return installs.isEmpty() || viewer.getCheckedElements().length > 0;
-	}
-	
-	private void add() {
-		Shell shell = SigilUI.getActiveWorkbenchShell();
-		DirectoryDialog dialog = new DirectoryDialog(shell);
-		String dir = dialog.open();
-		if ( dir != null ) {
-			Install install = new Install( UUID.randomUUID().toString(), dir );
-			if ( install.getType() == null ) {
-				MessageDialog.openError(shell, "Error", "Invalid OSGi install directory" );
-			}
-			else {
-				boolean empty = installs.isEmpty();
-				
-				installs.put( install.id, install );
-				viewer.refresh();
-				
-				if ( empty ) {
-					viewer.setCheckedElements( new Object[] { install } );
-				}
-				
-				checkValid();
-				changed = true;
-			}
-		}
-	}
+    public OSGiInstallsPreferencePage()
+    {
+        super( "OSGi Installs" );
+    }
 
-	private void checkValid() {
-		if ( isOK() ) {
-			setErrorMessage(null);
-			setValid(true);
-		}
-		else {
-			setErrorMessage("Missing default OSGi install");
-			setValid(false);
-		}
-	}
 
-	private void remove() {
-		IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();
-		Install i = (Install) sel.getFirstElement();
-		boolean def = viewer.getChecked(i);
-		installs.remove(i.id);
-		viewer.refresh();
-		if ( def && installs.size() > 0 ) {
-			viewer.setCheckedElements( new Object[] { installs.values().iterator().next() } );
-		}
-		checkValid();
-		changed = true;
-	}
+    public void init( IWorkbench workbench )
+    {
+    }
 
-	@Override
-	protected IPreferenceStore doGetPreferenceStore() {
-		return SigilCore.getDefault().getPreferenceStore();
-	}
+
+    @Override
+    protected Control createContents( Composite parent )
+    {
+        Composite control = new Composite( parent, SWT.NONE );
+
+        buildComponents( control );
+
+        load();
+
+        checkValid();
+
+        return control;
+    }
+
+
+    @Override
+    protected boolean isDirty()
+    {
+        return changed;
+    }
+
+
+    private void buildComponents( Composite control )
+    {
+        new Label( control, SWT.NONE ).setText( "Installs:" );
+        new Label( control, SWT.NONE ); // padding
+
+        Table table = new Table( control, SWT.CHECK | SWT.SINGLE | SWT.BORDER );
+
+        Button add = new Button( control, SWT.PUSH );
+        add.setText( "Add" );
+        add.addSelectionListener( new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected( SelectionEvent e )
+            {
+                add();
+            }
+        } );
+
+        final Button remove = new Button( control, SWT.PUSH );
+        remove.setEnabled( false );
+        remove.setText( "Remove" );
+        remove.addSelectionListener( new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected( SelectionEvent e )
+            {
+                remove();
+            }
+        } );
+
+        // viewers
+        viewer = new CheckboxTableViewer( table );
+        viewer.setContentProvider( new DefaultTableProvider()
+        {
+            public Object[] getElements( Object inputElement )
+            {
+                return toArray( inputElement );
+            }
+        } );
+
+        viewer.setLabelProvider( new LabelProvider()
+        {
+            @Override
+            public String getText( Object element )
+            {
+                Install i = ( Install ) element;
+                IOSGiInstallType type = i.getType();
+                if ( type == null )
+                {
+                    return "<invalid> [" + i.location + "]";
+                }
+                else
+                {
+                    return type.getName() + " " + type.getVersion() + " [" + i.location + "]";
+                }
+            }
+
+
+            @Override
+            public Image getImage( Object element )
+            {
+                Install i = ( Install ) element;
+                IOSGiInstallType type = i.getType();
+
+                if ( type == null )
+                {
+                    return null;
+                }
+                else
+                {
+                    return type.getIcon();
+                }
+            }
+        } );
+
+        viewer.addSelectionChangedListener( new ISelectionChangedListener()
+        {
+            public void selectionChanged( SelectionChangedEvent event )
+            {
+                boolean enabled = !event.getSelection().isEmpty();
+                remove.setEnabled( enabled );
+            }
+        } );
+
+        viewer.addCheckStateListener( new ICheckStateListener()
+        {
+            public void checkStateChanged( CheckStateChangedEvent event )
+            {
+                if ( event.getChecked() )
+                {
+                    changed = true;
+                }
+                viewer.setCheckedElements( new Object[]
+                    { event.getElement() } );
+            }
+        } );
+
+        viewer.setInput( installs.values() );
+
+        // layout
+        control.setLayout( new GridLayout( 2, false ) );
+        table.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true, 1, 3 ) );
+        add.setLayoutData( new GridData( SWT.FILL, SWT.FILL, false, false ) );
+        remove.setLayoutData( new GridData( SWT.FILL, SWT.FILL, false, false ) );
+    }
+
+
+    private void load()
+    {
+        String pref = getPreferenceStore().getString( SigilCore.OSGI_INSTALLS );
+        if ( pref != null && pref.length() > 0 )
+        {
+            for ( String id : pref.split( "," ) )
+            {
+                String loc = getPreferenceStore().getString( SigilCore.OSGI_INSTALL_PREFIX + id );
+                installs.put( id, new Install( id, loc ) );
+            }
+        }
+
+        viewer.refresh();
+
+        if ( !installs.isEmpty() )
+        {
+            String defId = getPreferenceStore().getString( SigilCore.OSGI_DEFAULT_INSTALL_ID );
+            if ( defId == null || defId.trim().length() == 0 )
+            {
+                viewer.setCheckedElements( new Object[]
+                    { installs.values().iterator().next() } );
+            }
+            else
+            {
+                viewer.setCheckedElements( new Object[]
+                    { installs.get( defId ) } );
+            }
+        }
+    }
+
+
+    protected void doSave()
+    {
+        // zero out old configs
+        String pref = getPreferenceStore().getString( SigilCore.OSGI_INSTALLS );
+        if ( pref != null && pref.length() > 0 )
+        {
+            for ( String id : pref.split( "," ) )
+            {
+                getPreferenceStore().setToDefault( SigilCore.OSGI_INSTALL_PREFIX + id );
+            }
+        }
+
+        // store new configs
+        if ( installs.isEmpty() )
+        {
+            getPreferenceStore().setToDefault( SigilCore.OSGI_INSTALLS );
+            getPreferenceStore().setToDefault( SigilCore.OSGI_DEFAULT_INSTALL_ID );
+        }
+        else
+        {
+            StringBuffer buf = new StringBuffer();
+            for ( Install i : installs.values() )
+            {
+                if ( buf.length() > 0 )
+                {
+                    buf.append( "," );
+                }
+                buf.append( i.id );
+                getPreferenceStore().setValue( SigilCore.OSGI_INSTALL_PREFIX + i.id, i.location );
+            }
+
+            getPreferenceStore().setValue( SigilCore.OSGI_INSTALLS, buf.toString() );
+            Install def = ( Install ) viewer.getCheckedElements()[0];
+            getPreferenceStore().setValue( SigilCore.OSGI_DEFAULT_INSTALL_ID, def.id );
+        }
+        changed = false;
+    }
+
+
+    private boolean isOK()
+    {
+        return installs.isEmpty() || viewer.getCheckedElements().length > 0;
+    }
+
+
+    private void add()
+    {
+        Shell shell = SigilUI.getActiveWorkbenchShell();
+        DirectoryDialog dialog = new DirectoryDialog( shell );
+        String dir = dialog.open();
+        if ( dir != null )
+        {
+            Install install = new Install( UUID.randomUUID().toString(), dir );
+            if ( install.getType() == null )
+            {
+                MessageDialog.openError( shell, "Error", "Invalid OSGi install directory" );
+            }
+            else
+            {
+                boolean empty = installs.isEmpty();
+
+                installs.put( install.id, install );
+                viewer.refresh();
+
+                if ( empty )
+                {
+                    viewer.setCheckedElements( new Object[]
+                        { install } );
+                }
+
+                checkValid();
+                changed = true;
+            }
+        }
+    }
+
+
+    private void checkValid()
+    {
+        if ( isOK() )
+        {
+            setErrorMessage( null );
+            setValid( true );
+        }
+        else
+        {
+            setErrorMessage( "Missing default OSGi install" );
+            setValid( false );
+        }
+    }
+
+
+    private void remove()
+    {
+        IStructuredSelection sel = ( IStructuredSelection ) viewer.getSelection();
+        Install i = ( Install ) sel.getFirstElement();
+        boolean def = viewer.getChecked( i );
+        installs.remove( i.id );
+        viewer.refresh();
+        if ( def && installs.size() > 0 )
+        {
+            viewer.setCheckedElements( new Object[]
+                { installs.values().iterator().next() } );
+        }
+        checkValid();
+        changed = true;
+    }
+
+
+    @Override
+    protected IPreferenceStore doGetPreferenceStore()
+    {
+        return SigilCore.getDefault().getPreferenceStore();
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/project/ProjectPropertyPage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/project/ProjectPropertyPage.java
index ececc87..8babe61 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/project/ProjectPropertyPage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/project/ProjectPropertyPage.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences.project;
 
+
 import java.util.concurrent.Callable;
 
 import org.apache.felix.sigil.eclipse.SigilCore;
@@ -48,143 +49,179 @@
 import org.eclipse.ui.dialogs.PropertyPage;
 import org.osgi.service.prefs.BackingStoreException;
 
-public class ProjectPropertyPage extends PropertyPage implements
-		IWorkbenchPropertyPage {
 
-	private boolean projectSpecific;
-	private ComboViewer setView;
-	private Composite settings;
-	private Button projectSpecificBtn;
+public class ProjectPropertyPage extends PropertyPage implements IWorkbenchPropertyPage
+{
 
-	@Override
-	protected Control createContents(Composite parent) {
-		final Composite control = new Composite(parent, SWT.NONE);
-		
-		projectSpecificBtn = new Button(control, SWT.CHECK);
-		projectSpecificBtn.setText( "Enable project specific settings");
-		projectSpecificBtn.addSelectionListener( new SelectionAdapter() {
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				setProjectSpecific(!projectSpecific);
-			}
-		});
-		
-		Label link = new Label( control, SWT.UNDERLINE_SINGLE );
-		link.addMouseListener( new MouseAdapter() {
-			@Override
-			public void mouseDown(MouseEvent e) {
-				PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn(null, SigilCore.REPOSITORIES_PREFERENCES_ID, null, null);
-				dialog.open();
-			}			
-		});
-		
-		link.setText("Configure workspace settings" );
-		
-		settings = new Composite( control, SWT.BORDER );
-		settings.setLayout( new GridLayout(1,false));
-		createSettings( settings );
-		
-		setFonts(control);
-		
-		// layout
-		control.setLayout( new GridLayout(2, false));
-		projectSpecificBtn.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, false ) );
-		settings.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1 ) );
+    private boolean projectSpecific;
+    private ComboViewer setView;
+    private Composite settings;
+    private Button projectSpecificBtn;
 
-		// load settings
-		String currentSet = getCurrentSet();
-		
-		if ( currentSet == null ) {
-			setProjectSpecific(false);
-		}
-		else {
-			setView.setSelection( new StructuredSelection(currentSet) );
-			setProjectSpecific(true);
-		}
-		
-		return control;
-	}
 
-	private void setFonts(Composite control) {
-		Composite p = control.getParent();
-		for ( Control c : control.getChildren() ) {
-			c.setFont( p.getFont() );
-			if ( c instanceof Composite ) {
-				setFonts( (Composite) c );
-			}
-		}
-	}
+    @Override
+    protected Control createContents( Composite parent )
+    {
+        final Composite control = new Composite( parent, SWT.NONE );
 
-	private void setProjectSpecific(boolean projectSpecific) {
-		if ( this.projectSpecific != projectSpecific ) {
-			this.projectSpecific = projectSpecific;
-			settings.setEnabled(projectSpecific);
-			for ( Control c : settings.getChildren() ) {
-				c.setEnabled( projectSpecific );
-			}
-			projectSpecificBtn.setSelection(projectSpecific);
-		}
-	}
+        projectSpecificBtn = new Button( control, SWT.CHECK );
+        projectSpecificBtn.setText( "Enable project specific settings" );
+        projectSpecificBtn.addSelectionListener( new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected( SelectionEvent e )
+            {
+                setProjectSpecific( !projectSpecific );
+            }
+        } );
 
-	private void createSettings(Composite parent) {
-		Composite control = new Composite(parent, SWT.NONE);
-		
-		new Label( control, SWT.NONE).setText( "Repository Set:" );
-		Combo combo = new Combo(control, SWT.SINGLE);
-		
-		setView = new ComboViewer(combo);
-		setView.setContentProvider( new DefaultTableProvider() {
-			public Object[] getElements(Object inputElement) {
-				return toArray(inputElement);
-			}
-		});
-		
-		setView.setInput( SigilCore.getRepositoryConfiguration().loadRepositorySets().keySet() );
-		
-		// layout
-		control.setLayout( new GridLayout(2, false ) );
-	}
+        Label link = new Label( control, SWT.UNDERLINE_SINGLE );
+        link.addMouseListener( new MouseAdapter()
+        {
+            @Override
+            public void mouseDown( MouseEvent e )
+            {
+                PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn( null,
+                    SigilCore.REPOSITORIES_PREFERENCES_ID, null, null );
+                dialog.open();
+            }
+        } );
 
-	private String getCurrentSet() {
-		try {
-			IProject p = (IProject) getElement().getAdapter(IProject.class);
-			ISigilProjectModel model = SigilCore.create(p);
-			return model.getPreferences().get( SigilCore.REPOSITORY_SET, null );
-		} catch (CoreException e) {
-			SigilCore.error("Failed to read repository set", e );
-			return null;
-		}
-	}
+        link.setText( "Configure workspace settings" );
 
-	@Override
-	public boolean okToLeave() {
-		if ( projectSpecific ) {
-			if ( setView.getSelection().isEmpty() ) {
-				setErrorMessage("Must select a repository set");
-				return false;
-			}
-		}
-		setErrorMessage(null);
-		return true;
-	}
+        settings = new Composite( control, SWT.BORDER );
+        settings.setLayout( new GridLayout( 1, false ) );
+        createSettings( settings );
 
-	@Override
-	public boolean performOk() {
-		return ProjectUtils.runTaskWithRebuildCheck( new Callable<Boolean>() {
-			public Boolean call() throws CoreException, BackingStoreException {
-				String set = null;
-				if ( projectSpecific ) {
-					set = (String) ((IStructuredSelection) setView.getSelection()).getFirstElement();
-				}
+        setFonts( control );
 
-				IProject p = (IProject) getElement().getAdapter(IProject.class);
-				ISigilProjectModel model = SigilCore.create(p);
-				model.getPreferences().put( SigilCore.REPOSITORY_SET, set );
-				model.getPreferences().flush();
-				return true;
-			}
+        // layout
+        control.setLayout( new GridLayout( 2, false ) );
+        projectSpecificBtn.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        settings.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true, 2, 1 ) );
 
-		}, getShell());
-	}
+        // load settings
+        String currentSet = getCurrentSet();
+
+        if ( currentSet == null )
+        {
+            setProjectSpecific( false );
+        }
+        else
+        {
+            setView.setSelection( new StructuredSelection( currentSet ) );
+            setProjectSpecific( true );
+        }
+
+        return control;
+    }
+
+
+    private void setFonts( Composite control )
+    {
+        Composite p = control.getParent();
+        for ( Control c : control.getChildren() )
+        {
+            c.setFont( p.getFont() );
+            if ( c instanceof Composite )
+            {
+                setFonts( ( Composite ) c );
+            }
+        }
+    }
+
+
+    private void setProjectSpecific( boolean projectSpecific )
+    {
+        if ( this.projectSpecific != projectSpecific )
+        {
+            this.projectSpecific = projectSpecific;
+            settings.setEnabled( projectSpecific );
+            for ( Control c : settings.getChildren() )
+            {
+                c.setEnabled( projectSpecific );
+            }
+            projectSpecificBtn.setSelection( projectSpecific );
+        }
+    }
+
+
+    private void createSettings( Composite parent )
+    {
+        Composite control = new Composite( parent, SWT.NONE );
+
+        new Label( control, SWT.NONE ).setText( "Repository Set:" );
+        Combo combo = new Combo( control, SWT.SINGLE );
+
+        setView = new ComboViewer( combo );
+        setView.setContentProvider( new DefaultTableProvider()
+        {
+            public Object[] getElements( Object inputElement )
+            {
+                return toArray( inputElement );
+            }
+        } );
+
+        setView.setInput( SigilCore.getRepositoryConfiguration().loadRepositorySets().keySet() );
+
+        // layout
+        control.setLayout( new GridLayout( 2, false ) );
+    }
+
+
+    private String getCurrentSet()
+    {
+        try
+        {
+            IProject p = ( IProject ) getElement().getAdapter( IProject.class );
+            ISigilProjectModel model = SigilCore.create( p );
+            return model.getPreferences().get( SigilCore.REPOSITORY_SET, null );
+        }
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Failed to read repository set", e );
+            return null;
+        }
+    }
+
+
+    @Override
+    public boolean okToLeave()
+    {
+        if ( projectSpecific )
+        {
+            if ( setView.getSelection().isEmpty() )
+            {
+                setErrorMessage( "Must select a repository set" );
+                return false;
+            }
+        }
+        setErrorMessage( null );
+        return true;
+    }
+
+
+    @Override
+    public boolean performOk()
+    {
+        return ProjectUtils.runTaskWithRebuildCheck( new Callable<Boolean>()
+        {
+            public Boolean call() throws CoreException, BackingStoreException
+            {
+                String set = null;
+                if ( projectSpecific )
+                {
+                    set = ( String ) ( ( IStructuredSelection ) setView.getSelection() ).getFirstElement();
+                }
+
+                IProject p = ( IProject ) getElement().getAdapter( IProject.class );
+                ISigilProjectModel model = SigilCore.create( p );
+                model.getPreferences().put( SigilCore.REPOSITORY_SET, set );
+                model.getPreferences().flush();
+                return true;
+            }
+
+        }, getShell() );
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/NewRepositoryWizard.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/NewRepositoryWizard.java
index 3d16553..df7de93 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/NewRepositoryWizard.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/NewRepositoryWizard.java
@@ -19,32 +19,43 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences.repository;
 
+
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
 import org.eclipse.jface.wizard.Wizard;
 
-public class NewRepositoryWizard extends Wizard {
 
-	private IRepositoryModel repository;
-	
-	private RepositoryTypeSelectionPage page = new RepositoryTypeSelectionPage();
-	
-	public void addPages() {
-		addPage( page );
-	}
-	
-	@Override
-	public boolean performFinish() {
-		repository = page.getRepository();
-		return true;
-	}
-	@Override
-	public boolean needsPreviousAndNextButtons() {
-		return true;
-	}
+public class NewRepositoryWizard extends Wizard
+{
 
-	public IRepositoryModel getRepository() {
-		return repository;
-	}
+    private IRepositoryModel repository;
 
+    private RepositoryTypeSelectionPage page = new RepositoryTypeSelectionPage();
+
+
+    public void addPages()
+    {
+        addPage( page );
+    }
+
+
+    @Override
+    public boolean performFinish()
+    {
+        repository = page.getRepository();
+        return true;
+    }
+
+
+    @Override
+    public boolean needsPreviousAndNextButtons()
+    {
+        return true;
+    }
+
+
+    public IRepositoryModel getRepository()
+    {
+        return repository;
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoriesPreferencePage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoriesPreferencePage.java
index 3e1baef..13c9f5b 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoriesPreferencePage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoriesPreferencePage.java
@@ -17,8 +17,9 @@
  * under the License.
  */
 
-package org.apache.felix.sigil.ui.eclipse.ui.preferences.repository;

-

+package org.apache.felix.sigil.ui.eclipse.ui.preferences.repository;
+
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryConfiguration;
 import org.apache.felix.sigil.eclipse.model.repository.IRepositorySet;
@@ -35,80 +36,101 @@
 import org.eclipse.swt.widgets.TabItem;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferencePage;
-

-public class RepositoriesPreferencePage extends ProjectDependentPreferencesPage implements

-		IWorkbenchPreferencePage {

 
-	private boolean changed;
-	private RepositoriesView viewPage;
-	private RepositorySetsView setPage;
 
-	public RepositoriesPreferencePage() {
-		super( "Repository Preferences" );
-	}
-	@Override

-	protected Control createContents(Composite parent) {

-		Control control = initContents( parent );
-		return control;

-	}

-

-	@Override

-	protected IPreferenceStore doGetPreferenceStore() {

-		return SigilCore.getDefault().getPreferenceStore();

-	}

+public class RepositoriesPreferencePage extends ProjectDependentPreferencesPage implements IWorkbenchPreferencePage
+{
 
-	protected void changed() {
-		changed = true;
-		updateApplyButton();
-	}

-	
-	private Control initContents(Composite parent) {
-		viewPage = new RepositoriesView(this);
-		setPage = new RepositorySetsView(this);
-		
-		Composite control = new Composite(parent, SWT.NONE);
-		
-		TabFolder folder = new TabFolder(control, SWT.TOP);
-		
-		TabItem view = new TabItem(folder, SWT.NONE);
-		view.setText("Repositories");
-		view.setControl(viewPage.createContents(folder) );
-		
-		TabItem sets = new TabItem(folder, SWT.NONE);
-		sets.setText("Sets");
-		sets.setControl(setPage.createContents(folder) );
+    private boolean changed;
+    private RepositoriesView viewPage;
+    private RepositorySetsView setPage;
 
-		control.setLayout(new GridLayout(1, true));
-		folder.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, true));
-		
-		return control;
-	}
 
-	public void init(IWorkbench workbench) {
-		// TODO Auto-generated method stub
-		
-	}
+    public RepositoriesPreferencePage()
+    {
+        super( "Repository Preferences" );
+    }
 
-	@Override
-	protected void doSave() {
-		try {
-			IRepositoryConfiguration config = SigilCore.getRepositoryConfiguration();
-			config.saveRepositories(viewPage.getRepositories());
-			config.saveRepositorySets(setPage.getSets());
-			IRepositorySet defaultSet = new RepositorySet(setPage.getDefaultRepositories());
-			config.setDefaultRepositorySet(defaultSet);
-			
-			setErrorMessage(null);
-			getApplyButton().setEnabled(false);
-			changed = false;
-		} catch (CoreException e) {
-			setErrorMessage("Failed to save repositories:" + e.getStatus().getMessage());
-			SigilCore.error("Failed to save repositories", e);
-		}
-	}
 
-	@Override
-	protected boolean isDirty() {
-		return changed;
-	}	

-}

+    @Override
+    protected Control createContents( Composite parent )
+    {
+        Control control = initContents( parent );
+        return control;
+    }
+
+
+    @Override
+    protected IPreferenceStore doGetPreferenceStore()
+    {
+        return SigilCore.getDefault().getPreferenceStore();
+    }
+
+
+    protected void changed()
+    {
+        changed = true;
+        updateApplyButton();
+    }
+
+
+    private Control initContents( Composite parent )
+    {
+        viewPage = new RepositoriesView( this );
+        setPage = new RepositorySetsView( this );
+
+        Composite control = new Composite( parent, SWT.NONE );
+
+        TabFolder folder = new TabFolder( control, SWT.TOP );
+
+        TabItem view = new TabItem( folder, SWT.NONE );
+        view.setText( "Repositories" );
+        view.setControl( viewPage.createContents( folder ) );
+
+        TabItem sets = new TabItem( folder, SWT.NONE );
+        sets.setText( "Sets" );
+        sets.setControl( setPage.createContents( folder ) );
+
+        control.setLayout( new GridLayout( 1, true ) );
+        folder.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
+
+        return control;
+    }
+
+
+    public void init( IWorkbench workbench )
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    @Override
+    protected void doSave()
+    {
+        try
+        {
+            IRepositoryConfiguration config = SigilCore.getRepositoryConfiguration();
+            config.saveRepositories( viewPage.getRepositories() );
+            config.saveRepositorySets( setPage.getSets() );
+            IRepositorySet defaultSet = new RepositorySet( setPage.getDefaultRepositories() );
+            config.setDefaultRepositorySet( defaultSet );
+
+            setErrorMessage( null );
+            getApplyButton().setEnabled( false );
+            changed = false;
+        }
+        catch ( CoreException e )
+        {
+            setErrorMessage( "Failed to save repositories:" + e.getStatus().getMessage() );
+            SigilCore.error( "Failed to save repositories", e );
+        }
+    }
+
+
+    @Override
+    protected boolean isDirty()
+    {
+        return changed;
+    }
+}
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoriesView.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoriesView.java
index 5048d73..12e0e2c 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoriesView.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoriesView.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences.repository;
 
+
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -49,213 +50,271 @@
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Table;
 
-public class RepositoriesView {
-	private final RepositoriesPreferencePage page;
 
-	private List<IRepositoryModel> repositories;
-	
-	private TableViewer repositoryView;
+public class RepositoriesView
+{
+    private final RepositoriesPreferencePage page;
 
-	public RepositoriesView(RepositoriesPreferencePage page) {
-		this.page = page;
-	}
+    private List<IRepositoryModel> repositories;
 
-	public Control createContents(Composite parent) {
-		// Create Controls
-		Composite composite = new Composite(parent, SWT.NONE);
-		
-		Table table = new Table(composite, SWT.MULTI | SWT.BORDER);
+    private TableViewer repositoryView;
 
-		// Table Viewer Setup
-		repositoryView = new TableViewer(table);
-		repositoryView.setLabelProvider(new LabelProvider() {
-			@Override
-			public String getText(Object element) {
-				IRepositoryModel rep = (IRepositoryModel) element;
-				return rep.getName();
-			}
 
-			@Override
-			public Image getImage(Object element) {
-				IRepositoryModel rep = (IRepositoryModel) element;				
-				return rep.getType().getIcon();
-			}
-		});
+    public RepositoriesView( RepositoriesPreferencePage page )
+    {
+        this.page = page;
+    }
 
-		repositoryView.setContentProvider( new DefaultTableProvider() {
-			public Object[] getElements(Object inputElement) {
-				return toArray(inputElement);
-			}
-		} );
-		
-		// Layout
-		composite.setLayout(new GridLayout(2, false));
-		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 6));
-		
-		createButtons(composite, repositoryView);	
-		
-		repositories = SigilCore.getRepositoryConfiguration().loadRepositories();
-		repositoryView.setInput(repositories);		
-		
-		return composite;
-	}
-	
-	private void createButtons(final Composite composite, final TableViewer repositoryView) {
-		final Button add = new Button(composite, SWT.PUSH);
-		add.setText("Add...");
-		add.setEnabled(true);
-		
-		final Button edit = new Button(composite, SWT.PUSH);
-		edit.setText("Edit...");
-		edit.setEnabled(false);
-				
-		final Button remove = new Button(composite, SWT.PUSH);
-		remove.setText("Remove");
-		remove.setEnabled(false);
-		
-		final Button refresh = new Button(composite, SWT.PUSH);
-		refresh.setText("Refresh");
-		refresh.setEnabled( false );
-		
-		// Listeners
-		add.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				add(composite);
-			}			
-		});
-		
-		edit.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				IStructuredSelection sel = (IStructuredSelection) repositoryView.getSelection();
-				edit(composite, sel);
-			}			
-		});
-		
-		remove.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				IStructuredSelection sel = (IStructuredSelection) repositoryView.getSelection();
-				remove(sel);
-			}			
-		});
-		
-		refresh.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				IStructuredSelection sel = (IStructuredSelection) repositoryView.getSelection();
-				refresh(composite, sel);
-			}			
-		});
-		
-		repositoryView.addSelectionChangedListener( new ISelectionChangedListener() {
-			public void selectionChanged(SelectionChangedEvent event) {
-				boolean selected = !event.getSelection().isEmpty();
-				if ( selected ) {
-					refresh.setEnabled(true);
-					
-					IStructuredSelection sel = (IStructuredSelection) event.getSelection();
-					
-					checkEditEnabled(edit, sel);
-					checkRemoveEnabled(remove, sel);
-				}
-				else {
-					refresh.setEnabled(false);
-					edit.setEnabled(false);
-					remove.setEnabled(false);
-				}
-			}
-		});
-		
-		add.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-		edit.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-		remove.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-	}
-	
-	@SuppressWarnings("unchecked")
-	private void checkRemoveEnabled(Button button, IStructuredSelection sel) {
-		boolean alldynamic = true;
-		for ( Iterator i = sel.iterator(); i.hasNext(); ) {
-			IRepositoryModel model = (IRepositoryModel) i.next();
-			if ( !model.getType().isDynamic() ) {
-				alldynamic = false;
-				break;
-			}
-		}
-		button.setEnabled(alldynamic);
-	}
 
-	private void checkEditEnabled(Button edit, IStructuredSelection sel) {
-		if ( sel.size() == 1 ) {
-			IRepositoryModel element = (IRepositoryModel) sel.getFirstElement();
-			if ( WizardHelper.hasWizard( element.getType()) ) {
-				edit.setEnabled(true);						
-			}
-			else {
-				edit.setEnabled(false);
-			}
-		}
-		else {
-			edit.setEnabled(false);
-		}
-	}
+    public Control createContents( Composite parent )
+    {
+        // Create Controls
+        Composite composite = new Composite( parent, SWT.NONE );
 
-	@SuppressWarnings("unchecked")
-	protected void refresh(Control parent, IStructuredSelection sel) {
-		ArrayList<IRepositoryModel> models = new ArrayList<IRepositoryModel>(sel.size());
-		
-		for ( Iterator i = sel.iterator(); i.hasNext(); ) {
-			IRepositoryModel model = (IRepositoryModel) i.next();
-			models.add( model );
-		}
-		
-		new RefreshRepositoryAction(models.toArray(new IRepositoryModel[models.size()])).run();
-	}
+        Table table = new Table( composite, SWT.MULTI | SWT.BORDER );
 
-	private void add(Control parent) {
-		NewRepositoryWizard wizard = new NewRepositoryWizard();
-		WizardDialog dialog = new WizardDialog(getShell(parent), wizard);
-		if ( dialog.open() == Window.OK ) {
-			repositories.add(wizard.getRepository());
-			updated();
-		}
-	}
+        // Table Viewer Setup
+        repositoryView = new TableViewer( table );
+        repositoryView.setLabelProvider( new LabelProvider()
+        {
+            @Override
+            public String getText( Object element )
+            {
+                IRepositoryModel rep = ( IRepositoryModel ) element;
+                return rep.getName();
+            }
 
-	private void edit(Control parent, IStructuredSelection sel) {
-		IRepositoryModel model = (IRepositoryModel) sel.getFirstElement();
-		try {
-			RepositoryWizard wizard = WizardHelper.loadWizard(model.getType());
-			wizard.init(model);
-			WizardDialog dialog = new WizardDialog(getShell(parent), wizard);
-			if ( dialog.open() == Window.OK ) {
-				updated();
-			}
-		}
-		catch (CoreException e) {
-			SigilCore.error( "Failed to load wizard", e);
-			MessageDialog.openError(getShell(parent), "Error", "Failed to load wizard:" + e.getStatus().getMessage() );
-		}
-	}
 
-	private Shell getShell(Control parent) {
-		return parent.getShell();
-	}
+            @Override
+            public Image getImage( Object element )
+            {
+                IRepositoryModel rep = ( IRepositoryModel ) element;
+                return rep.getType().getIcon();
+            }
+        } );
 
-	@SuppressWarnings("unchecked")
-	private void remove(IStructuredSelection sel) {
-		boolean change = false;
-		for ( Iterator i = sel.iterator(); i.hasNext(); ) {
-			change = repositories.remove(i.next());
-		}
-		
-		if ( change ) {
-			updated();
-		}
-	}
+        repositoryView.setContentProvider( new DefaultTableProvider()
+        {
+            public Object[] getElements( Object inputElement )
+            {
+                return toArray( inputElement );
+            }
+        } );
 
-	private void updated() {
-		repositoryView.refresh();
-		page.changed();
-	}
+        // Layout
+        composite.setLayout( new GridLayout( 2, false ) );
+        table.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true, 1, 6 ) );
 
-	public List<IRepositoryModel> getRepositories() {
-		return repositories;
-	}	
+        createButtons( composite, repositoryView );
+
+        repositories = SigilCore.getRepositoryConfiguration().loadRepositories();
+        repositoryView.setInput( repositories );
+
+        return composite;
+    }
+
+
+    private void createButtons( final Composite composite, final TableViewer repositoryView )
+    {
+        final Button add = new Button( composite, SWT.PUSH );
+        add.setText( "Add..." );
+        add.setEnabled( true );
+
+        final Button edit = new Button( composite, SWT.PUSH );
+        edit.setText( "Edit..." );
+        edit.setEnabled( false );
+
+        final Button remove = new Button( composite, SWT.PUSH );
+        remove.setText( "Remove" );
+        remove.setEnabled( false );
+
+        final Button refresh = new Button( composite, SWT.PUSH );
+        refresh.setText( "Refresh" );
+        refresh.setEnabled( false );
+
+        // Listeners
+        add.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                add( composite );
+            }
+        } );
+
+        edit.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                IStructuredSelection sel = ( IStructuredSelection ) repositoryView.getSelection();
+                edit( composite, sel );
+            }
+        } );
+
+        remove.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                IStructuredSelection sel = ( IStructuredSelection ) repositoryView.getSelection();
+                remove( sel );
+            }
+        } );
+
+        refresh.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                IStructuredSelection sel = ( IStructuredSelection ) repositoryView.getSelection();
+                refresh( composite, sel );
+            }
+        } );
+
+        repositoryView.addSelectionChangedListener( new ISelectionChangedListener()
+        {
+            public void selectionChanged( SelectionChangedEvent event )
+            {
+                boolean selected = !event.getSelection().isEmpty();
+                if ( selected )
+                {
+                    refresh.setEnabled( true );
+
+                    IStructuredSelection sel = ( IStructuredSelection ) event.getSelection();
+
+                    checkEditEnabled( edit, sel );
+                    checkRemoveEnabled( remove, sel );
+                }
+                else
+                {
+                    refresh.setEnabled( false );
+                    edit.setEnabled( false );
+                    remove.setEnabled( false );
+                }
+            }
+        } );
+
+        add.setLayoutData( new GridData( SWT.FILL, SWT.FILL, false, false ) );
+        edit.setLayoutData( new GridData( SWT.FILL, SWT.FILL, false, false ) );
+        remove.setLayoutData( new GridData( SWT.FILL, SWT.FILL, false, false ) );
+    }
+
+
+    @SuppressWarnings("unchecked")
+    private void checkRemoveEnabled( Button button, IStructuredSelection sel )
+    {
+        boolean alldynamic = true;
+        for ( Iterator i = sel.iterator(); i.hasNext(); )
+        {
+            IRepositoryModel model = ( IRepositoryModel ) i.next();
+            if ( !model.getType().isDynamic() )
+            {
+                alldynamic = false;
+                break;
+            }
+        }
+        button.setEnabled( alldynamic );
+    }
+
+
+    private void checkEditEnabled( Button edit, IStructuredSelection sel )
+    {
+        if ( sel.size() == 1 )
+        {
+            IRepositoryModel element = ( IRepositoryModel ) sel.getFirstElement();
+            if ( WizardHelper.hasWizard( element.getType() ) )
+            {
+                edit.setEnabled( true );
+            }
+            else
+            {
+                edit.setEnabled( false );
+            }
+        }
+        else
+        {
+            edit.setEnabled( false );
+        }
+    }
+
+
+    @SuppressWarnings("unchecked")
+    protected void refresh( Control parent, IStructuredSelection sel )
+    {
+        ArrayList<IRepositoryModel> models = new ArrayList<IRepositoryModel>( sel.size() );
+
+        for ( Iterator i = sel.iterator(); i.hasNext(); )
+        {
+            IRepositoryModel model = ( IRepositoryModel ) i.next();
+            models.add( model );
+        }
+
+        new RefreshRepositoryAction( models.toArray( new IRepositoryModel[models.size()] ) ).run();
+    }
+
+
+    private void add( Control parent )
+    {
+        NewRepositoryWizard wizard = new NewRepositoryWizard();
+        WizardDialog dialog = new WizardDialog( getShell( parent ), wizard );
+        if ( dialog.open() == Window.OK )
+        {
+            repositories.add( wizard.getRepository() );
+            updated();
+        }
+    }
+
+
+    private void edit( Control parent, IStructuredSelection sel )
+    {
+        IRepositoryModel model = ( IRepositoryModel ) sel.getFirstElement();
+        try
+        {
+            RepositoryWizard wizard = WizardHelper.loadWizard( model.getType() );
+            wizard.init( model );
+            WizardDialog dialog = new WizardDialog( getShell( parent ), wizard );
+            if ( dialog.open() == Window.OK )
+            {
+                updated();
+            }
+        }
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Failed to load wizard", e );
+            MessageDialog
+                .openError( getShell( parent ), "Error", "Failed to load wizard:" + e.getStatus().getMessage() );
+        }
+    }
+
+
+    private Shell getShell( Control parent )
+    {
+        return parent.getShell();
+    }
+
+
+    @SuppressWarnings("unchecked")
+    private void remove( IStructuredSelection sel )
+    {
+        boolean change = false;
+        for ( Iterator i = sel.iterator(); i.hasNext(); )
+        {
+            change = repositories.remove( i.next() );
+        }
+
+        if ( change )
+        {
+            updated();
+        }
+    }
+
+
+    private void updated()
+    {
+        repositoryView.refresh();
+        page.changed();
+    }
+
+
+    public List<IRepositoryModel> getRepositories()
+    {
+        return repositories;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositorySetDialog.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositorySetDialog.java
index 09a63ba..afa39fe 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositorySetDialog.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositorySetDialog.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences.repository;
 
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -49,212 +50,270 @@
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Text;
 
-public class RepositorySetDialog extends TitleAreaDialog {
-	
-	private CheckboxTableViewer viewer;
-	private Text nameTxt;
-	private Button upBtn;
-	private Button downBtn;
-	private final String setName;
-	private List<IRepositoryModel> repositories;
-	private final boolean nameEditable;
-	private final Set<String> set;
-	
-	private String newName;
-	
-	public RepositorySetDialog(Shell shell, Set<String> set) {
-		this(shell, null, true, set);
-	}
-	
-	public RepositorySetDialog(Shell parent, RepositoryViewData data, boolean nameEditable, Set<String> set) {
-		super(parent);
-		this.set = set;
-		this.setName = data == null ? "" : data.getName();
-		this.repositories = data == null ? new ArrayList<IRepositoryModel>() : new ArrayList<IRepositoryModel>(Arrays.asList(data.getRepositories()));
-		this.nameEditable = nameEditable;
-	}
 
-	@Override
-	protected Control createDialogArea(Composite parent) {
-		Composite area = (Composite) super.createDialogArea(parent);
-		createControl(area);
-		return area;
-	}
+public class RepositorySetDialog extends TitleAreaDialog
+{
 
-	public void createControl(Composite parent) {
-		// controls
-		Composite body = new Composite(parent, SWT.NONE);
-		body.setLayoutData( new GridData(GridData.FILL_BOTH) );
-		
-		if ( nameEditable ) {
-			new Label( body, SWT.NONE ).setText( "Name" );
-			
-			nameTxt = new Text( body, SWT.BORDER );
-			
-			nameTxt.setText(setName);
-			
-			nameTxt.addKeyListener( new KeyAdapter() {
-				@Override
-				public void keyReleased(KeyEvent e) {
-					checkComplete();
-				}
-			});
-		}
-		
-		Composite table = new Composite(body, SWT.NONE);
-		table.setLayout( new GridLayout(2, false ) );
-		createTable( table );
-		
-		// layout
-		body.setLayout( new GridLayout( 2, false ) );
-		if ( nameEditable ) {
-			nameTxt.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, false) );
-		}
-		table.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1) );
-	}
-	
-	public RepositoryViewData getData() {
-		String name = nameEditable ? newName : setName;
-		IRepositoryModel[] reps = repositories.toArray( new IRepositoryModel[repositories.size()]);
-		return new RepositoryViewData( name, reps );
-	}
+    private CheckboxTableViewer viewer;
+    private Text nameTxt;
+    private Button upBtn;
+    private Button downBtn;
+    private final String setName;
+    private List<IRepositoryModel> repositories;
+    private final boolean nameEditable;
+    private final Set<String> set;
 
-	private void checkComplete() {
-		if ( nameEditable ) {
-			String name = nameTxt.getText();
-			if ( !name.equals( setName ) && set.contains( name ) ) {
-				setErrorMessage("Set " + name + " already exists" );
-				Button b = getButton(IDialogConstants.OK_ID);
-				b.setEnabled(false);
-			}
-		}		
-		setErrorMessage(null);
-		Button b = getButton(IDialogConstants.OK_ID);
-		b.setEnabled(true);
-	}
+    private String newName;
 
 
-	@Override
-	protected void okPressed() {
-		if ( nameEditable ) {
-			newName = nameTxt.getText();
-		}
-		repositories = getRepositories();
-		super.okPressed();
-	}
+    public RepositorySetDialog( Shell shell, Set<String> set )
+    {
+        this( shell, null, true, set );
+    }
 
-	private void createTable(Composite body) {
-		createViewer(body);
-		
-		Composite btns = new Composite(body, SWT.NONE);
-		btns.setLayout( new GridLayout( 1, true ) );
-		
-		createButtons(btns);
-		
-		// layout
-		viewer.getTable().setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
-		btns.setLayoutData( new GridData( SWT.RIGHT, SWT.TOP, false, false ) );
-	}
 
-	private void createButtons(Composite parent) {
-		upBtn = new Button(parent, SWT.PUSH);
-		upBtn.setText( "Up" );
-		upBtn.addSelectionListener( new SelectionAdapter() {
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				up();
-			}
-		});
-		
-		downBtn = new Button(parent, SWT.PUSH);
-		downBtn.setText( "Down" );
-		downBtn.addSelectionListener( new SelectionAdapter() {
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				down();
-			}
-		});
-		
-		setUpDownEnabled(false);
-	}
+    public RepositorySetDialog( Shell parent, RepositoryViewData data, boolean nameEditable, Set<String> set )
+    {
+        super( parent );
+        this.set = set;
+        this.setName = data == null ? "" : data.getName();
+        this.repositories = data == null ? new ArrayList<IRepositoryModel>() : new ArrayList<IRepositoryModel>( Arrays
+            .asList( data.getRepositories() ) );
+        this.nameEditable = nameEditable;
+    }
 
-	private void up() {
-		IRepositoryModel model = (IRepositoryModel) ((StructuredSelection) viewer.getSelection()).getFirstElement();
-		int i = repositories.indexOf(model);
-		if ( i > 0 ) {
-			repositories.remove( i );
-			repositories.add( i - 1, model );
-			viewer.refresh();
-		}
-	}
 
-	private void down() {
-		IRepositoryModel model = (IRepositoryModel) ((StructuredSelection) viewer.getSelection()).getFirstElement();
-		int i = repositories.indexOf(model);
-		if ( i < repositories.size() - 1 ) {
-			repositories.remove( i );
-			repositories.add( i + 1, model );
-			viewer.refresh();
-		}
-	}
+    @Override
+    protected Control createDialogArea( Composite parent )
+    {
+        Composite area = ( Composite ) super.createDialogArea( parent );
+        createControl( area );
+        return area;
+    }
 
-	private void createViewer(Composite parent) {
-		viewer = CheckboxTableViewer.newCheckList(parent, SWT.BORDER);
-		
-		viewer.addSelectionChangedListener( new ISelectionChangedListener() {
-			public void selectionChanged(SelectionChangedEvent event) {
-				setUpDownEnabled( !viewer.getSelection().isEmpty() ); 
-			}
-		});
-		
-		viewer.setContentProvider( new DefaultTableProvider() {
-			public Object[] getElements(Object inputElement) {
-				return toArray(inputElement);
-			}
-		});
-		
-		viewer.setLabelProvider( new DefaultLabelProvider() {
-			public Image getImage(Object element) {
-				return null;
-			}
 
-			public String getText(Object element) {
-				IRepositoryModel m = (IRepositoryModel) element;
-				return m.getName();
-			}			
-		});
-		
-		viewer.setInput( repositories );
-		
-		for ( IRepositoryModel m : repositories ) {
-			viewer.setChecked(m, true);
-		}
-		
-		List<IRepositoryModel> allRepositories = SigilCore.getRepositoryConfiguration().loadRepositories();
-		
-		for ( IRepositoryModel m : allRepositories ) {
-			if ( !repositories.contains(m) ) {
-				repositories.add(m);
-			}
-		}
-		
-		viewer.refresh();		
-	}
+    public void createControl( Composite parent )
+    {
+        // controls
+        Composite body = new Composite( parent, SWT.NONE );
+        body.setLayoutData( new GridData( GridData.FILL_BOTH ) );
 
-	private void setUpDownEnabled(boolean enabled) {
-		upBtn.setEnabled(enabled);
-		downBtn.setEnabled(enabled);
-	}
+        if ( nameEditable )
+        {
+            new Label( body, SWT.NONE ).setText( "Name" );
 
-	private List<IRepositoryModel> getRepositories() {
-		ArrayList<IRepositoryModel> reps = new ArrayList<IRepositoryModel>();
-		
-		for ( IRepositoryModel m : repositories ) {
-			if ( viewer.getChecked(m) ) {
-				reps.add( m );
-			}
-		}
-		
-		return reps;
-	}
+            nameTxt = new Text( body, SWT.BORDER );
+
+            nameTxt.setText( setName );
+
+            nameTxt.addKeyListener( new KeyAdapter()
+            {
+                @Override
+                public void keyReleased( KeyEvent e )
+                {
+                    checkComplete();
+                }
+            } );
+        }
+
+        Composite table = new Composite( body, SWT.NONE );
+        table.setLayout( new GridLayout( 2, false ) );
+        createTable( table );
+
+        // layout
+        body.setLayout( new GridLayout( 2, false ) );
+        if ( nameEditable )
+        {
+            nameTxt.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        }
+        table.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true, 2, 1 ) );
+    }
+
+
+    public RepositoryViewData getData()
+    {
+        String name = nameEditable ? newName : setName;
+        IRepositoryModel[] reps = repositories.toArray( new IRepositoryModel[repositories.size()] );
+        return new RepositoryViewData( name, reps );
+    }
+
+
+    private void checkComplete()
+    {
+        if ( nameEditable )
+        {
+            String name = nameTxt.getText();
+            if ( !name.equals( setName ) && set.contains( name ) )
+            {
+                setErrorMessage( "Set " + name + " already exists" );
+                Button b = getButton( IDialogConstants.OK_ID );
+                b.setEnabled( false );
+            }
+        }
+        setErrorMessage( null );
+        Button b = getButton( IDialogConstants.OK_ID );
+        b.setEnabled( true );
+    }
+
+
+    @Override
+    protected void okPressed()
+    {
+        if ( nameEditable )
+        {
+            newName = nameTxt.getText();
+        }
+        repositories = getRepositories();
+        super.okPressed();
+    }
+
+
+    private void createTable( Composite body )
+    {
+        createViewer( body );
+
+        Composite btns = new Composite( body, SWT.NONE );
+        btns.setLayout( new GridLayout( 1, true ) );
+
+        createButtons( btns );
+
+        // layout
+        viewer.getTable().setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
+        btns.setLayoutData( new GridData( SWT.RIGHT, SWT.TOP, false, false ) );
+    }
+
+
+    private void createButtons( Composite parent )
+    {
+        upBtn = new Button( parent, SWT.PUSH );
+        upBtn.setText( "Up" );
+        upBtn.addSelectionListener( new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected( SelectionEvent e )
+            {
+                up();
+            }
+        } );
+
+        downBtn = new Button( parent, SWT.PUSH );
+        downBtn.setText( "Down" );
+        downBtn.addSelectionListener( new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected( SelectionEvent e )
+            {
+                down();
+            }
+        } );
+
+        setUpDownEnabled( false );
+    }
+
+
+    private void up()
+    {
+        IRepositoryModel model = ( IRepositoryModel ) ( ( StructuredSelection ) viewer.getSelection() )
+            .getFirstElement();
+        int i = repositories.indexOf( model );
+        if ( i > 0 )
+        {
+            repositories.remove( i );
+            repositories.add( i - 1, model );
+            viewer.refresh();
+        }
+    }
+
+
+    private void down()
+    {
+        IRepositoryModel model = ( IRepositoryModel ) ( ( StructuredSelection ) viewer.getSelection() )
+            .getFirstElement();
+        int i = repositories.indexOf( model );
+        if ( i < repositories.size() - 1 )
+        {
+            repositories.remove( i );
+            repositories.add( i + 1, model );
+            viewer.refresh();
+        }
+    }
+
+
+    private void createViewer( Composite parent )
+    {
+        viewer = CheckboxTableViewer.newCheckList( parent, SWT.BORDER );
+
+        viewer.addSelectionChangedListener( new ISelectionChangedListener()
+        {
+            public void selectionChanged( SelectionChangedEvent event )
+            {
+                setUpDownEnabled( !viewer.getSelection().isEmpty() );
+            }
+        } );
+
+        viewer.setContentProvider( new DefaultTableProvider()
+        {
+            public Object[] getElements( Object inputElement )
+            {
+                return toArray( inputElement );
+            }
+        } );
+
+        viewer.setLabelProvider( new DefaultLabelProvider()
+        {
+            public Image getImage( Object element )
+            {
+                return null;
+            }
+
+
+            public String getText( Object element )
+            {
+                IRepositoryModel m = ( IRepositoryModel ) element;
+                return m.getName();
+            }
+        } );
+
+        viewer.setInput( repositories );
+
+        for ( IRepositoryModel m : repositories )
+        {
+            viewer.setChecked( m, true );
+        }
+
+        List<IRepositoryModel> allRepositories = SigilCore.getRepositoryConfiguration().loadRepositories();
+
+        for ( IRepositoryModel m : allRepositories )
+        {
+            if ( !repositories.contains( m ) )
+            {
+                repositories.add( m );
+            }
+        }
+
+        viewer.refresh();
+    }
+
+
+    private void setUpDownEnabled( boolean enabled )
+    {
+        upBtn.setEnabled( enabled );
+        downBtn.setEnabled( enabled );
+    }
+
+
+    private List<IRepositoryModel> getRepositories()
+    {
+        ArrayList<IRepositoryModel> reps = new ArrayList<IRepositoryModel>();
+
+        for ( IRepositoryModel m : repositories )
+        {
+            if ( viewer.getChecked( m ) )
+            {
+                reps.add( m );
+            }
+        }
+
+        return reps;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositorySetsView.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositorySetsView.java
index af92242..85292a9 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositorySetsView.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositorySetsView.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences.repository;
 
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -48,181 +49,233 @@
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Table;
 
-public class RepositorySetsView {
-	private static final String DEFAULT = "default";
 
-	private final RepositoriesPreferencePage page;
+public class RepositorySetsView
+{
+    private static final String DEFAULT = "default";
 
-	private ArrayList<RepositoryViewData> sets = new ArrayList<RepositoryViewData>();
-	
-	private TableViewer setView;
+    private final RepositoriesPreferencePage page;
 
-	private RepositoryViewData defaultSet;
-	
-	public RepositorySetsView(RepositoriesPreferencePage page) {
-		this.page = page;
-	}
+    private ArrayList<RepositoryViewData> sets = new ArrayList<RepositoryViewData>();
 
-	public Control createContents(Composite parent) {
-		// Create Controls
-		Composite composite = new Composite(parent, SWT.NONE);
-		
-		Table table = new Table(composite, SWT.SINGLE | SWT.BORDER);
+    private TableViewer setView;
 
-		// Table Viewer Setup
-		setView = new TableViewer(table);
+    private RepositoryViewData defaultSet;
 
-		setView.setContentProvider( new DefaultTableProvider() {
-			public Object[] getElements(Object inputElement) {
-				return toArray(inputElement);
-			}
-		} );
-		
-		defaultSet = new RepositoryViewData(DEFAULT, SigilCore.getRepositoryConfiguration().getDefaultRepositorySet().getRepositories());
-		
-		sets.add( defaultSet );
-		
-		for( Map.Entry<String, IRepositorySet> e : SigilCore.getRepositoryConfiguration().loadRepositorySets().entrySet() ) {
-			IRepositorySet s = e.getValue();
-			sets.add( new RepositoryViewData( e.getKey(), s.getRepositories() ) );
-		}
-		
-		setView.setLabelProvider( new DefaultLabelProvider() {
-			public Image getImage(Object element) {
-				return null;
-			}
 
-			public String getText(Object element) {
-				RepositoryViewData data = (RepositoryViewData) element;
-				return data.getName();
-			}
-		});
-		
-		setView.setInput(sets);
-		
-		// Layout
-		composite.setLayout(new GridLayout(2, false));
-		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 6));
-		
-		createButtons(composite);	
-				
-		return composite;
-	}
-	
-	private void createButtons(final Composite composite) {
-		final Button add = new Button(composite, SWT.PUSH);
-		add.setText("Add...");
-		add.setEnabled(true);
-		
-		final Button edit = new Button(composite, SWT.PUSH);
-		edit.setText("Edit...");
-		edit.setEnabled(false);
-				
-		final Button remove = new Button(composite, SWT.PUSH);
-		remove.setText("Remove");
-		remove.setEnabled(false);
-		// Listeners
-		add.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				add(composite);
-			}			
-		});
-		
-		edit.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				IStructuredSelection sel = (IStructuredSelection) setView.getSelection();
-				edit(composite, sel);
-			}			
-		});
-		
-		remove.addSelectionListener( new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				IStructuredSelection sel = (IStructuredSelection) setView.getSelection();
-				remove(sel);
-			}			
-		});
+    public RepositorySetsView( RepositoriesPreferencePage page )
+    {
+        this.page = page;
+    }
 
-		setView.addSelectionChangedListener( new ISelectionChangedListener() {
-			public void selectionChanged(SelectionChangedEvent event) {
-				boolean enabled = !event.getSelection().isEmpty();
-				if ( enabled ) {
-					RepositoryViewData element = (RepositoryViewData) ((IStructuredSelection) event.getSelection()).getFirstElement();
-					edit.setEnabled(true);
-					remove.setEnabled( element != defaultSet );
-				}
-				else {
-					edit.setEnabled(false);
-					remove.setEnabled(false);
-				}
-			}
-		});
-		
-		add.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-		edit.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-		remove.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));		
-	}
-	
-	private void add(Control parent) {
-		RepositorySetDialog wizard = new RepositorySetDialog(getShell(parent), getNames());
-		if ( wizard.open() == Window.OK ) {
-			sets.add( wizard.getData() );
-			updated();
-		}
-	}
 
-	private void edit(Control parent, IStructuredSelection sel) {
-		RepositoryViewData data = (RepositoryViewData) sel.getFirstElement();
-		RepositorySetDialog wizard = new RepositorySetDialog(getShell(parent), data, data != defaultSet, getNames());
-		if ( wizard.open() == Window.OK ) {
-			if ( data != defaultSet ) {
-				data.setName( wizard.getData().getName() );
-			}
-			data.setRepositories( wizard.getData().getRepositories() );
-			updated();
-		}
-	}
+    public Control createContents( Composite parent )
+    {
+        // Create Controls
+        Composite composite = new Composite( parent, SWT.NONE );
 
-	private Set<String> getNames() {
-		HashSet<String> names = new HashSet<String>();
-		
-		for ( RepositoryViewData view : sets ) {
-			if ( view != defaultSet ) {
-				names.add( view.getName() );
-			}
-		}
-		
-		return names;
-	}
+        Table table = new Table( composite, SWT.SINGLE | SWT.BORDER );
 
-	private Shell getShell(Control parent) {
-		return parent.getShell();
-	}
+        // Table Viewer Setup
+        setView = new TableViewer( table );
 
-	private void remove(IStructuredSelection sel) {
-		if ( sets.remove(sel.getFirstElement())) {
-			updated();
-		}
-	}
+        setView.setContentProvider( new DefaultTableProvider()
+        {
+            public Object[] getElements( Object inputElement )
+            {
+                return toArray( inputElement );
+            }
+        } );
 
-	private void updated() {
-		setView.refresh();
-		page.changed();
-	}
+        defaultSet = new RepositoryViewData( DEFAULT, SigilCore.getRepositoryConfiguration().getDefaultRepositorySet()
+            .getRepositories() );
 
-	public Map<String, IRepositorySet> getSets() {
-		HashMap<String, IRepositorySet> ret = new HashMap<String, IRepositorySet>();
-		
-		for ( RepositoryViewData data : sets ) {
-			if ( data != defaultSet ) {
-				IRepositorySet set = new RepositorySet(data.getRepositories());
-				ret.put( data.getName(), set );
-			}
-		}
-		
-		return ret;
-	}
+        sets.add( defaultSet );
 
-	public IRepositoryModel[] getDefaultRepositories() {
-		return defaultSet.getRepositories();
-	}
+        for ( Map.Entry<String, IRepositorySet> e : SigilCore.getRepositoryConfiguration().loadRepositorySets()
+            .entrySet() )
+        {
+            IRepositorySet s = e.getValue();
+            sets.add( new RepositoryViewData( e.getKey(), s.getRepositories() ) );
+        }
+
+        setView.setLabelProvider( new DefaultLabelProvider()
+        {
+            public Image getImage( Object element )
+            {
+                return null;
+            }
+
+
+            public String getText( Object element )
+            {
+                RepositoryViewData data = ( RepositoryViewData ) element;
+                return data.getName();
+            }
+        } );
+
+        setView.setInput( sets );
+
+        // Layout
+        composite.setLayout( new GridLayout( 2, false ) );
+        table.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true, 1, 6 ) );
+
+        createButtons( composite );
+
+        return composite;
+    }
+
+
+    private void createButtons( final Composite composite )
+    {
+        final Button add = new Button( composite, SWT.PUSH );
+        add.setText( "Add..." );
+        add.setEnabled( true );
+
+        final Button edit = new Button( composite, SWT.PUSH );
+        edit.setText( "Edit..." );
+        edit.setEnabled( false );
+
+        final Button remove = new Button( composite, SWT.PUSH );
+        remove.setText( "Remove" );
+        remove.setEnabled( false );
+        // Listeners
+        add.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                add( composite );
+            }
+        } );
+
+        edit.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                IStructuredSelection sel = ( IStructuredSelection ) setView.getSelection();
+                edit( composite, sel );
+            }
+        } );
+
+        remove.addSelectionListener( new SelectionAdapter()
+        {
+            public void widgetSelected( SelectionEvent e )
+            {
+                IStructuredSelection sel = ( IStructuredSelection ) setView.getSelection();
+                remove( sel );
+            }
+        } );
+
+        setView.addSelectionChangedListener( new ISelectionChangedListener()
+        {
+            public void selectionChanged( SelectionChangedEvent event )
+            {
+                boolean enabled = !event.getSelection().isEmpty();
+                if ( enabled )
+                {
+                    RepositoryViewData element = ( RepositoryViewData ) ( ( IStructuredSelection ) event.getSelection() )
+                        .getFirstElement();
+                    edit.setEnabled( true );
+                    remove.setEnabled( element != defaultSet );
+                }
+                else
+                {
+                    edit.setEnabled( false );
+                    remove.setEnabled( false );
+                }
+            }
+        } );
+
+        add.setLayoutData( new GridData( SWT.FILL, SWT.FILL, false, false ) );
+        edit.setLayoutData( new GridData( SWT.FILL, SWT.FILL, false, false ) );
+        remove.setLayoutData( new GridData( SWT.FILL, SWT.FILL, false, false ) );
+    }
+
+
+    private void add( Control parent )
+    {
+        RepositorySetDialog wizard = new RepositorySetDialog( getShell( parent ), getNames() );
+        if ( wizard.open() == Window.OK )
+        {
+            sets.add( wizard.getData() );
+            updated();
+        }
+    }
+
+
+    private void edit( Control parent, IStructuredSelection sel )
+    {
+        RepositoryViewData data = ( RepositoryViewData ) sel.getFirstElement();
+        RepositorySetDialog wizard = new RepositorySetDialog( getShell( parent ), data, data != defaultSet, getNames() );
+        if ( wizard.open() == Window.OK )
+        {
+            if ( data != defaultSet )
+            {
+                data.setName( wizard.getData().getName() );
+            }
+            data.setRepositories( wizard.getData().getRepositories() );
+            updated();
+        }
+    }
+
+
+    private Set<String> getNames()
+    {
+        HashSet<String> names = new HashSet<String>();
+
+        for ( RepositoryViewData view : sets )
+        {
+            if ( view != defaultSet )
+            {
+                names.add( view.getName() );
+            }
+        }
+
+        return names;
+    }
+
+
+    private Shell getShell( Control parent )
+    {
+        return parent.getShell();
+    }
+
+
+    private void remove( IStructuredSelection sel )
+    {
+        if ( sets.remove( sel.getFirstElement() ) )
+        {
+            updated();
+        }
+    }
+
+
+    private void updated()
+    {
+        setView.refresh();
+        page.changed();
+    }
+
+
+    public Map<String, IRepositorySet> getSets()
+    {
+        HashMap<String, IRepositorySet> ret = new HashMap<String, IRepositorySet>();
+
+        for ( RepositoryViewData data : sets )
+        {
+            if ( data != defaultSet )
+            {
+                IRepositorySet set = new RepositorySet( data.getRepositories() );
+                ret.put( data.getName(), set );
+            }
+        }
+
+        return ret;
+    }
+
+
+    public IRepositoryModel[] getDefaultRepositories()
+    {
+        return defaultSet.getRepositories();
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoryTypeSelectionPage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoryTypeSelectionPage.java
index 5a7ce11..de0cb1c 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoryTypeSelectionPage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoryTypeSelectionPage.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences.repository;
 
+
 import java.util.ArrayList;
 import java.util.Iterator;
 
@@ -41,85 +42,109 @@
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Table;
 
-public class RepositoryTypeSelectionPage extends WizardSelectionPage implements IWizardPage {
 
-	private static final String TITLE = "Select Repository";
-	
-	private TableViewer repositoryView;
-	private IRepositoryModel repositoryElement;
-	
-	public RepositoryTypeSelectionPage() {
-		super(TITLE);
-		setTitle(TITLE);
-	}
+public class RepositoryTypeSelectionPage extends WizardSelectionPage implements IWizardPage
+{
 
-	public void createControl(Composite parent) {
-		Composite control = new Composite(parent, SWT.NONE);
-		
-		// components
-		new Label(control, SWT.NONE).setText("Repositories" );
-		Table table = new Table(control, SWT.SINGLE | SWT.BORDER);
-		
-		// layout
-		control.setLayout( new GridLayout(1, true) );
-		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-		
-		// view
-		repositoryView = new TableViewer(table);
-		repositoryView.setLabelProvider( new LabelProvider() {
-			@Override
-			public String getText(Object element) {
-				IRepositoryType rep = (IRepositoryType) element;
-				return rep.getType();
-			}
+    private static final String TITLE = "Select Repository";
 
-			@Override
-			public Image getImage(Object element) {
-				IRepositoryType rep = (IRepositoryType) element;
-				return rep.getIcon();
-			}			
-		});
-		
-		repositoryView.setContentProvider( new DefaultTableProvider() {
-			public Object[] getElements(Object inputElement) {
-				return toArray(inputElement);
-			}
-		} );
-		
-		repositoryView.addSelectionChangedListener( new ISelectionChangedListener() {
-			public void selectionChanged(SelectionChangedEvent event) {
-				if ( !event.getSelection().isEmpty() ) {
-					IStructuredSelection sel = (IStructuredSelection) event.getSelection();
-					IRepositoryType type = (IRepositoryType) sel.getFirstElement();
-					repositoryElement = SigilCore.getRepositoryConfiguration().newRepositoryElement(type);
-					selectWizardNode(new RepositoryWizardNode(repositoryElement));
-				}
-			}
-		});
-		
-		ArrayList<IRepositoryType> descriptors = new ArrayList<IRepositoryType>(SigilCore.getRepositoryConfiguration().loadRepositoryTypes());
-		
-		for ( Iterator<IRepositoryType> i = descriptors.iterator(); i.hasNext(); ) {
-			if ( !i.next().isDynamic() ) {
-				i.remove();
-			}
-		}
-		
-		repositoryView.setInput( descriptors );
-		
-		setControl(control);
-	}
-	
-	public void selectWizardNode(RepositoryWizardNode node) {
-		setSelectedNode(node);
-	}
-	
-	public RepositoryWizardNode getSelectedWizardNode() {
-		return (RepositoryWizardNode) getSelectedNode();
-	}
+    private TableViewer repositoryView;
+    private IRepositoryModel repositoryElement;
 
-	public IRepositoryModel getRepository() {		
-		return repositoryElement;
-	}
+
+    public RepositoryTypeSelectionPage()
+    {
+        super( TITLE );
+        setTitle( TITLE );
+    }
+
+
+    public void createControl( Composite parent )
+    {
+        Composite control = new Composite( parent, SWT.NONE );
+
+        // components
+        new Label( control, SWT.NONE ).setText( "Repositories" );
+        Table table = new Table( control, SWT.SINGLE | SWT.BORDER );
+
+        // layout
+        control.setLayout( new GridLayout( 1, true ) );
+        table.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
+
+        // view
+        repositoryView = new TableViewer( table );
+        repositoryView.setLabelProvider( new LabelProvider()
+        {
+            @Override
+            public String getText( Object element )
+            {
+                IRepositoryType rep = ( IRepositoryType ) element;
+                return rep.getType();
+            }
+
+
+            @Override
+            public Image getImage( Object element )
+            {
+                IRepositoryType rep = ( IRepositoryType ) element;
+                return rep.getIcon();
+            }
+        } );
+
+        repositoryView.setContentProvider( new DefaultTableProvider()
+        {
+            public Object[] getElements( Object inputElement )
+            {
+                return toArray( inputElement );
+            }
+        } );
+
+        repositoryView.addSelectionChangedListener( new ISelectionChangedListener()
+        {
+            public void selectionChanged( SelectionChangedEvent event )
+            {
+                if ( !event.getSelection().isEmpty() )
+                {
+                    IStructuredSelection sel = ( IStructuredSelection ) event.getSelection();
+                    IRepositoryType type = ( IRepositoryType ) sel.getFirstElement();
+                    repositoryElement = SigilCore.getRepositoryConfiguration().newRepositoryElement( type );
+                    selectWizardNode( new RepositoryWizardNode( repositoryElement ) );
+                }
+            }
+        } );
+
+        ArrayList<IRepositoryType> descriptors = new ArrayList<IRepositoryType>( SigilCore.getRepositoryConfiguration()
+            .loadRepositoryTypes() );
+
+        for ( Iterator<IRepositoryType> i = descriptors.iterator(); i.hasNext(); )
+        {
+            if ( !i.next().isDynamic() )
+            {
+                i.remove();
+            }
+        }
+
+        repositoryView.setInput( descriptors );
+
+        setControl( control );
+    }
+
+
+    public void selectWizardNode( RepositoryWizardNode node )
+    {
+        setSelectedNode( node );
+    }
+
+
+    public RepositoryWizardNode getSelectedWizardNode()
+    {
+        return ( RepositoryWizardNode ) getSelectedNode();
+    }
+
+
+    public IRepositoryModel getRepository()
+    {
+        return repositoryElement;
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoryViewData.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoryViewData.java
index 171ab3b..bec9f94 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoryViewData.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoryViewData.java
@@ -19,31 +19,44 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences.repository;
 
+
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
 
-class RepositoryViewData {
-	private String name;
-	private IRepositoryModel[] reps;
 
-	RepositoryViewData(String name, IRepositoryModel[] reps) {
-		this.name = name;
-		this.reps = reps;
-	}
+class RepositoryViewData
+{
+    private String name;
+    private IRepositoryModel[] reps;
 
-	String getName() {
-		return name;
-	}
 
-	IRepositoryModel[] getRepositories() {
-		return reps;
-	}
-	
-	void setName(String name) {
-		this.name = name;
-	}
+    RepositoryViewData( String name, IRepositoryModel[] reps )
+    {
+        this.name = name;
+        this.reps = reps;
+    }
 
-	void setRepositories(IRepositoryModel[] reps) {
-		this.reps = reps;
-	}
+
+    String getName()
+    {
+        return name;
+    }
+
+
+    IRepositoryModel[] getRepositories()
+    {
+        return reps;
+    }
+
+
+    void setName( String name )
+    {
+        this.name = name;
+    }
+
+
+    void setRepositories( IRepositoryModel[] reps )
+    {
+        this.reps = reps;
+    }
 
 }
\ No newline at end of file
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoryWizardNode.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoryWizardNode.java
index ab92a62..8662cf7 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoryWizardNode.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/RepositoryWizardNode.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences.repository;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
 import org.apache.felix.sigil.ui.eclipse.ui.wizard.repository.RepositoryWizard;
@@ -27,45 +28,64 @@
 import org.eclipse.jface.wizard.IWizardNode;
 import org.eclipse.swt.graphics.Point;
 
-public class RepositoryWizardNode implements IWizardNode {
 
-	private IRepositoryModel repository;
-	
-	private RepositoryWizard wizard;
-	
-	public RepositoryWizardNode(IRepositoryModel repository) {
-		this.repository = repository;
-	}
+public class RepositoryWizardNode implements IWizardNode
+{
 
-	public void dispose() {
-		if ( wizard != null ) {
-			wizard.dispose();
-			wizard = null;
-		}
-	}
+    private IRepositoryModel repository;
 
-	public Point getExtent() {
-		return new Point(-1, -1);
-	}
+    private RepositoryWizard wizard;
 
-	public IWizard getWizard() {
-		if ( wizard == null ) {
-			try {
-				wizard = WizardHelper.loadWizard(repository.getType());
-				wizard.init( repository );
-			} catch (CoreException e) {
-				SigilCore.error( "Failed to create wizard for " + repository.getType(), e);
-			}
-		}
-		return wizard;
-	}
-	
-	public IRepositoryModel getRepository() {
-		return repository;
-	}
 
-	public boolean isContentCreated() {
-		return wizard != null;
-	}
+    public RepositoryWizardNode( IRepositoryModel repository )
+    {
+        this.repository = repository;
+    }
+
+
+    public void dispose()
+    {
+        if ( wizard != null )
+        {
+            wizard.dispose();
+            wizard = null;
+        }
+    }
+
+
+    public Point getExtent()
+    {
+        return new Point( -1, -1 );
+    }
+
+
+    public IWizard getWizard()
+    {
+        if ( wizard == null )
+        {
+            try
+            {
+                wizard = WizardHelper.loadWizard( repository.getType() );
+                wizard.init( repository );
+            }
+            catch ( CoreException e )
+            {
+                SigilCore.error( "Failed to create wizard for " + repository.getType(), e );
+            }
+        }
+        return wizard;
+    }
+
+
+    public IRepositoryModel getRepository()
+    {
+        return repository;
+    }
+
+
+    public boolean isContentCreated()
+    {
+        return wizard != null;
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/WizardHelper.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/WizardHelper.java
index f41da6c..4b17e6d 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/WizardHelper.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/preferences/repository/WizardHelper.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.preferences.repository;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryType;
 import org.apache.felix.sigil.ui.eclipse.ui.SigilUI;
@@ -30,35 +31,45 @@
 import org.eclipse.core.runtime.IExtensionRegistry;
 import org.eclipse.core.runtime.Platform;
 
-public class WizardHelper {
-	public static RepositoryWizard loadWizard(IRepositoryType type) throws CoreException {
-		IConfigurationElement e = findWizardConfig(type.getId());
-		
-		if ( e == null ) {
-			throw SigilCore.newCoreException("No wizard registered for repository " + type, null);
-		}
-		
-		return (RepositoryWizard) e.createExecutableExtension("class");
-	}
-	
-	public static boolean hasWizard(IRepositoryType type) {
-		return findWizardConfig(type.getId()) != null;
-	}	
-		
-	private static IConfigurationElement findWizardConfig(String id) {
-		IExtensionRegistry registry = Platform.getExtensionRegistry();		
-		IExtensionPoint p = registry.getExtensionPoint(SigilUI.REPOSITORY_WIZARD_EXTENSION_POINT_ID);
-		
-		for ( IExtension e : p.getExtensions() ) {
-			for ( IConfigurationElement c : e.getConfigurationElements() ) {
-				if ( id.equals( c.getAttribute("repository") ) ) {
-					return c;
-				}
-			}
-		}
-		
-		return null;
-	}
-	
-	
+
+public class WizardHelper
+{
+    public static RepositoryWizard loadWizard( IRepositoryType type ) throws CoreException
+    {
+        IConfigurationElement e = findWizardConfig( type.getId() );
+
+        if ( e == null )
+        {
+            throw SigilCore.newCoreException( "No wizard registered for repository " + type, null );
+        }
+
+        return ( RepositoryWizard ) e.createExecutableExtension( "class" );
+    }
+
+
+    public static boolean hasWizard( IRepositoryType type )
+    {
+        return findWizardConfig( type.getId() ) != null;
+    }
+
+
+    private static IConfigurationElement findWizardConfig( String id )
+    {
+        IExtensionRegistry registry = Platform.getExtensionRegistry();
+        IExtensionPoint p = registry.getExtensionPoint( SigilUI.REPOSITORY_WIZARD_EXTENSION_POINT_ID );
+
+        for ( IExtension e : p.getExtensions() )
+        {
+            for ( IConfigurationElement c : e.getConfigurationElements() )
+            {
+                if ( id.equals( c.getAttribute( "repository" ) ) )
+                {
+                    return c;
+                }
+            }
+        }
+
+        return null;
+    }
+
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportPackageProposal.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportPackageProposal.java
index 4e8ecf5..92dcec2 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportPackageProposal.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportPackageProposal.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.quickfix;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.apache.felix.sigil.model.ModelElementFactory;
@@ -39,69 +40,93 @@
 import org.eclipse.ui.actions.WorkspaceModifyOperation;
 import org.osgi.framework.Version;
 
-public class ImportPackageProposal implements IJavaCompletionProposal {
 
-	private IPackageExport e;
-	private ISigilProjectModel n;
-	
-	public ImportPackageProposal(IPackageExport e, ISigilProjectModel n) {
-		this.e = e;
-		this.n = n;
-	}
+public class ImportPackageProposal implements IJavaCompletionProposal
+{
 
-	public int getRelevance() {
-		return 100;
-	}
+    private IPackageExport e;
+    private ISigilProjectModel n;
 
-	public void apply(IDocument document) {
-		try {
-			
-			final IPackageImport i = ModelElementFactory.getInstance().newModelElement(IPackageImport.class);
-			i.setPackageName(e.getPackageName());
-			IPreferenceStore store = SigilCore.getDefault().getPreferenceStore();
-			VersionRangeBoundingRule lowerBoundRule = VersionRangeBoundingRule.valueOf(store.getString(SigilCore.DEFAULT_VERSION_LOWER_BOUND));
-			VersionRangeBoundingRule upperBoundRule = VersionRangeBoundingRule.valueOf(store.getString(SigilCore.DEFAULT_VERSION_UPPER_BOUND));
-			
-			Version version = e.getVersion();
-			VersionRange selectedVersions = VersionRange.newInstance(version, lowerBoundRule, upperBoundRule);
-			i.setVersions( selectedVersions );
-			
-			WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
-				@Override
-				protected void execute(IProgressMonitor monitor)
-						throws CoreException {
-					n.getBundle().getBundleInfo().addImport( i );
-					n.save(null);
-				}
-			};
-			
-			SigilUI.runWorkspaceOperation(op, null);
-		} catch (ModelElementFactoryException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}
 
-	public String getAdditionalProposalInfo() {
-		return null;
-	}
+    public ImportPackageProposal( IPackageExport e, ISigilProjectModel n )
+    {
+        this.e = e;
+        this.n = n;
+    }
 
-	public IContextInformation getContextInformation() {
-		// TODO Auto-generated method stub
-		return null;
-	}
 
-	public String getDisplayString() {
-		return "Import package " + e.getPackageName() + " version " + e.getVersion() + " to bundle";
-	}
+    public int getRelevance()
+    {
+        return 100;
+    }
 
-	public Image getImage() {
-		// TODO Auto-generated method stub
-		return null;
-	}
 
-	public Point getSelection(IDocument document) {
-		return null;
-	}
+    public void apply( IDocument document )
+    {
+        try
+        {
+
+            final IPackageImport i = ModelElementFactory.getInstance().newModelElement( IPackageImport.class );
+            i.setPackageName( e.getPackageName() );
+            IPreferenceStore store = SigilCore.getDefault().getPreferenceStore();
+            VersionRangeBoundingRule lowerBoundRule = VersionRangeBoundingRule.valueOf( store
+                .getString( SigilCore.DEFAULT_VERSION_LOWER_BOUND ) );
+            VersionRangeBoundingRule upperBoundRule = VersionRangeBoundingRule.valueOf( store
+                .getString( SigilCore.DEFAULT_VERSION_UPPER_BOUND ) );
+
+            Version version = e.getVersion();
+            VersionRange selectedVersions = VersionRange.newInstance( version, lowerBoundRule, upperBoundRule );
+            i.setVersions( selectedVersions );
+
+            WorkspaceModifyOperation op = new WorkspaceModifyOperation()
+            {
+                @Override
+                protected void execute( IProgressMonitor monitor ) throws CoreException
+                {
+                    n.getBundle().getBundleInfo().addImport( i );
+                    n.save( null );
+                }
+            };
+
+            SigilUI.runWorkspaceOperation( op, null );
+        }
+        catch ( ModelElementFactoryException e )
+        {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+
+    public String getAdditionalProposalInfo()
+    {
+        return null;
+    }
+
+
+    public IContextInformation getContextInformation()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public String getDisplayString()
+    {
+        return "Import package " + e.getPackageName() + " version " + e.getVersion() + " to bundle";
+    }
+
+
+    public Image getImage()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public Point getSelection( IDocument document )
+    {
+        return null;
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportQuickFixProcessor.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportQuickFixProcessor.java
index 18f37b8..00e7fdc 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportQuickFixProcessor.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportQuickFixProcessor.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.quickfix;
 
+
 import java.util.ArrayList;
 import java.util.HashMap;
 
@@ -48,206 +49,267 @@
 import org.eclipse.jdt.ui.text.java.IProblemLocation;
 import org.eclipse.jdt.ui.text.java.IQuickFixProcessor;
 
+
 @SuppressWarnings("restriction")
-public class ImportQuickFixProcessor implements IQuickFixProcessor {
+public class ImportQuickFixProcessor implements IQuickFixProcessor
+{
 
-	private static final Object SYNC_FLAG = new Object();
-	
-	public boolean hasCorrections(ICompilationUnit unit, int problemId) {
-		switch ( problemId ) {
-		case IProblem.ImportNotFound:
-		case IProblem.ForbiddenReference:
-		case IProblem.NotVisibleType:
-		case IProblem.UndefinedType:
-			return true;
-		default:
-			return false;
-		}
-	}
+    private static final Object SYNC_FLAG = new Object();
 
-	public IJavaCompletionProposal[] getCorrections(IInvocationContext context,
-			IProblemLocation[] locations) throws CoreException {
-		try {
-			HashMap<Object, IJavaCompletionProposal> results = new HashMap<Object, IJavaCompletionProposal>();
-			
-			ISigilProjectModel project = findProject(context);
-			
-			if ( project != null ) {
-				for ( int i = 0; i < locations.length; i++ ) {
-					switch ( locations[i].getProblemId() ) {
-					case IProblem.ForbiddenReference:
-						handleImportNotFound(project, context, locations[i], results);
-						break;
-					case IProblem.ImportNotFound:
-						handleImportNotFound(project, context, locations[i], results);
-						break;
-					case IProblem.IsClassPathCorrect:
-						handleIsClassPathCorrect(project, context, locations[i], results);
-						break;
-					case IProblem.UndefinedType:
-						handleUndefinedType(project, context, locations[i], results);
-						break;
-					case IProblem.UndefinedName:
-						handleUndefinedName(project, context, locations[i], results);
-						break;
-					}
-				}
-			}		
-			
-			return (IJavaCompletionProposal[])results.values().toArray(new IJavaCompletionProposal[results.size()]);
-		}
-		catch ( RuntimeException e ) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
 
-	private void handleUndefinedName(ISigilProjectModel project,
-			IInvocationContext context, IProblemLocation problem,
-			HashMap<Object, IJavaCompletionProposal> results) {
-		Name node = findNode(context, problem);
-		
-		if ( node == null ) {
-			return;
-		}
-		addSearchResults(node, project, results);
-	}
+    public boolean hasCorrections( ICompilationUnit unit, int problemId )
+    {
+        switch ( problemId )
+        {
+            case IProblem.ImportNotFound:
+            case IProblem.ForbiddenReference:
+            case IProblem.NotVisibleType:
+            case IProblem.UndefinedType:
+                return true;
+            default:
+                return false;
+        }
+    }
 
-	private void handleIsClassPathCorrect(ISigilProjectModel project, final IInvocationContext context,
-			IProblemLocation problemLocation,
-			final HashMap<Object, IJavaCompletionProposal> results) {
-		for ( final String type : problemLocation.getProblemArguments() ) {
-			final String iPackage = type.substring(0, type.lastIndexOf("."));
-			
-			for ( IPackageExport pe : JavaHelper.findExportsForPackage(project, iPackage) ) { 
-				results.put( type, new ImportPackageProposal( pe, project ) );
-			}
-		}
-		
-		if ( !results.containsKey(SYNC_FLAG) ) {
-			//results.put( SYNC_FLAG, null);
-		}
-	}
 
-	private void handleUndefinedType(ISigilProjectModel project, IInvocationContext context,
-			IProblemLocation problem,
-			HashMap<Object, IJavaCompletionProposal> results) throws CoreException {
-		Name node = findNode(context, problem);
-		
-		if ( node == null ) {
-			return;
-		}
-		addSearchResults(node, project, results);
-	}
+    public IJavaCompletionProposal[] getCorrections( IInvocationContext context, IProblemLocation[] locations )
+        throws CoreException
+    {
+        try
+        {
+            HashMap<Object, IJavaCompletionProposal> results = new HashMap<Object, IJavaCompletionProposal>();
 
-	private void handleImportNotFound(ISigilProjectModel project, final IInvocationContext context, IProblemLocation location, final HashMap<Object, IJavaCompletionProposal> results) throws CoreException {
-		ASTNode selectedNode= location.getCoveringNode(context.getASTRoot());
-		if (selectedNode == null) return;
-		
-		if ( selectedNode instanceof ClassInstanceCreation ) {
-			ClassInstanceCreation c = (ClassInstanceCreation) selectedNode;
-			Type t = c.getType();
-			Name node = findName( t );
-			if ( node != null ) {
-				addSearchResults(node, project, results);
-			}
-		}
-		else {
-			for ( final String iPackage : readPackage(selectedNode, location) ) {
-				if ( !results.containsKey(iPackage) ) {
-					for ( IPackageExport pe : JavaHelper.findExportsForPackage(project, iPackage) ) { 
-						results.put( iPackage, new ImportPackageProposal( pe, project ) );
-					}
-				}
-			}
-		}
-	}
+            ISigilProjectModel project = findProject( context );
 
-	private void addSearchResults(Name node, ISigilProjectModel project,
-			HashMap<Object, IJavaCompletionProposal> results) {
-		for ( ISearchResult result : SigilSearch.findProviders( node.getFullyQualifiedName(), project, null) ) {
-			if ( project.getBundle().findImport( result.getPackageName() ) == null ) {
-				String type = result.getPackageName() + "." + node.getFullyQualifiedName();
-				results.put( type, new ImportSearchResultProposal( SigilUI.getActiveWorkbenchShell(), result, node, project ) );
-			}
-		}		
-	}
+            if ( project != null )
+            {
+                for ( int i = 0; i < locations.length; i++ )
+                {
+                    switch ( locations[i].getProblemId() )
+                    {
+                        case IProblem.ForbiddenReference:
+                            handleImportNotFound( project, context, locations[i], results );
+                            break;
+                        case IProblem.ImportNotFound:
+                            handleImportNotFound( project, context, locations[i], results );
+                            break;
+                        case IProblem.IsClassPathCorrect:
+                            handleIsClassPathCorrect( project, context, locations[i], results );
+                            break;
+                        case IProblem.UndefinedType:
+                            handleUndefinedType( project, context, locations[i], results );
+                            break;
+                        case IProblem.UndefinedName:
+                            handleUndefinedName( project, context, locations[i], results );
+                            break;
+                    }
+                }
+            }
 
-	private Name findName(Type t) {
-		if ( t.isSimpleType() ) {
-			SimpleType st = (SimpleType) t;
-			return st.getName();
-		}
-		else if ( t.isArrayType() ) {
-			ArrayType at = (ArrayType) t;
-			return findName(at.getElementType());
-		}
-		else {
-			return null;
-		}
-	}
+            return ( IJavaCompletionProposal[] ) results.values().toArray( new IJavaCompletionProposal[results.size()] );
+        }
+        catch ( RuntimeException e )
+        {
+            e.printStackTrace();
+            throw e;
+        }
+    }
 
-	private Name findNode(IInvocationContext context, IProblemLocation problem) {
-		ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
-		if (selectedNode == null) {
-			return null;
-		}
 
-		while (selectedNode.getLocationInParent() == QualifiedName.NAME_PROPERTY) {
-			selectedNode= selectedNode.getParent();
-		}
+    private void handleUndefinedName( ISigilProjectModel project, IInvocationContext context, IProblemLocation problem,
+        HashMap<Object, IJavaCompletionProposal> results )
+    {
+        Name node = findNode( context, problem );
 
-		Name node= null;
-		
-		if (selectedNode instanceof Type) {
-			node = findName( (Type) selectedNode );
-		} else if (selectedNode instanceof Name) {
-			node= (Name) selectedNode;
-		}
-		
-		return node;
-	}
+        if ( node == null )
+        {
+            return;
+        }
+        addSearchResults( node, project, results );
+    }
 
-	private ISigilProjectModel findProject(IInvocationContext context) throws CoreException {
-		IProject project = context.getCompilationUnit().getJavaProject().getProject();
-		if ( project.hasNature( SigilCore.NATURE_ID ) ) {
-			return SigilCore.create(project);
-		}
-		else {
-			return null;
-		}
-	}
 
-	private String[] readPackage(ASTNode selectedNode, IProblemLocation location) {
-		ArrayList<String> packages = new ArrayList<String>();
-		
-		ImportDeclaration id = (ImportDeclaration) ASTNodes.getParent(selectedNode, ASTNode.IMPORT_DECLARATION);
+    private void handleIsClassPathCorrect( ISigilProjectModel project, final IInvocationContext context,
+        IProblemLocation problemLocation, final HashMap<Object, IJavaCompletionProposal> results )
+    {
+        for ( final String type : problemLocation.getProblemArguments() )
+        {
+            final String iPackage = type.substring( 0, type.lastIndexOf( "." ) );
 
-		if ( id == null ) {
-			MethodInvocation m = (MethodInvocation) ASTNodes.getParent(selectedNode, ASTNode.METHOD_INVOCATION);
+            for ( IPackageExport pe : JavaHelper.findExportsForPackage( project, iPackage ) )
+            {
+                results.put( type, new ImportPackageProposal( pe, project ) );
+            }
+        }
 
-			if (m != null) {
-				packages.add( readPackage( m ) );
-				while ( m.getExpression() != null && m.getExpression() instanceof MethodInvocation) {
-					m = (MethodInvocation) m.getExpression();
-					packages.add( readPackage( m ) );
-				}
-			}
-		}
-		else {
-			if ( id.isOnDemand() ) {
-				packages.add(id.getName().toString());
-			}
-			else {
-				String iStr = id.getName().toString();
-				packages.add(iStr.substring(0, iStr.lastIndexOf( "." ) ));
-			}
-		}
-		
-		return packages.toArray( new String[packages.size()] );
-	}
+        if ( !results.containsKey( SYNC_FLAG ) )
+        {
+            //results.put( SYNC_FLAG, null);
+        }
+    }
 
-	private String readPackage(MethodInvocation m) {
-		return m.resolveMethodBinding().getDeclaringClass().getPackage().getName();
-	}
+
+    private void handleUndefinedType( ISigilProjectModel project, IInvocationContext context, IProblemLocation problem,
+        HashMap<Object, IJavaCompletionProposal> results ) throws CoreException
+    {
+        Name node = findNode( context, problem );
+
+        if ( node == null )
+        {
+            return;
+        }
+        addSearchResults( node, project, results );
+    }
+
+
+    private void handleImportNotFound( ISigilProjectModel project, final IInvocationContext context,
+        IProblemLocation location, final HashMap<Object, IJavaCompletionProposal> results ) throws CoreException
+    {
+        ASTNode selectedNode = location.getCoveringNode( context.getASTRoot() );
+        if ( selectedNode == null )
+            return;
+
+        if ( selectedNode instanceof ClassInstanceCreation )
+        {
+            ClassInstanceCreation c = ( ClassInstanceCreation ) selectedNode;
+            Type t = c.getType();
+            Name node = findName( t );
+            if ( node != null )
+            {
+                addSearchResults( node, project, results );
+            }
+        }
+        else
+        {
+            for ( final String iPackage : readPackage( selectedNode, location ) )
+            {
+                if ( !results.containsKey( iPackage ) )
+                {
+                    for ( IPackageExport pe : JavaHelper.findExportsForPackage( project, iPackage ) )
+                    {
+                        results.put( iPackage, new ImportPackageProposal( pe, project ) );
+                    }
+                }
+            }
+        }
+    }
+
+
+    private void addSearchResults( Name node, ISigilProjectModel project,
+        HashMap<Object, IJavaCompletionProposal> results )
+    {
+        for ( ISearchResult result : SigilSearch.findProviders( node.getFullyQualifiedName(), project, null ) )
+        {
+            if ( project.getBundle().findImport( result.getPackageName() ) == null )
+            {
+                String type = result.getPackageName() + "." + node.getFullyQualifiedName();
+                results.put( type, new ImportSearchResultProposal( SigilUI.getActiveWorkbenchShell(), result, node,
+                    project ) );
+            }
+        }
+    }
+
+
+    private Name findName( Type t )
+    {
+        if ( t.isSimpleType() )
+        {
+            SimpleType st = ( SimpleType ) t;
+            return st.getName();
+        }
+        else if ( t.isArrayType() )
+        {
+            ArrayType at = ( ArrayType ) t;
+            return findName( at.getElementType() );
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    private Name findNode( IInvocationContext context, IProblemLocation problem )
+    {
+        ASTNode selectedNode = problem.getCoveringNode( context.getASTRoot() );
+        if ( selectedNode == null )
+        {
+            return null;
+        }
+
+        while ( selectedNode.getLocationInParent() == QualifiedName.NAME_PROPERTY )
+        {
+            selectedNode = selectedNode.getParent();
+        }
+
+        Name node = null;
+
+        if ( selectedNode instanceof Type )
+        {
+            node = findName( ( Type ) selectedNode );
+        }
+        else if ( selectedNode instanceof Name )
+        {
+            node = ( Name ) selectedNode;
+        }
+
+        return node;
+    }
+
+
+    private ISigilProjectModel findProject( IInvocationContext context ) throws CoreException
+    {
+        IProject project = context.getCompilationUnit().getJavaProject().getProject();
+        if ( project.hasNature( SigilCore.NATURE_ID ) )
+        {
+            return SigilCore.create( project );
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    private String[] readPackage( ASTNode selectedNode, IProblemLocation location )
+    {
+        ArrayList<String> packages = new ArrayList<String>();
+
+        ImportDeclaration id = ( ImportDeclaration ) ASTNodes.getParent( selectedNode, ASTNode.IMPORT_DECLARATION );
+
+        if ( id == null )
+        {
+            MethodInvocation m = ( MethodInvocation ) ASTNodes.getParent( selectedNode, ASTNode.METHOD_INVOCATION );
+
+            if ( m != null )
+            {
+                packages.add( readPackage( m ) );
+                while ( m.getExpression() != null && m.getExpression() instanceof MethodInvocation )
+                {
+                    m = ( MethodInvocation ) m.getExpression();
+                    packages.add( readPackage( m ) );
+                }
+            }
+        }
+        else
+        {
+            if ( id.isOnDemand() )
+            {
+                packages.add( id.getName().toString() );
+            }
+            else
+            {
+                String iStr = id.getName().toString();
+                packages.add( iStr.substring( 0, iStr.lastIndexOf( "." ) ) );
+            }
+        }
+
+        return packages.toArray( new String[packages.size()] );
+    }
+
+
+    private String readPackage( MethodInvocation m )
+    {
+        return m.resolveMethodBinding().getDeclaringClass().getPackage().getName();
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportSearchResultProposal.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportSearchResultProposal.java
index 4d0e289..9ea358e 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportSearchResultProposal.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportSearchResultProposal.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.quickfix;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.apache.felix.sigil.model.ModelElementFactory;
@@ -50,107 +51,140 @@
 import org.eclipse.ui.actions.WorkspaceModifyOperation;
 import org.osgi.framework.Version;
 
-public class ImportSearchResultProposal implements IJavaCompletionProposal {
 
-	private ISigilProjectModel project;
-	private ICompilationUnit fCompilationUnit;
-	private final ISearchResult result;
-	private final Shell shell;
-	
-	public ImportSearchResultProposal(Shell shell, ISearchResult result, Name node, ISigilProjectModel project) {
-		this.shell = shell;
-		this.result = result;
-		this.project = project;
-		if ( node != null ) {
-			CompilationUnit cu = (CompilationUnit) ASTNodes.getParent(node, ASTNode.COMPILATION_UNIT);
-			this.fCompilationUnit = (ICompilationUnit) cu.getJavaElement();
-		}
-	}
+public class ImportSearchResultProposal implements IJavaCompletionProposal
+{
 
-	public int getRelevance() {
-		return 100;
-	}
+    private ISigilProjectModel project;
+    private ICompilationUnit fCompilationUnit;
+    private final ISearchResult result;
+    private final Shell shell;
 
-	public void apply(IDocument document) {
-		IPackageExport e = result.getExport();
-		if ( result.getExport() == null ) {
-			if ( MessageDialog.openQuestion(shell, "Modify " + result.getProvider().getBundleInfo().getSymbolicName(), result.getPackageName() + " is not exported. Do you want to export it now?" ) ) {
-				final IPackageExport pe = ModelElementFactory.getInstance().newModelElement(IPackageExport.class);
-				pe.setPackageName(result.getPackageName());
-				//e.setVersion(version)
-				final ISigilProjectModel mod = result.getProvider().getAncestor(ISigilProjectModel.class);
-				if ( mod == null ) {
-					throw new IllegalStateException( "Attempt to modify binary package export" );
-				}
-				WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
-					@Override
-					protected void execute(IProgressMonitor monitor)
-					throws CoreException {
-						mod.getBundle().getBundleInfo().addExport(pe);
-						mod.save(null);
-					}
-				};
 
-				SigilUI.runWorkspaceOperation(op, null);
-				e = pe;
-			}
-		}
+    public ImportSearchResultProposal( Shell shell, ISearchResult result, Name node, ISigilProjectModel project )
+    {
+        this.shell = shell;
+        this.result = result;
+        this.project = project;
+        if ( node != null )
+        {
+            CompilationUnit cu = ( CompilationUnit ) ASTNodes.getParent( node, ASTNode.COMPILATION_UNIT );
+            this.fCompilationUnit = ( ICompilationUnit ) cu.getJavaElement();
+        }
+    }
 
-		final IPackageImport i = ModelElementFactory.getInstance().newModelElement(IPackageImport.class);
-		i.setPackageName(e.getPackageName());
-		IPreferenceStore store = SigilCore.getDefault().getPreferenceStore();
-		VersionRangeBoundingRule lowerBoundRule = VersionRangeBoundingRule.valueOf(store.getString(SigilCore.DEFAULT_VERSION_LOWER_BOUND));
-		VersionRangeBoundingRule upperBoundRule = VersionRangeBoundingRule.valueOf(store.getString(SigilCore.DEFAULT_VERSION_UPPER_BOUND));
 
-		Version version = e.getVersion();
-		VersionRange selectedVersions = VersionRange.newInstance(version, lowerBoundRule, upperBoundRule);
-		i.setVersions( selectedVersions );
+    public int getRelevance()
+    {
+        return 100;
+    }
 
-		WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
-			@Override
-			protected void execute(IProgressMonitor monitor)
-			throws CoreException {
-				project.getBundle().getBundleInfo().addImport( i );
-				project.save(null);
-			}
-		};
 
-		SigilUI.runWorkspaceOperation(op, null);
-		addSourceImport();
-	}
+    public void apply( IDocument document )
+    {
+        IPackageExport e = result.getExport();
+        if ( result.getExport() == null )
+        {
+            if ( MessageDialog.openQuestion( shell, "Modify " + result.getProvider().getBundleInfo().getSymbolicName(),
+                result.getPackageName() + " is not exported. Do you want to export it now?" ) )
+            {
+                final IPackageExport pe = ModelElementFactory.getInstance().newModelElement( IPackageExport.class );
+                pe.setPackageName( result.getPackageName() );
+                //e.setVersion(version)
+                final ISigilProjectModel mod = result.getProvider().getAncestor( ISigilProjectModel.class );
+                if ( mod == null )
+                {
+                    throw new IllegalStateException( "Attempt to modify binary package export" );
+                }
+                WorkspaceModifyOperation op = new WorkspaceModifyOperation()
+                {
+                    @Override
+                    protected void execute( IProgressMonitor monitor ) throws CoreException
+                    {
+                        mod.getBundle().getBundleInfo().addExport( pe );
+                        mod.save( null );
+                    }
+                };
 
-	private void addSourceImport() {
-		// add import
-		try {
-			ImportRewrite rewrite= CodeStyleConfiguration.createImportRewrite(fCompilationUnit, true);
-			rewrite.addImport(result.getClassName());
-			JavaModelUtil.applyEdit(fCompilationUnit, rewrite.rewriteImports(null), false, null);
-		} catch (CoreException e) {
-			SigilCore.error( "Failed to add import", e);
-		}
-	}
+                SigilUI.runWorkspaceOperation( op, null );
+                e = pe;
+            }
+        }
 
-	public String getAdditionalProposalInfo() {
-		return null;
-	}
+        final IPackageImport i = ModelElementFactory.getInstance().newModelElement( IPackageImport.class );
+        i.setPackageName( e.getPackageName() );
+        IPreferenceStore store = SigilCore.getDefault().getPreferenceStore();
+        VersionRangeBoundingRule lowerBoundRule = VersionRangeBoundingRule.valueOf( store
+            .getString( SigilCore.DEFAULT_VERSION_LOWER_BOUND ) );
+        VersionRangeBoundingRule upperBoundRule = VersionRangeBoundingRule.valueOf( store
+            .getString( SigilCore.DEFAULT_VERSION_UPPER_BOUND ) );
 
-	public IContextInformation getContextInformation() {
-		// TODO Auto-generated method stub
-		return null;
-	}
-	
-	public String getDisplayString() {
-		String type = result.getClassName();
-		String loc = result.getExport() == null ? " from " + result.getProvider().getBundleInfo().getSymbolicName() : " version " + result.getExport().getVersion();
-		return "Import " + type + loc;
-	}
+        Version version = e.getVersion();
+        VersionRange selectedVersions = VersionRange.newInstance( version, lowerBoundRule, upperBoundRule );
+        i.setVersions( selectedVersions );
 
-	public Image getImage() {
-		// TODO Auto-generated method stub
-		return null;
-	}
+        WorkspaceModifyOperation op = new WorkspaceModifyOperation()
+        {
+            @Override
+            protected void execute( IProgressMonitor monitor ) throws CoreException
+            {
+                project.getBundle().getBundleInfo().addImport( i );
+                project.save( null );
+            }
+        };
 
-	public Point getSelection(IDocument document) {
-		return null;
-	}
+        SigilUI.runWorkspaceOperation( op, null );
+        addSourceImport();
+    }
+
+
+    private void addSourceImport()
+    {
+        // add import
+        try
+        {
+            ImportRewrite rewrite = CodeStyleConfiguration.createImportRewrite( fCompilationUnit, true );
+            rewrite.addImport( result.getClassName() );
+            JavaModelUtil.applyEdit( fCompilationUnit, rewrite.rewriteImports( null ), false, null );
+        }
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Failed to add import", e );
+        }
+    }
+
+
+    public String getAdditionalProposalInfo()
+    {
+        return null;
+    }
+
+
+    public IContextInformation getContextInformation()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public String getDisplayString()
+    {
+        String type = result.getClassName();
+        String loc = result.getExport() == null ? " from " + result.getProvider().getBundleInfo().getSymbolicName()
+            : " version " + result.getExport().getVersion();
+        return "Import " + type + loc;
+    }
+
+
+    public Image getImage()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    public Point getSelection( IDocument document )
+    {
+        return null;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportedClassReference.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportedClassReference.java
index ca234ec..7b28a64 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportedClassReference.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/quickfix/ImportedClassReference.java
@@ -19,22 +19,31 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.quickfix;
 
+
 import org.apache.felix.sigil.model.osgi.IPackageImport;
 
-public class ImportedClassReference {
-	private IPackageImport pi;
-	private String type;
-	
-	public ImportedClassReference(IPackageImport packageImport, String typeName) {
-		this.pi = packageImport;
-		this.type = typeName;
-	}
 
-	public IPackageImport getPackageImport() {
-		return pi;
-	}
+public class ImportedClassReference
+{
+    private IPackageImport pi;
+    private String type;
 
-	public String getFullType() {
-		return type;
-	}
+
+    public ImportedClassReference( IPackageImport packageImport, String typeName )
+    {
+        this.pi = packageImport;
+        this.type = typeName;
+    }
+
+
+    public IPackageImport getPackageImport()
+    {
+        return pi;
+    }
+
+
+    public String getFullType()
+    {
+        return type;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/refactor/RenameCompositeRefactoring.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/refactor/RenameCompositeRefactoring.java
index 962f82c..ca2c2b7 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/refactor/RenameCompositeRefactoring.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/refactor/RenameCompositeRefactoring.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.refactor;
 
+
 import java.util.Map;
 
 import org.eclipse.core.runtime.CoreException;
@@ -28,32 +29,40 @@
 import org.eclipse.ltk.core.refactoring.Refactoring;
 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
 
-public class RenameCompositeRefactoring extends Refactoring {
 
-	@Override
-	public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException,
-			OperationCanceledException {
-		// TODO Auto-generated method stub
-		return null;
-	}
+public class RenameCompositeRefactoring extends Refactoring
+{
 
-	@Override
-	public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException,
-			OperationCanceledException {
-		// TODO Auto-generated method stub
-		return null;
-	}
+    @Override
+    public RefactoringStatus checkFinalConditions( IProgressMonitor pm ) throws CoreException,
+        OperationCanceledException
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
 
-	@Override
-	public Change createChange(IProgressMonitor pm) throws CoreException,
-			OperationCanceledException {
-		// TODO Auto-generated method stub
-		return null;
-	}
 
-	@Override
-	public String getName() {
-		// TODO Auto-generated method stub
-		return null;
-	}
+    @Override
+    public RefactoringStatus checkInitialConditions( IProgressMonitor pm ) throws CoreException,
+        OperationCanceledException
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    @Override
+    public Change createChange( IProgressMonitor pm ) throws CoreException, OperationCanceledException
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+
+    @Override
+    public String getName()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/AccumulatorAdapter.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/AccumulatorAdapter.java
index 309d549..421af3f 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/AccumulatorAdapter.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/AccumulatorAdapter.java
@@ -19,16 +19,22 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import java.util.Collection;
 import java.util.LinkedList;
 
-public abstract class AccumulatorAdapter<E> implements IAccumulator<E> {
-	public void addElement(E element) {
-		LinkedList<E> list = new LinkedList<E>();
-		list.add(element);
-		addElements(list);
-	};
-	
-	public void addElements(Collection<? extends E> elements) {
-	}
+
+public abstract class AccumulatorAdapter<E> implements IAccumulator<E>
+{
+    public void addElement( E element )
+    {
+        LinkedList<E> list = new LinkedList<E>();
+        list.add( element );
+        addElements( list );
+    };
+
+
+    public void addElements( Collection<? extends E> elements )
+    {
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/BackgroundLoadingSelectionDialog.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/BackgroundLoadingSelectionDialog.java
index e22b620..ce025ee 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/BackgroundLoadingSelectionDialog.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/BackgroundLoadingSelectionDialog.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -72,416 +73,562 @@
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.progress.IJobRunnable;
 
-public class BackgroundLoadingSelectionDialog<E> extends TitleAreaDialog implements IAccumulator<E> {
 
-	private final ILabelProvider DEFAULT_LABEL_PROVIDER = new LabelProvider() {
-		@SuppressWarnings("unchecked")
-		public String getText(Object element) {
-			String result;
-			if(element instanceof WrappedContentProposal<?>) {
-				WrappedContentProposal<E> contentProposal = (WrappedContentProposal<E>) element;
-				result = contentProposal.getLabel();
-			} else {
-				result = descriptor.getLabel((E) element);
-			}
-			return result;
-		}
-	};
+public class BackgroundLoadingSelectionDialog<E> extends TitleAreaDialog implements IAccumulator<E>
+{
 
-	private final IElementDescriptor<E> DEFAULT_DESCRIPTOR = new IElementDescriptor<E>() {
-		public String getLabel(E element) {
-			return getName(element);
-		}
-		public String getName(E element) {
-			return element == null ? "null" : element.toString();
-		}
-	};
-	
-	private final String selectionLabel;
-	private IFilter<? super E> filter;
-	private IElementDescriptor<? super E> descriptor = DEFAULT_DESCRIPTOR;
-	private ILabelProvider labelProvider = DEFAULT_LABEL_PROVIDER;
-	private final boolean multi;
-	
-	private final List<E> elements;
-	
-	private List<E> selection = null;
-	private String selectedName = null;
-	
-	private TableViewer viewer = null;
-	private Comparator<? super E> comparator;
-	
-	private HashMap<String, IJobRunnable> background = new HashMap<String, IJobRunnable>(); 
-	
-	public BackgroundLoadingSelectionDialog(Shell parentShell, String selectionLabel, boolean multi) {
-		super(parentShell);
-		elements = new ArrayList<E>();		
-		this.selectionLabel = selectionLabel;
-		this.multi = multi;
-	}
-	
-	public void setFilter(IFilter<? super E> filter) {
-		this.filter = filter;		
-	}
-	
-	public void setDescriptor(final IElementDescriptor<? super E> descriptor) {
-		if(descriptor != null) {
-			this.descriptor = descriptor;
-		} else {
-			this.descriptor = DEFAULT_DESCRIPTOR;
-		}
-	}
-	
-	public IElementDescriptor<? super E> getDescriptor() {
-		return descriptor;
-	}
+    private final ILabelProvider DEFAULT_LABEL_PROVIDER = new LabelProvider()
+    {
+        @SuppressWarnings("unchecked")
+        public String getText( Object element )
+        {
+            String result;
+            if ( element instanceof WrappedContentProposal<?> )
+            {
+                WrappedContentProposal<E> contentProposal = ( WrappedContentProposal<E> ) element;
+                result = contentProposal.getLabel();
+            }
+            else
+            {
+                result = descriptor.getLabel( ( E ) element );
+            }
+            return result;
+        }
+    };
 
-	public void setComparator(Comparator<? super E> comparator) {
-		this.comparator = comparator;		
-	}
-	
-	public void setLabelProvider(ILabelProvider labelProvider) {
-		if(labelProvider != null) {
-			this.labelProvider = labelProvider;
-		} else {
-			this.labelProvider = DEFAULT_LABEL_PROVIDER;
-		}
-	}
-	
-	public void addBackgroundJob(String name, IJobRunnable job) {
-		background.put(name, job);
-	}
-	
-	@Override
-	public int open() {
-		Job[] jobs = scheduleJobs();
-		try {
-			return super.open();
-		}
-		finally {
-			for ( Job j : jobs ) {
-				j.cancel();
-			}
-		}
-	}
+    private final IElementDescriptor<E> DEFAULT_DESCRIPTOR = new IElementDescriptor<E>()
+    {
+        public String getLabel( E element )
+        {
+            return getName( element );
+        }
 
-	private Job[] scheduleJobs() {
-		if ( background.isEmpty() ) {
-			return new Job[] {};
-		}
-		else {
-			ArrayList<Job> jobs = new ArrayList<Job>(background.size()); 
-			for ( Map.Entry<String, IJobRunnable> e : background.entrySet() ) {
-				final IJobRunnable run = e.getValue();
-				Job job = new Job(e.getKey()) {
-					@Override
-					protected IStatus run(IProgressMonitor monitor) {
-						return run.run(monitor);
-					}
-				};				
-				job.schedule();
-			}
-			
-			return jobs.toArray( new Job[jobs.size()] );
-		}
-	}
 
-	@Override
-	protected Control createDialogArea(Composite parent) {
-		// Create Controls
-		Composite container = (Composite) super.createDialogArea(parent);
-		Composite composite = new Composite(container, SWT.NONE);
-		
-		new Label(composite, SWT.NONE).setText(selectionLabel);
-		
-		ContentProposalAdapter proposalAdapter = null;
-		Text txtSelection = null;
-		
-		Table table = null;
-		if(multi) {
-			table = new Table(composite, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
-			viewer = new TableViewer(table);
-			viewer.setContentProvider(new ArrayContentProvider());
-			viewer.addFilter(new ViewerFilter() {
-				public boolean select(Viewer viewer, Object parentElement, Object element) {
-					@SuppressWarnings("unchecked") E castedElement = (E) element;
-					return filter == null || filter.select(castedElement);
-				}
-			});
-			if(comparator != null) {
-				viewer.setSorter(new ViewerSorter() {
-					@Override
-					public int compare(Viewer viewer, Object o1, Object o2) {
-						@SuppressWarnings("unchecked")
-						E e1 = (E) o1;
-						@SuppressWarnings("unchecked")
-						E e2 = (E) o2;
-						return comparator.compare(e1, e2);
-					}
-				});
-			}
-			synchronized (elements) {
-				viewer.setInput(elements);
-			}
-			
-			if(labelProvider != null) {
-				viewer.setLabelProvider(labelProvider);
-			}
-		} else {
-			txtSelection = new Text(composite, SWT.BORDER);
-			ControlDecoration selectionDecor = new ControlDecoration(txtSelection, SWT.LEFT | SWT.TOP);
-			FieldDecoration proposalDecor = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_CONTENT_PROPOSAL);
-			selectionDecor.setImage(proposalDecor.getImage());
-			selectionDecor.setDescriptionText(proposalDecor.getDescription());
-			
-			ExclusionContentProposalProvider<E> proposalProvider = new ExclusionContentProposalProvider<E>(elements, filter, descriptor);
-			
-			proposalAdapter = new ContentProposalAdapter(txtSelection, new TextContentAdapter(), proposalProvider, null, null);
-			proposalAdapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
-			if(labelProvider != null) {
-				proposalAdapter.setLabelProvider(labelProvider);
-			}
-			
-			if(selectedName != null) {
-				txtSelection.setText(selectedName);
-			}
-		}
-		updateSelection();
-		updateButtons();
-		
-		// Hookup listeners
-		if(proposalAdapter != null) {
-			proposalAdapter.addContentProposalListener(new IContentProposalListener() {
-				public void proposalAccepted(IContentProposal proposal) {
-					@SuppressWarnings("unchecked")
-					WrappedContentProposal<E> valueProposal = (WrappedContentProposal<E>) proposal;
-					E selected = valueProposal.getElement();
-					selection = new ArrayList<E>(1);
-					selection.add(selected);
-					
-					elementSelected(selected);
-					
-					updateButtons();
-				}
-			});
-		}
-		if(txtSelection != null) {
-			txtSelection.addModifyListener(new ModifyListener() {
-				public void modifyText(ModifyEvent e) {
-					selectedName = ((Text) e.widget).getText();
-					updateButtons();
-				}
-			});
-		}
-		if(viewer != null) {
-			viewer.addSelectionChangedListener(new ISelectionChangedListener() {
-				public void selectionChanged(SelectionChangedEvent event) {
-					IStructuredSelection sel = (IStructuredSelection) event.getSelection();
-					selection = new ArrayList<E>(sel.size());
-					for(Iterator<?> iter = sel.iterator(); iter.hasNext(); ) {
-						@SuppressWarnings("unchecked")
-						E element = (E) iter.next();
-						selection.add(element);
-					}
-					updateButtons();
-				}
-			});
-			viewer.addOpenListener(new IOpenListener() {
-				public void open(OpenEvent event) {
-					if(canComplete()) {
-						setReturnCode(IDialogConstants.OK_ID);
-						close();
-					}
-				}
-			});
-		}
-		
-		// Layout
-		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		if(multi) {
-			composite.setLayout(new GridLayout(1, false));
-			GridData layoutTable = new GridData(SWT.FILL, SWT.FILL, true, true);
-			layoutTable.heightHint = 200;
-			table.setLayoutData(layoutTable);
-		} else {
-			composite.setLayout(new GridLayout(2, false));
-			txtSelection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		}
+        public String getName( E element )
+        {
+            return element == null ? "null" : element.toString();
+        }
+    };
 
-		return container;
-	}
-	
-	protected void elementSelected(E selection) {
-	}
-	
-	@Override
-	protected Control createButtonBar(Composite parent) {
-		Control bar = super.createButtonBar(parent);
-		updateButtons();
-		return bar;
-	}
+    private final String selectionLabel;
+    private IFilter<? super E> filter;
+    private IElementDescriptor<? super E> descriptor = DEFAULT_DESCRIPTOR;
+    private ILabelProvider labelProvider = DEFAULT_LABEL_PROVIDER;
+    private final boolean multi;
 
-	/**
-	 * Can be called from any thread
-	 */
-	protected final void updateButtons() {
-		Runnable updateButtonsRunnable = new Runnable() {
-			public void run() {
-				Shell shell = getShell();
-				if(shell != null && !shell.isDisposed()) {
-					Button okButton = getButton(IDialogConstants.OK_ID);
-					if(okButton != null && !okButton.isDisposed()) {
-						okButton.setEnabled(canComplete());
-					}
-				}
-			}
-		};
-		Shell shell = getShell();
-		if (shell != null) {
-			onUIThread(shell, updateButtonsRunnable);
-		}
-	}
-	
-	/**
-	 * Subclasses may override but must call super.canComplete
-	 * @return
-	 */
-	protected synchronized boolean canComplete() {
-		boolean result = false;
-		
-		if ( selection != null ) {
-			if(multi) {
-				result = selection.size() > 0;
-			} else {
-				E sel = getSelectedElement();
-				result = sel != null && descriptor.getName(sel).equals(selectedName);
-			}
-		}
-		
-		return result;
-	}
-	
-	public final void addElement(E added) {
-		addElements(Collections.singleton(added));
-	}
-	
-	/**
-	 * Can be called from any thread
-	 */
-	public final void addElements(Collection<? extends E> added) {
-		final LinkedList<E> toAdd = new LinkedList<E>();
-		synchronized (elements) {
-			for ( E e : added ) {
-				if ( !elements.contains(e) ) {
-					elements.add( e );
-					toAdd.add(e);
-				}
-			}
-			Collections.sort(elements, comparator);
-		}
-		if(viewer != null) {
-			onUIThread(viewer.getControl(), new Runnable() {
-				public void run() {
-					if(!viewer.getControl().isDisposed()) {
-						viewer.add( toAdd.toArray() );
-						viewer.refresh();
-					}
-				}
-			});
-		}
-		else {
-			
-		}
-		updateSelection();
-		updateButtons();
-	}
+    private final List<E> elements;
 
-	protected void updateSelection() {
-		onUIThread(getShell(), new Runnable() {
-			public void run() {
-				if(selectedName != null) {
-					ArrayList<E> newSelection = new ArrayList<E>();
-					synchronized (elements) {
-						for (E e : elements) {
-							if(selectedName.equals(descriptor.getName(e))) {
-								newSelection.add(e);
-								break;
-							}
-						}
-					}
-					selection = newSelection;
-				}
-				else {
-					selection = Collections.emptyList();
-				}
-				if(viewer != null && !viewer.getControl().isDisposed()) {
-					viewer.setSelection(selection.isEmpty() ? StructuredSelection.EMPTY : new StructuredSelection(selection));
-				}
-			}
-		});			
-	}
+    private List<E> selection = null;
+    private String selectedName = null;
 
-	private static final void onUIThread(Control control, Runnable r) {
-		if(control != null && !control.isDisposed()) {
-			try {
-				Display display = control.getDisplay();
-				if(Thread.currentThread() == display.getThread()) {
-					// We are on the UI thread already, just do the work
-					r.run();
-				} else {
-					// Not on the UI thread, need to bung over the runnable
-					display.asyncExec(r);
-				}
-			}
-			catch (SWTError e) {
-				if ( e.code == SWT.ERROR_WIDGET_DISPOSED ) {
-					// ignore
-				}
-				else {
-					throw e;
-				}
-			}
-		}
-	}
-	
-	public String getSelectedName() {
-		return selectedName;
-	}
-	
-	public void setSelectedName(String selectedName) {
-		this.selectedName = selectedName;
-		boolean change = false;
-		if ( selectedName == null ) {
-			if ( selection != null && !selection.isEmpty() ) {
-				change = true;
-			}
-		}
-		else {
-			if ( selection == null ) {
-				change = true;
-			}
-			else if ( selection.size() != 1 || !descriptor.getLabel(selection.get(0)).equals(selectedName)) {
-				change = true;				
-			}
-		}
-		
-		if ( change ) {
-			updateSelection();
-			updateButtons();
-		}
-	}
-	
-	public List<E> getSelectedElements() {
-		return selection;
-	}
-	
-	public E getSelectedElement() {
-		E result;
-		if(selection == null || selection.isEmpty()) {
-			result = null;
-		} else {
-			result = selection.get(0);
-		}
-		return result;
-	}
+    private TableViewer viewer = null;
+    private Comparator<? super E> comparator;
+
+    private HashMap<String, IJobRunnable> background = new HashMap<String, IJobRunnable>();
+
+
+    public BackgroundLoadingSelectionDialog( Shell parentShell, String selectionLabel, boolean multi )
+    {
+        super( parentShell );
+        elements = new ArrayList<E>();
+        this.selectionLabel = selectionLabel;
+        this.multi = multi;
+    }
+
+
+    public void setFilter( IFilter<? super E> filter )
+    {
+        this.filter = filter;
+    }
+
+
+    public void setDescriptor( final IElementDescriptor<? super E> descriptor )
+    {
+        if ( descriptor != null )
+        {
+            this.descriptor = descriptor;
+        }
+        else
+        {
+            this.descriptor = DEFAULT_DESCRIPTOR;
+        }
+    }
+
+
+    public IElementDescriptor<? super E> getDescriptor()
+    {
+        return descriptor;
+    }
+
+
+    public void setComparator( Comparator<? super E> comparator )
+    {
+        this.comparator = comparator;
+    }
+
+
+    public void setLabelProvider( ILabelProvider labelProvider )
+    {
+        if ( labelProvider != null )
+        {
+            this.labelProvider = labelProvider;
+        }
+        else
+        {
+            this.labelProvider = DEFAULT_LABEL_PROVIDER;
+        }
+    }
+
+
+    public void addBackgroundJob( String name, IJobRunnable job )
+    {
+        background.put( name, job );
+    }
+
+
+    @Override
+    public int open()
+    {
+        Job[] jobs = scheduleJobs();
+        try
+        {
+            return super.open();
+        }
+        finally
+        {
+            for ( Job j : jobs )
+            {
+                j.cancel();
+            }
+        }
+    }
+
+
+    private Job[] scheduleJobs()
+    {
+        if ( background.isEmpty() )
+        {
+            return new Job[]
+                {};
+        }
+        else
+        {
+            ArrayList<Job> jobs = new ArrayList<Job>( background.size() );
+            for ( Map.Entry<String, IJobRunnable> e : background.entrySet() )
+            {
+                final IJobRunnable run = e.getValue();
+                Job job = new Job( e.getKey() )
+                {
+                    @Override
+                    protected IStatus run( IProgressMonitor monitor )
+                    {
+                        return run.run( monitor );
+                    }
+                };
+                job.schedule();
+            }
+
+            return jobs.toArray( new Job[jobs.size()] );
+        }
+    }
+
+
+    @Override
+    protected Control createDialogArea( Composite parent )
+    {
+        // Create Controls
+        Composite container = ( Composite ) super.createDialogArea( parent );
+        Composite composite = new Composite( container, SWT.NONE );
+
+        new Label( composite, SWT.NONE ).setText( selectionLabel );
+
+        ContentProposalAdapter proposalAdapter = null;
+        Text txtSelection = null;
+
+        Table table = null;
+        if ( multi )
+        {
+            table = new Table( composite, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER );
+            viewer = new TableViewer( table );
+            viewer.setContentProvider( new ArrayContentProvider() );
+            viewer.addFilter( new ViewerFilter()
+            {
+                public boolean select( Viewer viewer, Object parentElement, Object element )
+                {
+                    @SuppressWarnings("unchecked")
+                    E castedElement = ( E ) element;
+                    return filter == null || filter.select( castedElement );
+                }
+            } );
+            if ( comparator != null )
+            {
+                viewer.setSorter( new ViewerSorter()
+                {
+                    @Override
+                    public int compare( Viewer viewer, Object o1, Object o2 )
+                    {
+                        @SuppressWarnings("unchecked")
+                        E e1 = ( E ) o1;
+                        @SuppressWarnings("unchecked")
+                        E e2 = ( E ) o2;
+                        return comparator.compare( e1, e2 );
+                    }
+                } );
+            }
+            synchronized ( elements )
+            {
+                viewer.setInput( elements );
+            }
+
+            if ( labelProvider != null )
+            {
+                viewer.setLabelProvider( labelProvider );
+            }
+        }
+        else
+        {
+            txtSelection = new Text( composite, SWT.BORDER );
+            ControlDecoration selectionDecor = new ControlDecoration( txtSelection, SWT.LEFT | SWT.TOP );
+            FieldDecoration proposalDecor = FieldDecorationRegistry.getDefault().getFieldDecoration(
+                FieldDecorationRegistry.DEC_CONTENT_PROPOSAL );
+            selectionDecor.setImage( proposalDecor.getImage() );
+            selectionDecor.setDescriptionText( proposalDecor.getDescription() );
+
+            ExclusionContentProposalProvider<E> proposalProvider = new ExclusionContentProposalProvider<E>( elements,
+                filter, descriptor );
+
+            proposalAdapter = new ContentProposalAdapter( txtSelection, new TextContentAdapter(), proposalProvider,
+                null, null );
+            proposalAdapter.setProposalAcceptanceStyle( ContentProposalAdapter.PROPOSAL_REPLACE );
+            if ( labelProvider != null )
+            {
+                proposalAdapter.setLabelProvider( labelProvider );
+            }
+
+            if ( selectedName != null )
+            {
+                txtSelection.setText( selectedName );
+            }
+        }
+        updateSelection();
+        updateButtons();
+
+        // Hookup listeners
+        if ( proposalAdapter != null )
+        {
+            proposalAdapter.addContentProposalListener( new IContentProposalListener()
+            {
+                public void proposalAccepted( IContentProposal proposal )
+                {
+                    @SuppressWarnings("unchecked")
+                    WrappedContentProposal<E> valueProposal = ( WrappedContentProposal<E> ) proposal;
+                    E selected = valueProposal.getElement();
+                    selection = new ArrayList<E>( 1 );
+                    selection.add( selected );
+
+                    elementSelected( selected );
+
+                    updateButtons();
+                }
+            } );
+        }
+        if ( txtSelection != null )
+        {
+            txtSelection.addModifyListener( new ModifyListener()
+            {
+                public void modifyText( ModifyEvent e )
+                {
+                    selectedName = ( ( Text ) e.widget ).getText();
+                    updateButtons();
+                }
+            } );
+        }
+        if ( viewer != null )
+        {
+            viewer.addSelectionChangedListener( new ISelectionChangedListener()
+            {
+                public void selectionChanged( SelectionChangedEvent event )
+                {
+                    IStructuredSelection sel = ( IStructuredSelection ) event.getSelection();
+                    selection = new ArrayList<E>( sel.size() );
+                    for ( Iterator<?> iter = sel.iterator(); iter.hasNext(); )
+                    {
+                        @SuppressWarnings("unchecked")
+                        E element = ( E ) iter.next();
+                        selection.add( element );
+                    }
+                    updateButtons();
+                }
+            } );
+            viewer.addOpenListener( new IOpenListener()
+            {
+                public void open( OpenEvent event )
+                {
+                    if ( canComplete() )
+                    {
+                        setReturnCode( IDialogConstants.OK_ID );
+                        close();
+                    }
+                }
+            } );
+        }
+
+        // Layout
+        composite.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        if ( multi )
+        {
+            composite.setLayout( new GridLayout( 1, false ) );
+            GridData layoutTable = new GridData( SWT.FILL, SWT.FILL, true, true );
+            layoutTable.heightHint = 200;
+            table.setLayoutData( layoutTable );
+        }
+        else
+        {
+            composite.setLayout( new GridLayout( 2, false ) );
+            txtSelection.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        }
+
+        return container;
+    }
+
+
+    protected void elementSelected( E selection )
+    {
+    }
+
+
+    @Override
+    protected Control createButtonBar( Composite parent )
+    {
+        Control bar = super.createButtonBar( parent );
+        updateButtons();
+        return bar;
+    }
+
+
+    /**
+     * Can be called from any thread
+     */
+    protected final void updateButtons()
+    {
+        Runnable updateButtonsRunnable = new Runnable()
+        {
+            public void run()
+            {
+                Shell shell = getShell();
+                if ( shell != null && !shell.isDisposed() )
+                {
+                    Button okButton = getButton( IDialogConstants.OK_ID );
+                    if ( okButton != null && !okButton.isDisposed() )
+                    {
+                        okButton.setEnabled( canComplete() );
+                    }
+                }
+            }
+        };
+        Shell shell = getShell();
+        if ( shell != null )
+        {
+            onUIThread( shell, updateButtonsRunnable );
+        }
+    }
+
+
+    /**
+     * Subclasses may override but must call super.canComplete
+     * @return
+     */
+    protected synchronized boolean canComplete()
+    {
+        boolean result = false;
+
+        if ( selection != null )
+        {
+            if ( multi )
+            {
+                result = selection.size() > 0;
+            }
+            else
+            {
+                E sel = getSelectedElement();
+                result = sel != null && descriptor.getName( sel ).equals( selectedName );
+            }
+        }
+
+        return result;
+    }
+
+
+    public final void addElement( E added )
+    {
+        addElements( Collections.singleton( added ) );
+    }
+
+
+    /**
+     * Can be called from any thread
+     */
+    public final void addElements( Collection<? extends E> added )
+    {
+        final LinkedList<E> toAdd = new LinkedList<E>();
+        synchronized ( elements )
+        {
+            for ( E e : added )
+            {
+                if ( !elements.contains( e ) )
+                {
+                    elements.add( e );
+                    toAdd.add( e );
+                }
+            }
+            Collections.sort( elements, comparator );
+        }
+        if ( viewer != null )
+        {
+            onUIThread( viewer.getControl(), new Runnable()
+            {
+                public void run()
+                {
+                    if ( !viewer.getControl().isDisposed() )
+                    {
+                        viewer.add( toAdd.toArray() );
+                        viewer.refresh();
+                    }
+                }
+            } );
+        }
+        else
+        {
+
+        }
+        updateSelection();
+        updateButtons();
+    }
+
+
+    protected void updateSelection()
+    {
+        onUIThread( getShell(), new Runnable()
+        {
+            public void run()
+            {
+                if ( selectedName != null )
+                {
+                    ArrayList<E> newSelection = new ArrayList<E>();
+                    synchronized ( elements )
+                    {
+                        for ( E e : elements )
+                        {
+                            if ( selectedName.equals( descriptor.getName( e ) ) )
+                            {
+                                newSelection.add( e );
+                                break;
+                            }
+                        }
+                    }
+                    selection = newSelection;
+                }
+                else
+                {
+                    selection = Collections.emptyList();
+                }
+                if ( viewer != null && !viewer.getControl().isDisposed() )
+                {
+                    viewer.setSelection( selection.isEmpty() ? StructuredSelection.EMPTY : new StructuredSelection(
+                        selection ) );
+                }
+            }
+        } );
+    }
+
+
+    private static final void onUIThread( Control control, Runnable r )
+    {
+        if ( control != null && !control.isDisposed() )
+        {
+            try
+            {
+                Display display = control.getDisplay();
+                if ( Thread.currentThread() == display.getThread() )
+                {
+                    // We are on the UI thread already, just do the work
+                    r.run();
+                }
+                else
+                {
+                    // Not on the UI thread, need to bung over the runnable
+                    display.asyncExec( r );
+                }
+            }
+            catch ( SWTError e )
+            {
+                if ( e.code == SWT.ERROR_WIDGET_DISPOSED )
+                {
+                    // ignore
+                }
+                else
+                {
+                    throw e;
+                }
+            }
+        }
+    }
+
+
+    public String getSelectedName()
+    {
+        return selectedName;
+    }
+
+
+    public void setSelectedName( String selectedName )
+    {
+        this.selectedName = selectedName;
+        boolean change = false;
+        if ( selectedName == null )
+        {
+            if ( selection != null && !selection.isEmpty() )
+            {
+                change = true;
+            }
+        }
+        else
+        {
+            if ( selection == null )
+            {
+                change = true;
+            }
+            else if ( selection.size() != 1 || !descriptor.getLabel( selection.get( 0 ) ).equals( selectedName ) )
+            {
+                change = true;
+            }
+        }
+
+        if ( change )
+        {
+            updateSelection();
+            updateButtons();
+        }
+    }
+
+
+    public List<E> getSelectedElements()
+    {
+        return selection;
+    }
+
+
+    public E getSelectedElement()
+    {
+        E result;
+        if ( selection == null || selection.isEmpty() )
+        {
+            result = null;
+        }
+        else
+        {
+            result = selection.get( 0 );
+        }
+        return result;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ColumnModelLabelProvider.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ColumnModelLabelProvider.java
index 39311fc..39b59ea 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ColumnModelLabelProvider.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ColumnModelLabelProvider.java
@@ -19,21 +19,28 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import org.eclipse.jface.viewers.ColumnLabelProvider;
 import org.eclipse.swt.graphics.Image;
 
-public class ColumnModelLabelProvider extends ColumnLabelProvider {
 
-	private ModelLabelProvider provider = new ModelLabelProvider();
-	
-	@Override
-	public Image getImage(Object element) {
-		return provider.getImage(element);
-	}
+public class ColumnModelLabelProvider extends ColumnLabelProvider
+{
 
-	@Override
-	public String getText(Object element) {
-		return provider.getText(element);
-	}
+    private ModelLabelProvider provider = new ModelLabelProvider();
+
+
+    @Override
+    public Image getImage( Object element )
+    {
+        return provider.getImage( element );
+    }
+
+
+    @Override
+    public String getText( Object element )
+    {
+        return provider.getText( element );
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultContentProvider.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultContentProvider.java
index 8081e51..eaf6f89 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultContentProvider.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultContentProvider.java
@@ -19,14 +19,20 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import org.eclipse.jface.viewers.IContentProvider;
 import org.eclipse.jface.viewers.Viewer;
 
-public class DefaultContentProvider implements IContentProvider {
 
-	public void dispose() {
-	}
+public class DefaultContentProvider implements IContentProvider
+{
 
-	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-	}
+    public void dispose()
+    {
+    }
+
+
+    public void inputChanged( Viewer viewer, Object oldInput, Object newInput )
+    {
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultLabelProvider.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultLabelProvider.java
index 0d02846..f1305f4 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultLabelProvider.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultLabelProvider.java
@@ -19,23 +19,33 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import org.eclipse.jface.viewers.IBaseLabelProvider;
 import org.eclipse.jface.viewers.ILabelProvider;
 import org.eclipse.jface.viewers.ILabelProviderListener;
 
-public abstract class DefaultLabelProvider implements IBaseLabelProvider, ILabelProvider {
 
-	public boolean isLabelProperty(Object element, String property) {
-		return false;
-	}
+public abstract class DefaultLabelProvider implements IBaseLabelProvider, ILabelProvider
+{
 
-	public void dispose() {
-	}
+    public boolean isLabelProperty( Object element, String property )
+    {
+        return false;
+    }
 
-	public void addListener(ILabelProviderListener listener) {
-	}
 
-	public void removeListener(ILabelProviderListener listener) {
-	}
+    public void dispose()
+    {
+    }
+
+
+    public void addListener( ILabelProviderListener listener )
+    {
+    }
+
+
+    public void removeListener( ILabelProviderListener listener )
+    {
+    }
 
 }
\ No newline at end of file
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultTableProvider.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultTableProvider.java
index dac615f..dad96c0 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultTableProvider.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultTableProvider.java
@@ -19,37 +19,46 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import java.util.Collection;
 
 import org.eclipse.jface.viewers.IStructuredContentProvider;
 
-public abstract class DefaultTableProvider extends DefaultContentProvider implements IStructuredContentProvider {
 
-	/**
-	 * Utility method to convert the input element to an Object[].
-	 * 
-	 * @param inputElement
-	 * 
-	 * @return if inputElement is null -> empty array <br/>
-	 *         if inputElement is a {@link Collection} returns {@link Collection#toArray()}<br/>
-	 *         if inputElement is an Array class cast of inputElement to Object[]<br/>
-	 *  
-	 * @throws IllegalArgumentException if the element cannot be converted. 
-	 */
-	public Object[] toArray(Object inputElement) {
-		if ( inputElement == null ) {
-			return new Object[] {};
-		}
-		else if ( inputElement instanceof Collection ) {
-			Collection<?> col = (Collection<?>) inputElement;
-			return col.toArray();
-		}
-		else if ( inputElement.getClass().isArray() ) {
-			return (Object[]) inputElement;
-		}
-		else {
-			throw new IllegalArgumentException( "Invalid inputElement " + inputElement.getClass() );
-		}		
-	}
-	
+public abstract class DefaultTableProvider extends DefaultContentProvider implements IStructuredContentProvider
+{
+
+    /**
+     * Utility method to convert the input element to an Object[].
+     * 
+     * @param inputElement
+     * 
+     * @return if inputElement is null -> empty array <br/>
+     *         if inputElement is a {@link Collection} returns {@link Collection#toArray()}<br/>
+     *         if inputElement is an Array class cast of inputElement to Object[]<br/>
+     *  
+     * @throws IllegalArgumentException if the element cannot be converted. 
+     */
+    public Object[] toArray( Object inputElement )
+    {
+        if ( inputElement == null )
+        {
+            return new Object[]
+                {};
+        }
+        else if ( inputElement instanceof Collection )
+        {
+            Collection<?> col = ( Collection<?> ) inputElement;
+            return col.toArray();
+        }
+        else if ( inputElement.getClass().isArray() )
+        {
+            return ( Object[] ) inputElement;
+        }
+        else
+        {
+            throw new IllegalArgumentException( "Invalid inputElement " + inputElement.getClass() );
+        }
+    }
+
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultTreeContentProvider.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultTreeContentProvider.java
index 4a60b72..dafc1bd 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultTreeContentProvider.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/DefaultTreeContentProvider.java
@@ -19,7 +19,10 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import org.eclipse.jface.viewers.ITreeContentProvider;
 
-public abstract class DefaultTreeContentProvider extends DefaultContentProvider implements ITreeContentProvider {
+
+public abstract class DefaultTreeContentProvider extends DefaultContentProvider implements ITreeContentProvider
+{
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ExclusionContentProposalProvider.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ExclusionContentProposalProvider.java
index 0dd4254..371c464 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ExclusionContentProposalProvider.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ExclusionContentProposalProvider.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -31,43 +32,54 @@
 import org.eclipse.jface.fieldassist.IContentProposal;
 import org.eclipse.jface.fieldassist.IContentProposalProvider;
 
-public class ExclusionContentProposalProvider<T> implements
-		IContentProposalProvider {
-	
-	private final Collection<? extends T> elements;
-	private final IFilter<? super T> filter;
-	private final IElementDescriptor<? super T> descriptor;
 
-	public ExclusionContentProposalProvider(Collection<? extends T> elements, IFilter<? super T> filter, IElementDescriptor<? super T> descriptor) {
-		this.elements = elements;
-		this.filter = filter;
-		this.descriptor = descriptor;
-	}
-	
-	public IContentProposal[] getProposals(String contents, int position) {
-		String matchString = contents.substring(0, position);
-		Pattern pattern = GlobCompiler.compile(matchString);
+public class ExclusionContentProposalProvider<T> implements IContentProposalProvider
+{
 
-		// Get a snapshot of the elements
-		T[] elementArray;
-		synchronized (elements) {
-			@SuppressWarnings("unchecked") T[] temp = (T[]) elements.toArray();
-			elementArray = temp;
-		}
-		
-		List<IContentProposal> result = new ArrayList<IContentProposal>();
-		
-		for (T element : elementArray) {
-			if(filter != null && filter.select(element)) {
-				IContentProposal proposal = WrappedContentProposal.newInstance(element, descriptor);
-				Matcher matcher = pattern.matcher(proposal.getContent());
-				if(matcher.find()) {
-					result.add(proposal);
-				}
-			}
-		}
-		
-		return result.toArray(new IContentProposal[result.size()]);
-	}
+    private final Collection<? extends T> elements;
+    private final IFilter<? super T> filter;
+    private final IElementDescriptor<? super T> descriptor;
+
+
+    public ExclusionContentProposalProvider( Collection<? extends T> elements, IFilter<? super T> filter,
+        IElementDescriptor<? super T> descriptor )
+    {
+        this.elements = elements;
+        this.filter = filter;
+        this.descriptor = descriptor;
+    }
+
+
+    public IContentProposal[] getProposals( String contents, int position )
+    {
+        String matchString = contents.substring( 0, position );
+        Pattern pattern = GlobCompiler.compile( matchString );
+
+        // Get a snapshot of the elements
+        T[] elementArray;
+        synchronized ( elements )
+        {
+            @SuppressWarnings("unchecked")
+            T[] temp = ( T[] ) elements.toArray();
+            elementArray = temp;
+        }
+
+        List<IContentProposal> result = new ArrayList<IContentProposal>();
+
+        for ( T element : elementArray )
+        {
+            if ( filter != null && filter.select( element ) )
+            {
+                IContentProposal proposal = WrappedContentProposal.newInstance( element, descriptor );
+                Matcher matcher = pattern.matcher( proposal.getContent() );
+                if ( matcher.find() )
+                {
+                    result.add( proposal );
+                }
+            }
+        }
+
+        return result.toArray( new IContentProposal[result.size()] );
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ExportedPackageFinder.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ExportedPackageFinder.java
index 71e053b..d3f535f 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ExportedPackageFinder.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ExportedPackageFinder.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -32,37 +33,48 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.ui.progress.IJobRunnable;
 
-public class ExportedPackageFinder implements IJobRunnable {
-	
-	private final IAccumulator<? super IPackageExport> accumulator;
-	private final ISigilProjectModel sigil;
 
-	public ExportedPackageFinder(ISigilProjectModel sigil, IAccumulator<? super IPackageExport> accumulator) {
-		this.sigil = sigil;
-		this.accumulator = accumulator;
-	}
+public class ExportedPackageFinder implements IJobRunnable
+{
 
-	public IStatus run(final IProgressMonitor monitor) {
-		final List<IPackageExport> exports = new ArrayList<IPackageExport>(ResourcesDialogHelper.UPDATE_BATCH_SIZE);
-		final IModelWalker walker = new IModelWalker() {
-			public boolean visit(IModelElement element) {
-				if ( element instanceof IPackageExport ) {
-					IPackageExport pkgExport = (IPackageExport) element;
-					exports.add(pkgExport);
+    private final IAccumulator<? super IPackageExport> accumulator;
+    private final ISigilProjectModel sigil;
 
-					if(exports.size() >= ResourcesDialogHelper.UPDATE_BATCH_SIZE) {
-						accumulator.addElements(exports);
-						exports.clear();
-					}
-				}
-				return !monitor.isCanceled();
-			}
-		};
-		SigilCore.getRepositoryManager(sigil).visit(walker);
-		if(exports.size() > 0) {
-			accumulator.addElements(exports);
-		}
 
-		return Status.OK_STATUS;
-	}
+    public ExportedPackageFinder( ISigilProjectModel sigil, IAccumulator<? super IPackageExport> accumulator )
+    {
+        this.sigil = sigil;
+        this.accumulator = accumulator;
+    }
+
+
+    public IStatus run( final IProgressMonitor monitor )
+    {
+        final List<IPackageExport> exports = new ArrayList<IPackageExport>( ResourcesDialogHelper.UPDATE_BATCH_SIZE );
+        final IModelWalker walker = new IModelWalker()
+        {
+            public boolean visit( IModelElement element )
+            {
+                if ( element instanceof IPackageExport )
+                {
+                    IPackageExport pkgExport = ( IPackageExport ) element;
+                    exports.add( pkgExport );
+
+                    if ( exports.size() >= ResourcesDialogHelper.UPDATE_BATCH_SIZE )
+                    {
+                        accumulator.addElements( exports );
+                        exports.clear();
+                    }
+                }
+                return !monitor.isCanceled();
+            }
+        };
+        SigilCore.getRepositoryManager( sigil ).visit( walker );
+        if ( exports.size() > 0 )
+        {
+            accumulator.addElements( exports );
+        }
+
+        return Status.OK_STATUS;
+    }
 }
\ No newline at end of file
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/FileUtils.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/FileUtils.java
index 951aad2..f7c82d4 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/FileUtils.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/FileUtils.java
@@ -17,32 +17,40 @@
  * under the License.
  */
 
-package org.apache.felix.sigil.ui.eclipse.ui.util;

-

-import org.eclipse.swt.SWT;

-import org.eclipse.swt.widgets.DirectoryDialog;

-import org.eclipse.swt.widgets.FileDialog;

-import org.eclipse.swt.widgets.Shell;

-import org.eclipse.swt.widgets.Text;

-

-public class FileUtils {

-	public static void loadFile( Shell shell, Text text, String msg, boolean isDirectory ) {

-		if ( isDirectory ) {

-			DirectoryDialog dialog = new DirectoryDialog(shell, SWT.NONE);

-			dialog.setMessage(msg);

-			String value = dialog.open();

-			if ( value != null ) {

-				text.setText( value );

-			}

-		}

-		else {

-			FileDialog dialog = new FileDialog(shell, SWT.NONE);

-			dialog.setText(msg);

-			String value = dialog.open();

-			if ( value != null ) {

-				text.setText( value );

-			}

-		}

-	}

-

-}

+package org.apache.felix.sigil.ui.eclipse.ui.util;
+
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+
+public class FileUtils
+{
+    public static void loadFile( Shell shell, Text text, String msg, boolean isDirectory )
+    {
+        if ( isDirectory )
+        {
+            DirectoryDialog dialog = new DirectoryDialog( shell, SWT.NONE );
+            dialog.setMessage( msg );
+            String value = dialog.open();
+            if ( value != null )
+            {
+                text.setText( value );
+            }
+        }
+        else
+        {
+            FileDialog dialog = new FileDialog( shell, SWT.NONE );
+            dialog.setText( msg );
+            String value = dialog.open();
+            if ( value != null )
+            {
+                text.setText( value );
+            }
+        }
+    }
+
+}
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IAccumulator.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IAccumulator.java
index 86a1859..10023db 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IAccumulator.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IAccumulator.java
@@ -19,9 +19,14 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import java.util.Collection;
 
-public interface IAccumulator<E> {
-	public void addElement(E element);
-	public void addElements(Collection<? extends E> elements);
+
+public interface IAccumulator<E>
+{
+    public void addElement( E element );
+
+
+    public void addElements( Collection<? extends E> elements );
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IExportToImportConverter.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IExportToImportConverter.java
index 7c30b61..1290115 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IExportToImportConverter.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IExportToImportConverter.java
@@ -19,6 +19,8 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
-public interface IExportToImportConverter<E,I> {
-	I convert(E exportElement);
+
+public interface IExportToImportConverter<E, I>
+{
+    I convert( E exportElement );
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IFilter.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IFilter.java
index 987485d..9a58fcb 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IFilter.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IFilter.java
@@ -19,6 +19,8 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
-public interface IFilter<T> {
-	boolean select(T element);
+
+public interface IFilter<T>
+{
+    boolean select( T element );
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IValidationListener.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IValidationListener.java
index ae1f6d1..81827e5 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IValidationListener.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/IValidationListener.java
@@ -19,8 +19,10 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
-public interface IValidationListener {
 
-	void validationMessage(String message, int level);
+public interface IValidationListener
+{
+
+    void validationMessage( String message, int level );
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ModelLabelProvider.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ModelLabelProvider.java
index ea28ed8..072cdc7 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ModelLabelProvider.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ModelLabelProvider.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import java.util.Set;
 
 import org.apache.felix.sigil.eclipse.SigilCore;
@@ -40,146 +41,198 @@
 import org.eclipse.swt.graphics.Image;
 import org.osgi.framework.Version;
 
-public class ModelLabelProvider extends LabelProvider {
-	
-	private volatile Set<? extends IModelElement> unresolvedElements = null;
-	
-	public Image getImage(Object element) {
-		boolean unresolved = (unresolvedElements == null) ? false : unresolvedElements.contains(element);
-		
-		if ( element instanceof ISigilBundle || element instanceof IBundleModelElement) {
-			return findBundle();
-		} else if(element instanceof IRequiredBundle) {
-			boolean optional = ((IRequiredBundle) element).isOptional();
-			return findRequiredBundle(optional, unresolved);
-		}
-		else if ( element instanceof IPackageImport ) {
-			boolean optional = ((IPackageImport) element).isOptional();
-			return findPackageImport(optional, unresolved);
-		}
-		else if ( element instanceof IPackageExport ) {
-			return findPackageExport();
-		}
-		else if ( element instanceof IPackageFragmentRoot ) {
-			IPackageFragmentRoot root = (IPackageFragmentRoot) element;
-			try {
-				if ( root.getKind() == IPackageFragmentRoot.K_SOURCE ) {
-					return findPackage();
-				}
-				else {
-					return findBundle();
-				}
-			} catch (JavaModelException e) {
-				SigilCore.error( "Failed to inspect package fragment root", e );
-			}
-		}
-		else if ( element instanceof IClasspathEntry ) {
-			return findPackage();
-		}
-		if ( element instanceof IBundleRepository ) {
-			IBundleRepository rep = (IBundleRepository) element;
-			IRepositoryModel config = SigilCore.getRepositoryConfiguration().findRepository(rep.getId());
-			return config.getType().getIcon();
-		}
-	
-		return null;
-	}
 
-	public String getText(Object element) {
-		if ( element instanceof ISigilBundle ) {
-			ISigilBundle bundle = (ISigilBundle) element;
-			return bundle.getBundleInfo().getSymbolicName() + " " + bundle.getBundleInfo().getVersion(); 
-		}
-		if ( element instanceof IBundleModelElement ) {
-			IBundleModelElement bundle = (IBundleModelElement) element;
-			return bundle.getSymbolicName();
-		}
-		if ( element instanceof IRequiredBundle ) {
-			IRequiredBundle req = (IRequiredBundle) element;
-			return req.getSymbolicName() + " " + req.getVersions();
-		}
-		
-		if ( element instanceof IPackageImport ) {
-			IPackageImport req = (IPackageImport) element;
-			return req.getPackageName() + " " + req.getVersions();
-		}
-		
-		if ( element instanceof IPackageExport ) {
-			IPackageExport pe = (IPackageExport) element;
-			Version rawVersion = pe.getRawVersion();
-			return rawVersion != null ? pe.getPackageName() + " " + rawVersion : pe.getPackageName();
-		}
-		
-		if ( element instanceof IResource ) {
-			IResource resource = (IResource) element;
-			return resource.getName();
-		}
-		
-		if ( element instanceof IPackageFragment )  {
-			IPackageFragment f = (IPackageFragment) element;
-			return f.getElementName();
-		}
-		
-		if ( element instanceof IPackageFragmentRoot ) {
-			IPackageFragmentRoot f = (IPackageFragmentRoot) element;
-			try {
-				return f.getUnderlyingResource().getName();
-			} catch (JavaModelException e) {
-				return "unknown";
-			}
-		}
-		
-		if ( element instanceof IClasspathEntry ) {
-			IClasspathEntry cp = (IClasspathEntry) element;
-			return cp.getPath().toString();
-		}
-		
-		if ( element instanceof IBundleRepository ) {
-			IBundleRepository rep = (IBundleRepository) element;
-			IRepositoryModel config = SigilCore.getRepositoryConfiguration().findRepository(rep.getId());
-			return config.getName();
-		}
-		
-		return element.toString();
-	}
+public class ModelLabelProvider extends LabelProvider
+{
 
-	private Image findPackage() {
-		return cacheImage( "icons/package_obj.png" ); 
-	}
+    private volatile Set<? extends IModelElement> unresolvedElements = null;
 
-	private Image findPackageImport(boolean optional, boolean unresolved) {
-		String path;
-		if(optional) {
-			path = unresolved ? "icons/package_obj_import_opt_error.png" : "icons/package_obj_import_opt.png";
-		} else {
-			path = unresolved ? "icons/package_obj_import_error.png" : "icons/package_obj_import.png";
-		}
-		return cacheImage(path);
-	}
-	
-	private Image findPackageExport() {
-		return cacheImage("icons/package_obj_export.png");
-	}
-	
-	private Image findBundle() {
-		return cacheImage("icons/jar_obj.png");
-	}
-	
-	private Image findRequiredBundle(boolean optional, boolean unresolved) {
-		String path;
-		if(optional) {
-			path = unresolved ? "icons/required_bundle_opt_error.png" : "icons/required_bundle_opt.png";
-		} else {
-			path = unresolved ? "icons/required_bundle_error.png" : "icons/jar_obj.png";
-		}
-		return cacheImage(path);
-	}
-	
-	private static Image cacheImage(String path) {
-		return SigilUI.cacheImage(path, ModelLabelProvider.class.getClassLoader());
-	}
 
-	public void setUnresolvedElements(Set<? extends IModelElement> elements) {
-		this.unresolvedElements = elements;
-	}
+    public Image getImage( Object element )
+    {
+        boolean unresolved = ( unresolvedElements == null ) ? false : unresolvedElements.contains( element );
+
+        if ( element instanceof ISigilBundle || element instanceof IBundleModelElement )
+        {
+            return findBundle();
+        }
+        else if ( element instanceof IRequiredBundle )
+        {
+            boolean optional = ( ( IRequiredBundle ) element ).isOptional();
+            return findRequiredBundle( optional, unresolved );
+        }
+        else if ( element instanceof IPackageImport )
+        {
+            boolean optional = ( ( IPackageImport ) element ).isOptional();
+            return findPackageImport( optional, unresolved );
+        }
+        else if ( element instanceof IPackageExport )
+        {
+            return findPackageExport();
+        }
+        else if ( element instanceof IPackageFragmentRoot )
+        {
+            IPackageFragmentRoot root = ( IPackageFragmentRoot ) element;
+            try
+            {
+                if ( root.getKind() == IPackageFragmentRoot.K_SOURCE )
+                {
+                    return findPackage();
+                }
+                else
+                {
+                    return findBundle();
+                }
+            }
+            catch ( JavaModelException e )
+            {
+                SigilCore.error( "Failed to inspect package fragment root", e );
+            }
+        }
+        else if ( element instanceof IClasspathEntry )
+        {
+            return findPackage();
+        }
+        if ( element instanceof IBundleRepository )
+        {
+            IBundleRepository rep = ( IBundleRepository ) element;
+            IRepositoryModel config = SigilCore.getRepositoryConfiguration().findRepository( rep.getId() );
+            return config.getType().getIcon();
+        }
+
+        return null;
+    }
+
+
+    public String getText( Object element )
+    {
+        if ( element instanceof ISigilBundle )
+        {
+            ISigilBundle bundle = ( ISigilBundle ) element;
+            return bundle.getBundleInfo().getSymbolicName() + " " + bundle.getBundleInfo().getVersion();
+        }
+        if ( element instanceof IBundleModelElement )
+        {
+            IBundleModelElement bundle = ( IBundleModelElement ) element;
+            return bundle.getSymbolicName();
+        }
+        if ( element instanceof IRequiredBundle )
+        {
+            IRequiredBundle req = ( IRequiredBundle ) element;
+            return req.getSymbolicName() + " " + req.getVersions();
+        }
+
+        if ( element instanceof IPackageImport )
+        {
+            IPackageImport req = ( IPackageImport ) element;
+            return req.getPackageName() + " " + req.getVersions();
+        }
+
+        if ( element instanceof IPackageExport )
+        {
+            IPackageExport pe = ( IPackageExport ) element;
+            Version rawVersion = pe.getRawVersion();
+            return rawVersion != null ? pe.getPackageName() + " " + rawVersion : pe.getPackageName();
+        }
+
+        if ( element instanceof IResource )
+        {
+            IResource resource = ( IResource ) element;
+            return resource.getName();
+        }
+
+        if ( element instanceof IPackageFragment )
+        {
+            IPackageFragment f = ( IPackageFragment ) element;
+            return f.getElementName();
+        }
+
+        if ( element instanceof IPackageFragmentRoot )
+        {
+            IPackageFragmentRoot f = ( IPackageFragmentRoot ) element;
+            try
+            {
+                return f.getUnderlyingResource().getName();
+            }
+            catch ( JavaModelException e )
+            {
+                return "unknown";
+            }
+        }
+
+        if ( element instanceof IClasspathEntry )
+        {
+            IClasspathEntry cp = ( IClasspathEntry ) element;
+            return cp.getPath().toString();
+        }
+
+        if ( element instanceof IBundleRepository )
+        {
+            IBundleRepository rep = ( IBundleRepository ) element;
+            IRepositoryModel config = SigilCore.getRepositoryConfiguration().findRepository( rep.getId() );
+            return config.getName();
+        }
+
+        return element.toString();
+    }
+
+
+    private Image findPackage()
+    {
+        return cacheImage( "icons/package_obj.png" );
+    }
+
+
+    private Image findPackageImport( boolean optional, boolean unresolved )
+    {
+        String path;
+        if ( optional )
+        {
+            path = unresolved ? "icons/package_obj_import_opt_error.png" : "icons/package_obj_import_opt.png";
+        }
+        else
+        {
+            path = unresolved ? "icons/package_obj_import_error.png" : "icons/package_obj_import.png";
+        }
+        return cacheImage( path );
+    }
+
+
+    private Image findPackageExport()
+    {
+        return cacheImage( "icons/package_obj_export.png" );
+    }
+
+
+    private Image findBundle()
+    {
+        return cacheImage( "icons/jar_obj.png" );
+    }
+
+
+    private Image findRequiredBundle( boolean optional, boolean unresolved )
+    {
+        String path;
+        if ( optional )
+        {
+            path = unresolved ? "icons/required_bundle_opt_error.png" : "icons/required_bundle_opt.png";
+        }
+        else
+        {
+            path = unresolved ? "icons/required_bundle_error.png" : "icons/jar_obj.png";
+        }
+        return cacheImage( path );
+    }
+
+
+    private static Image cacheImage( String path )
+    {
+        return SigilUI.cacheImage( path, ModelLabelProvider.class.getClassLoader() );
+    }
+
+
+    public void setUnresolvedElements( Set<? extends IModelElement> elements )
+    {
+        this.unresolvedElements = elements;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/PackageFilter.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/PackageFilter.java
index c5d41a4..39226a4 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/PackageFilter.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/PackageFilter.java
@@ -19,30 +19,41 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import java.util.HashSet;
 import java.util.Set;
 
 import org.apache.felix.sigil.model.osgi.IPackageExport;
 import org.apache.felix.sigil.model.osgi.IPackageImport;
 
-public class PackageFilter implements IFilter<IPackageImport> {
-	
-	private Set<String> names = new HashSet<String>();
-	
-	public PackageFilter(String[] packageNames) {
-		for (String name : packageNames) {
-			names.add(name);
-		}
-	}
-	
-	public PackageFilter(IPackageExport[] packages) {
-		for (IPackageExport packageExport : packages) {
-			names.add(packageExport.getPackageName());
-		}
-	}
 
-	public boolean select(IPackageImport element) {
-		return !names.contains(element.getPackageName());
-	}
+public class PackageFilter implements IFilter<IPackageImport>
+{
+
+    private Set<String> names = new HashSet<String>();
+
+
+    public PackageFilter( String[] packageNames )
+    {
+        for ( String name : packageNames )
+        {
+            names.add( name );
+        }
+    }
+
+
+    public PackageFilter( IPackageExport[] packages )
+    {
+        for ( IPackageExport packageExport : packages )
+        {
+            names.add( packageExport.getPackageName() );
+        }
+    }
+
+
+    public boolean select( IPackageImport element )
+    {
+        return !names.contains( element.getPackageName() );
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ProjectUtils.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ProjectUtils.java
index 4da941d..9c7f01a 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ProjectUtils.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ProjectUtils.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import java.util.concurrent.Callable;
 
 import org.apache.felix.sigil.eclipse.SigilCore;
@@ -29,51 +30,72 @@
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.actions.WorkspaceModifyOperation;
 
-public class ProjectUtils {
-	public static boolean runTaskWithRebuildCheck(final Runnable task, Shell shell) {
-		return runTaskWithRebuildCheck( new Callable<Boolean>() {
-			public Boolean call() throws Exception {
-				task.run();
-				return true;
-			}
-		}, shell);
-	}
-	
-	public static boolean runTaskWithRebuildCheck(Callable<Boolean> callable,
-			Shell shell) {
-		int result = checkRebuild(shell);
-		if ( result == IDialogConstants.CANCEL_ID ) {
-			return false;
-		}
-		else {
-			try {
-				if ( Boolean.TRUE == callable.call() ) {
-					if ( result == IDialogConstants.YES_ID ) {
-						SigilUI.runWorkspaceOperation( new WorkspaceModifyOperation() {
-							@Override
-							protected void execute(IProgressMonitor monitor) {
-								SigilCore.rebuildAllBundleDependencies(monitor);
-							}
-						}, shell );
-					}
-					return true;
-				}
-				else {
-					return false;
-				}
-			} catch (Exception e) {
-				SigilCore.error( "Failed to run caller", e);
-				return false;
-			}
-		}
-	}
-	
-	private static int checkRebuild(Shell shell) {
-		if ( SigilCore.getRoot().getProjects().isEmpty() ) {
-			return IDialogConstants.NO_ID;
-		}
-		else {
-			return OptionalPrompt.optionallyPromptWithCancel(SigilCore.getDefault().getPreferenceStore(), SigilCore.PREFERENCES_REBUILD_PROJECTS, "Rebuild", "Do you wish to rebuild all Sigil projects", shell );
-		}
-	}
+
+public class ProjectUtils
+{
+    public static boolean runTaskWithRebuildCheck( final Runnable task, Shell shell )
+    {
+        return runTaskWithRebuildCheck( new Callable<Boolean>()
+        {
+            public Boolean call() throws Exception
+            {
+                task.run();
+                return true;
+            }
+        }, shell );
+    }
+
+
+    public static boolean runTaskWithRebuildCheck( Callable<Boolean> callable, Shell shell )
+    {
+        int result = checkRebuild( shell );
+        if ( result == IDialogConstants.CANCEL_ID )
+        {
+            return false;
+        }
+        else
+        {
+            try
+            {
+                if ( Boolean.TRUE == callable.call() )
+                {
+                    if ( result == IDialogConstants.YES_ID )
+                    {
+                        SigilUI.runWorkspaceOperation( new WorkspaceModifyOperation()
+                        {
+                            @Override
+                            protected void execute( IProgressMonitor monitor )
+                            {
+                                SigilCore.rebuildAllBundleDependencies( monitor );
+                            }
+                        }, shell );
+                    }
+                    return true;
+                }
+                else
+                {
+                    return false;
+                }
+            }
+            catch ( Exception e )
+            {
+                SigilCore.error( "Failed to run caller", e );
+                return false;
+            }
+        }
+    }
+
+
+    private static int checkRebuild( Shell shell )
+    {
+        if ( SigilCore.getRoot().getProjects().isEmpty() )
+        {
+            return IDialogConstants.NO_ID;
+        }
+        else
+        {
+            return OptionalPrompt.optionallyPromptWithCancel( SigilCore.getDefault().getPreferenceStore(),
+                SigilCore.PREFERENCES_REBUILD_PROJECTS, "Rebuild", "Do you wish to rebuild all Sigil projects", shell );
+        }
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ResourceReviewDialog.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ResourceReviewDialog.java
index f427036..af83018 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ResourceReviewDialog.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ResourceReviewDialog.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import java.util.Collection;
 
 import org.apache.felix.sigil.model.IModelElement;
@@ -39,73 +40,90 @@
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Table;
 
-public class ResourceReviewDialog<T extends IModelElement> extends TitleAreaDialog {
 
-	private String title;	
-	private Collection<T> resources;
-	
-	private TableViewer viewer;
+public class ResourceReviewDialog<T extends IModelElement> extends TitleAreaDialog
+{
 
-	public ResourceReviewDialog(Shell parentShell, String title, Collection<T> resources) {
-		super(parentShell);
-		this.title = title;
-		this.resources = resources;
-	}
+    private String title;
+    private Collection<T> resources;
 
-	public Collection<T> getResources() {
-		return resources;
-	}
+    private TableViewer viewer;
 
-	@Override
-	protected Control createDialogArea(Composite parent) {
-		setTitle(title);
 
-		// Create controls
-		Composite container = (Composite) super.createDialogArea(parent);
-		Composite composite = new Composite(container, SWT.NONE);		
-		Table table = new Table(composite, SWT.BORDER | SWT.VIRTUAL);
-		
-		final Button remove = new Button(composite, SWT.PUSH);
-		remove.setText("Remove");
-		remove.setEnabled(false);
-		
-		remove.addSelectionListener( new SelectionAdapter() {
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				handleRemove();
-			}
-		} );
-		
-		viewer = new TableViewer(table);
-		viewer.setContentProvider( new DefaultTableProvider() {
-			public Object[] getElements(Object inputElement) {
-				return toArray(inputElement);
-			}
-		});
-		
-		viewer.setInput( resources );
-		viewer.addSelectionChangedListener( new ISelectionChangedListener() {
-			public void selectionChanged(SelectionChangedEvent event) {
-				remove.setEnabled(!event.getSelection().isEmpty());
-			}
-		});
-		
-		// layout
-		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-		composite.setLayout(new GridLayout(2, false));
-		GridData tableLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 4);
-		tableLayoutData.heightHint = 150;
-		table.setLayoutData(tableLayoutData);
-		
-		return container;
-	}
+    public ResourceReviewDialog( Shell parentShell, String title, Collection<T> resources )
+    {
+        super( parentShell );
+        this.title = title;
+        this.resources = resources;
+    }
 
-	private void handleRemove() {
-		ISelection s = viewer.getSelection();
-		if ( !s.isEmpty() ) {
-			IStructuredSelection sel = (IStructuredSelection) s;
-			resources.remove( sel.getFirstElement() );
-			viewer.refresh();
-		}
-	}
+
+    public Collection<T> getResources()
+    {
+        return resources;
+    }
+
+
+    @Override
+    protected Control createDialogArea( Composite parent )
+    {
+        setTitle( title );
+
+        // Create controls
+        Composite container = ( Composite ) super.createDialogArea( parent );
+        Composite composite = new Composite( container, SWT.NONE );
+        Table table = new Table( composite, SWT.BORDER | SWT.VIRTUAL );
+
+        final Button remove = new Button( composite, SWT.PUSH );
+        remove.setText( "Remove" );
+        remove.setEnabled( false );
+
+        remove.addSelectionListener( new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected( SelectionEvent e )
+            {
+                handleRemove();
+            }
+        } );
+
+        viewer = new TableViewer( table );
+        viewer.setContentProvider( new DefaultTableProvider()
+        {
+            public Object[] getElements( Object inputElement )
+            {
+                return toArray( inputElement );
+            }
+        } );
+
+        viewer.setInput( resources );
+        viewer.addSelectionChangedListener( new ISelectionChangedListener()
+        {
+            public void selectionChanged( SelectionChangedEvent event )
+            {
+                remove.setEnabled( !event.getSelection().isEmpty() );
+            }
+        } );
+
+        // layout
+        composite.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        composite.setLayout( new GridLayout( 2, false ) );
+        GridData tableLayoutData = new GridData( SWT.FILL, SWT.FILL, true, true, 1, 4 );
+        tableLayoutData.heightHint = 150;
+        table.setLayoutData( tableLayoutData );
+
+        return container;
+    }
+
+
+    private void handleRemove()
+    {
+        ISelection s = viewer.getSelection();
+        if ( !s.isEmpty() )
+        {
+            IStructuredSelection sel = ( IStructuredSelection ) s;
+            resources.remove( sel.getFirstElement() );
+            viewer.refresh();
+        }
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ResourcesDialogHelper.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ResourcesDialogHelper.java
index c90ebed..928c7db 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ResourcesDialogHelper.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/ResourcesDialogHelper.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Comparator;
@@ -51,240 +52,315 @@
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.progress.IJobRunnable;
 
-public class ResourcesDialogHelper {
-	
-	static final int UPDATE_BATCH_SIZE = 100;
 
-	public static BackgroundLoadingSelectionDialog<String> createClassSelectDialog(Shell shell, String title, final ISigilProjectModel project, String selected, final String ifaceOrParentClass) {
-		final BackgroundLoadingSelectionDialog<String> dialog = new BackgroundLoadingSelectionDialog<String>(shell, "Class Name", true);
-		
-		IJobRunnable job = new IJobRunnable() {
-			public IStatus run(IProgressMonitor monitor) {
-				try {
-					for ( IJavaElement e : JavaHelper.findTypes(project.getJavaModel(), IJavaElement.PACKAGE_FRAGMENT_ROOT ) ) {
-						IPackageFragmentRoot root = (IPackageFragmentRoot) e;
-						if ( project.isInBundleClasspath(root)) {
-							for ( IJavaElement e1 : JavaHelper.findTypes(root, IJavaElement.COMPILATION_UNIT, IJavaElement.CLASS_FILE ) ) {
-								ITypeRoot typeRoot = (ITypeRoot) e1;
-								IType type = (IType) JavaHelper.findType(typeRoot, IJavaElement.TYPE);
-								if ( JavaHelper.isAssignableTo( ifaceOrParentClass, type ) ) {
-									dialog.addElement(type.getFullyQualifiedName());					
-								}							
-							}
-						}
-					}
-					
-					return Status.OK_STATUS;
-				} catch (JavaModelException e) {
-					return e.getStatus();
-				}				
-			}
+public class ResourcesDialogHelper
+{
 
-		};
-		
-		dialog.addBackgroundJob("Scanning for activators in project", job);
+    static final int UPDATE_BATCH_SIZE = 100;
 
-		return dialog;
-	}
-	
-	public static NewResourceSelectionDialog<IPackageExport> createImportDialog(
-			Shell shell, 
-			String title, 
-			ISigilProjectModel sigil, 
-			final IPackageImport selected, 
-			final Collection<IPackageImport> existing) {
-		final Set<String> existingNames = new HashSet<String>();
-		
-		for (IPackageImport existingImport : existing) {
-			existingNames.add(existingImport.getPackageName());
-		}
-		
-		final NewResourceSelectionDialog<IPackageExport> dialog = new NewResourceSelectionDialog<IPackageExport>(shell, "Package Name:", false);
-		
-		dialog.setFilter( new IFilter<IPackageModelElement>() {
-			public boolean select(IPackageModelElement element) {
-				return !existingNames.contains(element.getPackageName());
-			}
-		} );
-		
-		dialog.setComparator(new Comparator<IPackageExport>() {
-			public int compare(IPackageExport o1, IPackageExport o2) {
-				return o1.compareTo(o2);
-			}
-		});
-		
-		dialog.setDescriptor(new IElementDescriptor<IPackageExport>() {
-			public String getLabel(IPackageExport element) {
-				return getName(element) + " (" + element.getVersion().toString() + ")";
-			}
 
-			public String getName(IPackageExport element) {
-				return element.getPackageName();
-			}
-		});
-		
-		dialog.setLabelProvider(new WrappedContentProposalLabelProvider<IPackageExport>(dialog.getDescriptor()));
-		
-		if(selected != null) {
-			dialog.setSelectedName(selected.getPackageName());
-			dialog.setVersions(selected.getVersions());
-			dialog.setOptional(selected.isOptional());
-		}
+    public static BackgroundLoadingSelectionDialog<String> createClassSelectDialog( Shell shell, String title,
+        final ISigilProjectModel project, String selected, final String ifaceOrParentClass )
+    {
+        final BackgroundLoadingSelectionDialog<String> dialog = new BackgroundLoadingSelectionDialog<String>( shell,
+            "Class Name", true );
 
-		IJobRunnable job = new ExportedPackageFinder(sigil, dialog);
-		dialog.addBackgroundJob("Scanning for exports in workspace", job);
-		
-		return dialog;
-	}
-	
-	public static NewPackageExportDialog createNewExportDialog(Shell shell, String title, final IPackageExport selected, final ISigilProjectModel project, boolean multiSelect) {
-		IFilter<IJavaElement> selectFilter = new IFilter<IJavaElement>() {
-			public boolean select(IJavaElement e) {
-				if ( selected != null && e.getElementName().equals( selected.getPackageName() ) ) {
-					return true;
-				}
-				
-				if ( e.getElementName().trim().length() > 0 && isLocal( e ) ) {
-					for ( IPackageExport p : project.getBundle().getBundleInfo().getExports() ) {
-						if ( p.getPackageName().equals( e.getElementName() ) ) {
-							return false;
-						}
-					}
-					
-					return true;
-				}
-				else {
-					return false;
-				}
-			}
-			
-			private boolean isLocal(IJavaElement java) {
-				try {
-					switch ( java.getElementType() ) {
-					case IJavaElement.PACKAGE_FRAGMENT:
-						IPackageFragment fragment= (IPackageFragment) java;
-						return fragment.containsJavaResources();
-					default:
-						throw new IllegalStateException( "Unexpected resource type " + java );
-					}
-				}
-				catch (JavaModelException e) {
-					SigilCore.error( "Failed to inspect java element ", e );
-					return false;
-				}
-			}
-			
-		};
-		
-		final NewPackageExportDialog dialog = new NewPackageExportDialog(shell, multiSelect);
-		dialog.setFilter(selectFilter);
-		
-		dialog.setProjectVersion(project.getVersion());
-		if ( selected != null ) {
-			dialog.setSelectedName(selected.getPackageName());
-			dialog.setVersion(selected.getRawVersion());
-		}
-		
-		IJobRunnable job = new IJobRunnable() {
-			public IStatus run(IProgressMonitor monitor) {
-				try {
-					ArrayList<IPackageFragment> list = new ArrayList<IPackageFragment>(UPDATE_BATCH_SIZE);
-					for ( IJavaElement e : JavaHelper.findTypes(project.getJavaModel(), IJavaElement.PACKAGE_FRAGMENT_ROOT) ) {
-						IPackageFragmentRoot root = (IPackageFragmentRoot) e;
-						if ( project.isInBundleClasspath(root) ) {
-							for ( IJavaElement e1 : JavaHelper.findTypes(root, IJavaElement.PACKAGE_FRAGMENT) ) {
-								list.add((IPackageFragment) e1);
-								if(list.size() >= UPDATE_BATCH_SIZE) {
-									dialog.addElements(list);
-									list.clear();
-								}
-							}
-						}
-					}
-					if(!list.isEmpty()) {
-						dialog.addElements(list);
-					}
-					return Status.OK_STATUS;
-				} catch (JavaModelException e) {
-					return e.getStatus();
-				}
-			}
-		};
-		
-		dialog.addBackgroundJob("Scanning for packages in project", job);
-		
-		return dialog;
-	}
-	
-	public static NewResourceSelectionDialog<IBundleModelElement> createRequiredBundleDialog(Shell shell, String title, final ISigilProjectModel sigil, final IRequiredBundle selected, final Collection<IRequiredBundle> existing) {
-		final Set<String> existingNames = new HashSet<String>();
-		for(IRequiredBundle existingBundle : existing) {
-			existingNames.add(existingBundle.getSymbolicName());
-		}
-		
-		final NewResourceSelectionDialog<IBundleModelElement> dialog = new NewResourceSelectionDialog<IBundleModelElement>(shell, "Bundle:", false);
-		
-		dialog.setDescriptor(new IElementDescriptor<IBundleModelElement>() {
-			public String getLabel(IBundleModelElement element) {
-				return getName(element) + " (" + element.getVersion() + ")";
-			}
-			public String getName(IBundleModelElement element) {
-				return element.getSymbolicName();
-			}
-		});
-		
-		dialog.setLabelProvider(new WrappedContentProposalLabelProvider<IBundleModelElement>(dialog.getDescriptor()));
-		
-		dialog.setFilter(new IFilter<IBundleModelElement>() {
-			public boolean select(IBundleModelElement element) {
-				return !existingNames.contains(element.getSymbolicName());
-			}
-		});
-		
-		dialog.setComparator(new Comparator<IBundleModelElement>() {
-			public int compare(IBundleModelElement o1, IBundleModelElement o2) {
-				return o1.getSymbolicName().compareTo(o2.getSymbolicName());
-			}
-		});
-		
-		if(selected != null) {
-			dialog.setSelectedName(selected.getSymbolicName());
-			dialog.setVersions(selected.getVersions());
-			dialog.setOptional(selected.isOptional());
-		}
-				
-		IJobRunnable job = new IJobRunnable() {
-			public IStatus run(final IProgressMonitor monitor) {
-				final List<IBundleModelElement> bundles = new ArrayList<IBundleModelElement>(UPDATE_BATCH_SIZE);
-				final IModelWalker walker = new IModelWalker() {
-					//int count = 0;
-					public boolean visit(IModelElement element) {
-						if ( element instanceof  IBundleModelElement) {
-							IBundleModelElement b = (IBundleModelElement) element;
-							bundles.add(b);
+        IJobRunnable job = new IJobRunnable()
+        {
+            public IStatus run( IProgressMonitor monitor )
+            {
+                try
+                {
+                    for ( IJavaElement e : JavaHelper.findTypes( project.getJavaModel(),
+                        IJavaElement.PACKAGE_FRAGMENT_ROOT ) )
+                    {
+                        IPackageFragmentRoot root = ( IPackageFragmentRoot ) e;
+                        if ( project.isInBundleClasspath( root ) )
+                        {
+                            for ( IJavaElement e1 : JavaHelper.findTypes( root, IJavaElement.COMPILATION_UNIT,
+                                IJavaElement.CLASS_FILE ) )
+                            {
+                                ITypeRoot typeRoot = ( ITypeRoot ) e1;
+                                IType type = ( IType ) JavaHelper.findType( typeRoot, IJavaElement.TYPE );
+                                if ( JavaHelper.isAssignableTo( ifaceOrParentClass, type ) )
+                                {
+                                    dialog.addElement( type.getFullyQualifiedName() );
+                                }
+                            }
+                        }
+                    }
 
-							if(bundles.size() >= UPDATE_BATCH_SIZE) {
-								dialog.addElements(bundles);
-								bundles.clear();
-							}
-							// no need to recurse further.
-							return false;
-						}
-						return !monitor.isCanceled();
-					}
-				};
-				SigilCore.getRepositoryManager(sigil).visit(walker);
-				if(!bundles.isEmpty()) {
-					dialog.addElements(bundles);
-				}
-				return Status.OK_STATUS;
-			}
-		};
-		
-		dialog.addBackgroundJob("Scanning for bundles in workspace", job);
-		
-		return dialog;
-	}
+                    return Status.OK_STATUS;
+                }
+                catch ( JavaModelException e )
+                {
+                    return e.getStatus();
+                }
+            }
+
+        };
+
+        dialog.addBackgroundJob( "Scanning for activators in project", job );
+
+        return dialog;
+    }
+
+
+    public static NewResourceSelectionDialog<IPackageExport> createImportDialog( Shell shell, String title,
+        ISigilProjectModel sigil, final IPackageImport selected, final Collection<IPackageImport> existing )
+    {
+        final Set<String> existingNames = new HashSet<String>();
+
+        for ( IPackageImport existingImport : existing )
+        {
+            existingNames.add( existingImport.getPackageName() );
+        }
+
+        final NewResourceSelectionDialog<IPackageExport> dialog = new NewResourceSelectionDialog<IPackageExport>(
+            shell, "Package Name:", false );
+
+        dialog.setFilter( new IFilter<IPackageModelElement>()
+        {
+            public boolean select( IPackageModelElement element )
+            {
+                return !existingNames.contains( element.getPackageName() );
+            }
+        } );
+
+        dialog.setComparator( new Comparator<IPackageExport>()
+        {
+            public int compare( IPackageExport o1, IPackageExport o2 )
+            {
+                return o1.compareTo( o2 );
+            }
+        } );
+
+        dialog.setDescriptor( new IElementDescriptor<IPackageExport>()
+        {
+            public String getLabel( IPackageExport element )
+            {
+                return getName( element ) + " (" + element.getVersion().toString() + ")";
+            }
+
+
+            public String getName( IPackageExport element )
+            {
+                return element.getPackageName();
+            }
+        } );
+
+        dialog.setLabelProvider( new WrappedContentProposalLabelProvider<IPackageExport>( dialog.getDescriptor() ) );
+
+        if ( selected != null )
+        {
+            dialog.setSelectedName( selected.getPackageName() );
+            dialog.setVersions( selected.getVersions() );
+            dialog.setOptional( selected.isOptional() );
+        }
+
+        IJobRunnable job = new ExportedPackageFinder( sigil, dialog );
+        dialog.addBackgroundJob( "Scanning for exports in workspace", job );
+
+        return dialog;
+    }
+
+
+    public static NewPackageExportDialog createNewExportDialog( Shell shell, String title,
+        final IPackageExport selected, final ISigilProjectModel project, boolean multiSelect )
+    {
+        IFilter<IJavaElement> selectFilter = new IFilter<IJavaElement>()
+        {
+            public boolean select( IJavaElement e )
+            {
+                if ( selected != null && e.getElementName().equals( selected.getPackageName() ) )
+                {
+                    return true;
+                }
+
+                if ( e.getElementName().trim().length() > 0 && isLocal( e ) )
+                {
+                    for ( IPackageExport p : project.getBundle().getBundleInfo().getExports() )
+                    {
+                        if ( p.getPackageName().equals( e.getElementName() ) )
+                        {
+                            return false;
+                        }
+                    }
+
+                    return true;
+                }
+                else
+                {
+                    return false;
+                }
+            }
+
+
+            private boolean isLocal( IJavaElement java )
+            {
+                try
+                {
+                    switch ( java.getElementType() )
+                    {
+                        case IJavaElement.PACKAGE_FRAGMENT:
+                            IPackageFragment fragment = ( IPackageFragment ) java;
+                            return fragment.containsJavaResources();
+                        default:
+                            throw new IllegalStateException( "Unexpected resource type " + java );
+                    }
+                }
+                catch ( JavaModelException e )
+                {
+                    SigilCore.error( "Failed to inspect java element ", e );
+                    return false;
+                }
+            }
+
+        };
+
+        final NewPackageExportDialog dialog = new NewPackageExportDialog( shell, multiSelect );
+        dialog.setFilter( selectFilter );
+
+        dialog.setProjectVersion( project.getVersion() );
+        if ( selected != null )
+        {
+            dialog.setSelectedName( selected.getPackageName() );
+            dialog.setVersion( selected.getRawVersion() );
+        }
+
+        IJobRunnable job = new IJobRunnable()
+        {
+            public IStatus run( IProgressMonitor monitor )
+            {
+                try
+                {
+                    ArrayList<IPackageFragment> list = new ArrayList<IPackageFragment>( UPDATE_BATCH_SIZE );
+                    for ( IJavaElement e : JavaHelper.findTypes( project.getJavaModel(),
+                        IJavaElement.PACKAGE_FRAGMENT_ROOT ) )
+                    {
+                        IPackageFragmentRoot root = ( IPackageFragmentRoot ) e;
+                        if ( project.isInBundleClasspath( root ) )
+                        {
+                            for ( IJavaElement e1 : JavaHelper.findTypes( root, IJavaElement.PACKAGE_FRAGMENT ) )
+                            {
+                                list.add( ( IPackageFragment ) e1 );
+                                if ( list.size() >= UPDATE_BATCH_SIZE )
+                                {
+                                    dialog.addElements( list );
+                                    list.clear();
+                                }
+                            }
+                        }
+                    }
+                    if ( !list.isEmpty() )
+                    {
+                        dialog.addElements( list );
+                    }
+                    return Status.OK_STATUS;
+                }
+                catch ( JavaModelException e )
+                {
+                    return e.getStatus();
+                }
+            }
+        };
+
+        dialog.addBackgroundJob( "Scanning for packages in project", job );
+
+        return dialog;
+    }
+
+
+    public static NewResourceSelectionDialog<IBundleModelElement> createRequiredBundleDialog( Shell shell,
+        String title, final ISigilProjectModel sigil, final IRequiredBundle selected,
+        final Collection<IRequiredBundle> existing )
+    {
+        final Set<String> existingNames = new HashSet<String>();
+        for ( IRequiredBundle existingBundle : existing )
+        {
+            existingNames.add( existingBundle.getSymbolicName() );
+        }
+
+        final NewResourceSelectionDialog<IBundleModelElement> dialog = new NewResourceSelectionDialog<IBundleModelElement>(
+            shell, "Bundle:", false );
+
+        dialog.setDescriptor( new IElementDescriptor<IBundleModelElement>()
+        {
+            public String getLabel( IBundleModelElement element )
+            {
+                return getName( element ) + " (" + element.getVersion() + ")";
+            }
+
+
+            public String getName( IBundleModelElement element )
+            {
+                return element.getSymbolicName();
+            }
+        } );
+
+        dialog
+            .setLabelProvider( new WrappedContentProposalLabelProvider<IBundleModelElement>( dialog.getDescriptor() ) );
+
+        dialog.setFilter( new IFilter<IBundleModelElement>()
+        {
+            public boolean select( IBundleModelElement element )
+            {
+                return !existingNames.contains( element.getSymbolicName() );
+            }
+        } );
+
+        dialog.setComparator( new Comparator<IBundleModelElement>()
+        {
+            public int compare( IBundleModelElement o1, IBundleModelElement o2 )
+            {
+                return o1.getSymbolicName().compareTo( o2.getSymbolicName() );
+            }
+        } );
+
+        if ( selected != null )
+        {
+            dialog.setSelectedName( selected.getSymbolicName() );
+            dialog.setVersions( selected.getVersions() );
+            dialog.setOptional( selected.isOptional() );
+        }
+
+        IJobRunnable job = new IJobRunnable()
+        {
+            public IStatus run( final IProgressMonitor monitor )
+            {
+                final List<IBundleModelElement> bundles = new ArrayList<IBundleModelElement>( UPDATE_BATCH_SIZE );
+                final IModelWalker walker = new IModelWalker()
+                {
+                    //int count = 0;
+                    public boolean visit( IModelElement element )
+                    {
+                        if ( element instanceof IBundleModelElement )
+                        {
+                            IBundleModelElement b = ( IBundleModelElement ) element;
+                            bundles.add( b );
+
+                            if ( bundles.size() >= UPDATE_BATCH_SIZE )
+                            {
+                                dialog.addElements( bundles );
+                                bundles.clear();
+                            }
+                            // no need to recurse further.
+                            return false;
+                        }
+                        return !monitor.isCanceled();
+                    }
+                };
+                SigilCore.getRepositoryManager( sigil ).visit( walker );
+                if ( !bundles.isEmpty() )
+                {
+                    dialog.addElements( bundles );
+                }
+                return Status.OK_STATUS;
+            }
+        };
+
+        dialog.addBackgroundJob( "Scanning for bundles in workspace", job );
+
+        return dialog;
+    }
 }
-
-
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/SingletonSelection.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/SingletonSelection.java
index 49d087e..9a95544 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/SingletonSelection.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/SingletonSelection.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
@@ -26,38 +27,55 @@
 
 import org.eclipse.jface.viewers.IStructuredSelection;
 
+
 @SuppressWarnings("unchecked")
-public class SingletonSelection implements IStructuredSelection {
+public class SingletonSelection implements IStructuredSelection
+{
 
-	private final Object singleton;
-	
-	public SingletonSelection(Object singleton) {
-		this.singleton = singleton;
-	}
+    private final Object singleton;
 
-	public Object getFirstElement() {
-		return singleton;
-	}
 
-	public Iterator iterator() {
-		return Collections.singleton(singleton).iterator();
-	}
+    public SingletonSelection( Object singleton )
+    {
+        this.singleton = singleton;
+    }
 
-	public int size() {
-		return 1;
-	}
 
-	public Object[] toArray() {
-		return new Object[] { singleton };
-	}
+    public Object getFirstElement()
+    {
+        return singleton;
+    }
 
-	public List toList() {
-		ArrayList list = new ArrayList(1);
-		list.add( singleton );
-		return list;
-	}
 
-	public boolean isEmpty() {
-		return false;
-	}
+    public Iterator iterator()
+    {
+        return Collections.singleton( singleton ).iterator();
+    }
+
+
+    public int size()
+    {
+        return 1;
+    }
+
+
+    public Object[] toArray()
+    {
+        return new Object[]
+            { singleton };
+    }
+
+
+    public List toList()
+    {
+        ArrayList list = new ArrayList( 1 );
+        list.add( singleton );
+        return list;
+    }
+
+
+    public boolean isEmpty()
+    {
+        return false;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/WrappedContentProposalLabelProvider.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/WrappedContentProposalLabelProvider.java
index cde3bc1..fa52a0e 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/WrappedContentProposalLabelProvider.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/util/WrappedContentProposalLabelProvider.java
@@ -19,41 +19,55 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.util;
 
+
 import org.apache.felix.sigil.ui.eclipse.ui.editors.project.IElementDescriptor;
 import org.apache.felix.sigil.ui.eclipse.ui.editors.project.WrappedContentProposal;
 import org.eclipse.jface.viewers.LabelProvider;
 import org.eclipse.swt.graphics.Image;
 
-public class WrappedContentProposalLabelProvider<E> extends LabelProvider {
-	
-	private final IElementDescriptor<? super E> descriptor;
-	private final ModelLabelProvider projectLabelProvider;
 
-	public WrappedContentProposalLabelProvider(IElementDescriptor<? super E> descriptor) {
-		this.descriptor = descriptor;
-		projectLabelProvider = new ModelLabelProvider();
-	}
-	
-	@SuppressWarnings("unchecked")
-	private E adapt(Object element) {
-		E result;
-		if(element instanceof WrappedContentProposal<?>) {
-			WrappedContentProposal<?> proposal = (WrappedContentProposal<?>) element;
-			result = (E) proposal.getElement();
-		} else {
-			result = (E) element;
-		}
-		return result;
-	}
-	
-	@Override
-	public Image getImage(Object element) {
-		Object value = adapt(element);
-		return projectLabelProvider.getImage(value);
-	}
-	
-	@Override
-	public String getText(Object element) {
-		return descriptor.getLabel(adapt(element));
-	}
+public class WrappedContentProposalLabelProvider<E> extends LabelProvider
+{
+
+    private final IElementDescriptor<? super E> descriptor;
+    private final ModelLabelProvider projectLabelProvider;
+
+
+    public WrappedContentProposalLabelProvider( IElementDescriptor<? super E> descriptor )
+    {
+        this.descriptor = descriptor;
+        projectLabelProvider = new ModelLabelProvider();
+    }
+
+
+    @SuppressWarnings("unchecked")
+    private E adapt( Object element )
+    {
+        E result;
+        if ( element instanceof WrappedContentProposal<?> )
+        {
+            WrappedContentProposal<?> proposal = ( WrappedContentProposal<?> ) element;
+            result = ( E ) proposal.getElement();
+        }
+        else
+        {
+            result = ( E ) element;
+        }
+        return result;
+    }
+
+
+    @Override
+    public Image getImage( Object element )
+    {
+        Object value = adapt( element );
+        return projectLabelProvider.getImage( value );
+    }
+
+
+    @Override
+    public String getText( Object element )
+    {
+        return descriptor.getLabel( adapt( element ) );
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/ModelElementComparator.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/ModelElementComparator.java
index 5196fba..418683d 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/ModelElementComparator.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/ModelElementComparator.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.views;
 
+
 import org.apache.felix.sigil.model.osgi.IPackageExport;
 import org.apache.felix.sigil.model.osgi.IPackageImport;
 import org.apache.felix.sigil.model.osgi.IRequiredBundle;
@@ -28,68 +29,90 @@
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerComparator;
 
-public class ModelElementComparator extends ViewerComparator {
-	private static final int EXPORT_GROUP = 0;
-	private static final int IMPORT_GROUP = 1;
-	private static final int REQUIRE_GROUP = 2;
-	private static final int OTHER_GROUP = 4;
-	public int category(Object element) {
-		if ( element instanceof IPackageImport ) {
-			return IMPORT_GROUP;
-		}
-		else if ( element instanceof IPackageExport ) {
-			return EXPORT_GROUP;
-		}
-		else if ( element instanceof IRequiredBundle ) {
-			return REQUIRE_GROUP;
-		}
-		else {
-			return OTHER_GROUP;
-		}
-	}
-	@SuppressWarnings("unchecked")
-	@Override
-	public int compare(Viewer viewer, Object e1, Object e2) {
-        int cat1 = category(e1);
-        int cat2 = category(e2);
 
-        if (cat1 != cat2) {
-			return cat1 - cat2;
-		}
-        
-        if ( cat1 == OTHER_GROUP ) {
+public class ModelElementComparator extends ViewerComparator
+{
+    private static final int EXPORT_GROUP = 0;
+    private static final int IMPORT_GROUP = 1;
+    private static final int REQUIRE_GROUP = 2;
+    private static final int OTHER_GROUP = 4;
+
+
+    public int category( Object element )
+    {
+        if ( element instanceof IPackageImport )
+        {
+            return IMPORT_GROUP;
+        }
+        else if ( element instanceof IPackageExport )
+        {
+            return EXPORT_GROUP;
+        }
+        else if ( element instanceof IRequiredBundle )
+        {
+            return REQUIRE_GROUP;
+        }
+        else
+        {
+            return OTHER_GROUP;
+        }
+    }
+
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public int compare( Viewer viewer, Object e1, Object e2 )
+    {
+        int cat1 = category( e1 );
+        int cat2 = category( e2 );
+
+        if ( cat1 != cat2 )
+        {
+            return cat1 - cat2;
+        }
+
+        if ( cat1 == OTHER_GROUP )
+        {
             String name1;
             String name2;
 
-            if (viewer == null || !(viewer instanceof ContentViewer)) {
+            if ( viewer == null || !( viewer instanceof ContentViewer ) )
+            {
                 name1 = e1.toString();
                 name2 = e2.toString();
-            } else {
-                IBaseLabelProvider prov = ((ContentViewer) viewer)
-                        .getLabelProvider();
-                if (prov instanceof ILabelProvider) {
-                    ILabelProvider lprov = (ILabelProvider) prov;
-                    name1 = lprov.getText(e1);
-                    name2 = lprov.getText(e2);
-                } else {
+            }
+            else
+            {
+                IBaseLabelProvider prov = ( ( ContentViewer ) viewer ).getLabelProvider();
+                if ( prov instanceof ILabelProvider )
+                {
+                    ILabelProvider lprov = ( ILabelProvider ) prov;
+                    name1 = lprov.getText( e1 );
+                    name2 = lprov.getText( e2 );
+                }
+                else
+                {
                     name1 = e1.toString();
                     name2 = e2.toString();
                 }
             }
-            if (name1 == null) {
-    			name1 = "";//$NON-NLS-1$
-    		}
-            if (name2 == null) {
-    			name2 = "";//$NON-NLS-1$
-    		}
+            if ( name1 == null )
+            {
+                name1 = "";//$NON-NLS-1$
+            }
+            if ( name2 == null )
+            {
+                name2 = "";//$NON-NLS-1$
+            }
 
             // use the comparator to compare the strings
-            return getComparator().compare(name1, name2);
+            return getComparator().compare( name1, name2 );
         }
-        else {
-        	Comparable c1 = (Comparable) e1;
-        	Comparable c2 = (Comparable) e2;
-        	return c1.compareTo(c2);
+        else
+        {
+            Comparable c1 = ( Comparable ) e1;
+            Comparable c2 = ( Comparable ) e2;
+            return c1.compareTo( c2 );
         }
-	}
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/RepositoryViewPart.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/RepositoryViewPart.java
index 545caf6..6128e63 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/RepositoryViewPart.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/RepositoryViewPart.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.views;
 
+
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -58,263 +59,341 @@
 import org.eclipse.ui.IActionBars;
 import org.eclipse.ui.part.ViewPart;
 
-public class RepositoryViewPart extends ViewPart implements IRepositoryChangeListener {
 
-	public class FindUsersAction extends Action {
-		@Override
-		public String getText() {
-			return "Find Uses";
-		}
+public class RepositoryViewPart extends ViewPart implements IRepositoryChangeListener
+{
 
-		@Override
-		public void run() {
-			ISelection s = treeViewer.getSelection();
-			if ( !s.isEmpty() ) {
-				IStructuredSelection sel = (IStructuredSelection) s;
-				IModelElement e = (IModelElement) sel.getFirstElement();
-				List<IModelElement>	users = ModelHelper.findUsers(e);
-				String msg = null;
-				if ( users.isEmpty() ) {
-					msg = "No users of " + e;
-				}
-				else {
-					StringBuilder b = new StringBuilder();	
-					for ( IModelElement u : users ) {
-						ISigilBundle bndl = u.getAncestor(ISigilBundle.class);
-						b.append( bndl );
-						b.append( "->" );
-						b.append( u );
-						b.append( "\n" );
-					}
-					msg = b.toString();
-				}
-				MessageDialog.openInformation(getViewSite().getShell(), "Information", msg );
-			}
-		}
-	}
+    public class FindUsersAction extends Action
+    {
+        @Override
+        public String getText()
+        {
+            return "Find Uses";
+        }
 
-	class RepositoryAction extends Action {
-		final IBundleRepository rep;
-		final IRepositoryModel model;
-		
-		public RepositoryAction(IBundleRepository rep) {
-			this.rep = rep;
-			this.model = SigilCore.getRepositoryConfiguration().findRepository(rep.getId());
-		}
-		
-		
-		@Override
-		public void run() {
-			treeViewer.setInput(rep);
-			createMenu();
-		}
 
-		@Override
-		public String getText() {
-			String name = model.getName(); 
-			if ( treeViewer.getInput() == rep ) {
-				name = "> " + name;
-			}
-			return name;
-		}
-		
-		@Override
-		public ImageDescriptor getImageDescriptor() {
-			Image img = model.getType().getIcon();
-			if ( img == null ) {
-				return ImageDescriptor.createFromFile(RepositoryViewPart.class, "/icons/jars_obj.png");
-			}
-			else {
-				return ImageDescriptor.createFromImage(img);
-			}
-		}
-	}
-	
-	class RefreshAction extends Action {
-		@Override
-		public void run() {
-			IBundleRepository rep = (IBundleRepository) treeViewer.getInput();
-			if ( rep != null ) {
-				rep.refresh();
-				treeViewer.refresh();
-			}
-		}
+        @Override
+        public void run()
+        {
+            ISelection s = treeViewer.getSelection();
+            if ( !s.isEmpty() )
+            {
+                IStructuredSelection sel = ( IStructuredSelection ) s;
+                IModelElement e = ( IModelElement ) sel.getFirstElement();
+                List<IModelElement> users = ModelHelper.findUsers( e );
+                String msg = null;
+                if ( users.isEmpty() )
+                {
+                    msg = "No users of " + e;
+                }
+                else
+                {
+                    StringBuilder b = new StringBuilder();
+                    for ( IModelElement u : users )
+                    {
+                        ISigilBundle bndl = u.getAncestor( ISigilBundle.class );
+                        b.append( bndl );
+                        b.append( "->" );
+                        b.append( u );
+                        b.append( "\n" );
+                    }
+                    msg = b.toString();
+                }
+                MessageDialog.openInformation( getViewSite().getShell(), "Information", msg );
+            }
+        }
+    }
 
-		@Override
-		public String getText() {
-			return "Refresh";
-		}
-		
-		@Override
-		public ImageDescriptor getImageDescriptor() {
-			return ImageDescriptor.createFromFile(RepositoryViewPart.class, "/icons/refreshBundle.png");
-		}
+    class RepositoryAction extends Action
+    {
+        final IBundleRepository rep;
+        final IRepositoryModel model;
 
-	}
 
-	private TreeViewer treeViewer;
+        public RepositoryAction( IBundleRepository rep )
+        {
+            this.rep = rep;
+            this.model = SigilCore.getRepositoryConfiguration().findRepository( rep.getId() );
+        }
 
-	@Override
-	public void createPartControl(Composite parent) {
-		createBody(parent);
-		createMenu();
-		SigilCore.getGlobalRepositoryManager().addRepositoryChangeListener(this);
-	}
 
-	@Override
-	public void dispose() {
-		SigilCore.getGlobalRepositoryManager().removeRepositoryChangeListener(this);
-		super.dispose();
-	}
+        @Override
+        public void run()
+        {
+            treeViewer.setInput( rep );
+            createMenu();
+        }
 
-	private void createMenu() {
-		createTopMenu();
-		createLocalMenu();
-	}
 
-	private void createLocalMenu() {
-		/*MenuManager menuMgr = new MenuManager();
-		menuMgr.add( new FindUsersAction() );
-		Menu menu = menuMgr.createContextMenu(treeViewer.getControl());
+        @Override
+        public String getText()
+        {
+            String name = model.getName();
+            if ( treeViewer.getInput() == rep )
+            {
+                name = "> " + name;
+            }
+            return name;
+        }
 
-		treeViewer.getControl().setMenu(menu);
-		getViewSite().registerContextMenu(menuMgr, treeViewer); */
-		IActionBars bars = getViewSite().getActionBars();
-		IToolBarManager toolBar = bars.getToolBarManager();
-		toolBar.add( new RefreshAction() );
-	}
 
-	private void createTopMenu() {
-		IActionBars bars = getViewSite().getActionBars();
-		IMenuManager menu = bars.getMenuManager();
-		menu.removeAll();
-		for ( final IBundleRepository rep : SigilCore.getGlobalRepositoryManager().getRepositories() ) {
-			if ( treeViewer.getInput() == null ) {
-				treeViewer.setInput(rep);
-			}
-			
-			RepositoryAction action = new RepositoryAction(rep);
-			menu.add( action );			
-		}
-	}
+        @Override
+        public ImageDescriptor getImageDescriptor()
+        {
+            Image img = model.getType().getIcon();
+            if ( img == null )
+            {
+                return ImageDescriptor.createFromFile( RepositoryViewPart.class, "/icons/jars_obj.png" );
+            }
+            else
+            {
+                return ImageDescriptor.createFromImage( img );
+            }
+        }
+    }
 
-	private void createBody(Composite parent) {
-		// components
-		Composite control = new Composite(parent, SWT.NONE);
-		Tree tree = new Tree(control, SWT.NONE);
-		
-		// layout
-		control.setLayout( new GridLayout(1, false ) );
-		tree.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1) );
-		
-		// viewer
-		treeViewer = new TreeViewer(tree);
-		treeViewer.setContentProvider( new DefaultTreeContentProvider() {
-			public Object[] getChildren(Object parentElement) {
-				if ( parentElement instanceof ICompoundModelElement ) {
-					ICompoundModelElement model = (ICompoundModelElement) parentElement;
-					return model.children();
-				}
-				
-				return null;
-			}
+    class RefreshAction extends Action
+    {
+        @Override
+        public void run()
+        {
+            IBundleRepository rep = ( IBundleRepository ) treeViewer.getInput();
+            if ( rep != null )
+            {
+                rep.refresh();
+                treeViewer.refresh();
+            }
+        }
 
-			public Object getParent(Object element) {
-				if ( element instanceof IModelElement ) {
-					IModelElement model = (IModelElement) element;
-					return model.getParent();
-				}
-				
-				return null;
-			}
 
-			public boolean hasChildren(Object element) {
-				if ( element instanceof ICompoundModelElement ) {
-					ICompoundModelElement model = (ICompoundModelElement) element;
-					return model.children().length > 0;
-				}
-				return false;
-			}
+        @Override
+        public String getText()
+        {
+            return "Refresh";
+        }
 
-			public Object[] getElements(Object inputElement) {
-				IBundleRepository rep = (IBundleRepository) inputElement;
-				return getBundles(rep);
-			}
-		});
-		
-		treeViewer.setComparator( new ModelElementComparator() );
-		
-		treeViewer.setLabelProvider( new ModelLabelProvider() );
-		
-		treeViewer.addDragSupport(DND.DROP_LINK, new Transfer[] { LocalSelectionTransfer.getTransfer() }, new DragSourceAdapter() {
-			@Override
-			public void dragFinished(DragSourceEvent event) {
-				// TODO Auto-generated method stub
-				super.dragFinished(event);
-			}
 
-			@Override
-			public void dragSetData(DragSourceEvent event) {
-				// TODO Auto-generated method stub
-				super.dragSetData(event);
-			}
+        @Override
+        public ImageDescriptor getImageDescriptor()
+        {
+            return ImageDescriptor.createFromFile( RepositoryViewPart.class, "/icons/refreshBundle.png" );
+        }
 
-			@SuppressWarnings("unchecked")
-			@Override
-			public void dragStart(DragSourceEvent event) {
-				if ( treeViewer.getSelection().isEmpty() ) {
-					IStructuredSelection sel = (IStructuredSelection) treeViewer.getSelection();
-					for ( Iterator<IModelElement> i = sel.iterator(); i.hasNext(); ) {
-						IModelElement e = i.next();
-						if ( e instanceof ISigilBundle ) {
-							event.data = e;
-						}
-						else {
-							event.doit = false;
-						}
-					}
-				}
-				else {
-					event.doit = false;
-				}
-			}
-		});
-	}
+    }
 
-	@Override
-	public void setFocus() {
-	}
+    private TreeViewer treeViewer;
 
-	public void repositoryChanged(RepositoryChangeEvent event) {
-		switch ( event.getType() ) {
-		case ADDED:
-			createTopMenu();
-			break;
-		case CHANGED:
-			if ( event.getRepository() == treeViewer.getInput() ) {
-				SigilUI.runInUI( new Runnable() {
-					public void run() {
-						treeViewer.refresh();
-					} 					
-				} );
-			}
-			break;
-		case REMOVED:
-			if ( event.getRepository() == treeViewer.getInput() ) {
-				treeViewer.setInput(null);
-			}
-			createTopMenu();
-		}
-	}
-	
-	private Object[] getBundles(IBundleRepository repository) {
-		final LinkedList<ISigilBundle> bundles = new LinkedList<ISigilBundle>();
-		repository.accept(new IRepositoryVisitor() {
-			public boolean visit(ISigilBundle bundle) {
-				bundles.add(bundle);
-				return true;
-			}
-		});
-		return bundles.toArray();
-	}
+
+    @Override
+    public void createPartControl( Composite parent )
+    {
+        createBody( parent );
+        createMenu();
+        SigilCore.getGlobalRepositoryManager().addRepositoryChangeListener( this );
+    }
+
+
+    @Override
+    public void dispose()
+    {
+        SigilCore.getGlobalRepositoryManager().removeRepositoryChangeListener( this );
+        super.dispose();
+    }
+
+
+    private void createMenu()
+    {
+        createTopMenu();
+        createLocalMenu();
+    }
+
+
+    private void createLocalMenu()
+    {
+        /*MenuManager menuMgr = new MenuManager();
+        menuMgr.add( new FindUsersAction() );
+        Menu menu = menuMgr.createContextMenu(treeViewer.getControl());
+
+        treeViewer.getControl().setMenu(menu);
+        getViewSite().registerContextMenu(menuMgr, treeViewer); */
+        IActionBars bars = getViewSite().getActionBars();
+        IToolBarManager toolBar = bars.getToolBarManager();
+        toolBar.add( new RefreshAction() );
+    }
+
+
+    private void createTopMenu()
+    {
+        IActionBars bars = getViewSite().getActionBars();
+        IMenuManager menu = bars.getMenuManager();
+        menu.removeAll();
+        for ( final IBundleRepository rep : SigilCore.getGlobalRepositoryManager().getRepositories() )
+        {
+            if ( treeViewer.getInput() == null )
+            {
+                treeViewer.setInput( rep );
+            }
+
+            RepositoryAction action = new RepositoryAction( rep );
+            menu.add( action );
+        }
+    }
+
+
+    private void createBody( Composite parent )
+    {
+        // components
+        Composite control = new Composite( parent, SWT.NONE );
+        Tree tree = new Tree( control, SWT.NONE );
+
+        // layout
+        control.setLayout( new GridLayout( 1, false ) );
+        tree.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true, 1, 1 ) );
+
+        // viewer
+        treeViewer = new TreeViewer( tree );
+        treeViewer.setContentProvider( new DefaultTreeContentProvider()
+        {
+            public Object[] getChildren( Object parentElement )
+            {
+                if ( parentElement instanceof ICompoundModelElement )
+                {
+                    ICompoundModelElement model = ( ICompoundModelElement ) parentElement;
+                    return model.children();
+                }
+
+                return null;
+            }
+
+
+            public Object getParent( Object element )
+            {
+                if ( element instanceof IModelElement )
+                {
+                    IModelElement model = ( IModelElement ) element;
+                    return model.getParent();
+                }
+
+                return null;
+            }
+
+
+            public boolean hasChildren( Object element )
+            {
+                if ( element instanceof ICompoundModelElement )
+                {
+                    ICompoundModelElement model = ( ICompoundModelElement ) element;
+                    return model.children().length > 0;
+                }
+                return false;
+            }
+
+
+            public Object[] getElements( Object inputElement )
+            {
+                IBundleRepository rep = ( IBundleRepository ) inputElement;
+                return getBundles( rep );
+            }
+        } );
+
+        treeViewer.setComparator( new ModelElementComparator() );
+
+        treeViewer.setLabelProvider( new ModelLabelProvider() );
+
+        treeViewer.addDragSupport( DND.DROP_LINK, new Transfer[]
+            { LocalSelectionTransfer.getTransfer() }, new DragSourceAdapter()
+        {
+            @Override
+            public void dragFinished( DragSourceEvent event )
+            {
+                // TODO Auto-generated method stub
+                super.dragFinished( event );
+            }
+
+
+            @Override
+            public void dragSetData( DragSourceEvent event )
+            {
+                // TODO Auto-generated method stub
+                super.dragSetData( event );
+            }
+
+
+            @SuppressWarnings("unchecked")
+            @Override
+            public void dragStart( DragSourceEvent event )
+            {
+                if ( treeViewer.getSelection().isEmpty() )
+                {
+                    IStructuredSelection sel = ( IStructuredSelection ) treeViewer.getSelection();
+                    for ( Iterator<IModelElement> i = sel.iterator(); i.hasNext(); )
+                    {
+                        IModelElement e = i.next();
+                        if ( e instanceof ISigilBundle )
+                        {
+                            event.data = e;
+                        }
+                        else
+                        {
+                            event.doit = false;
+                        }
+                    }
+                }
+                else
+                {
+                    event.doit = false;
+                }
+            }
+        } );
+    }
+
+
+    @Override
+    public void setFocus()
+    {
+    }
+
+
+    public void repositoryChanged( RepositoryChangeEvent event )
+    {
+        switch ( event.getType() )
+        {
+            case ADDED:
+                createTopMenu();
+                break;
+            case CHANGED:
+                if ( event.getRepository() == treeViewer.getInput() )
+                {
+                    SigilUI.runInUI( new Runnable()
+                    {
+                        public void run()
+                        {
+                            treeViewer.refresh();
+                        }
+                    } );
+                }
+                break;
+            case REMOVED:
+                if ( event.getRepository() == treeViewer.getInput() )
+                {
+                    treeViewer.setInput( null );
+                }
+                createTopMenu();
+        }
+    }
+
+
+    private Object[] getBundles( IBundleRepository repository )
+    {
+        final LinkedList<ISigilBundle> bundles = new LinkedList<ISigilBundle>();
+        repository.accept( new IRepositoryVisitor()
+        {
+            public boolean visit( ISigilBundle bundle )
+            {
+                bundles.add( bundle );
+                return true;
+            }
+        } );
+        return bundles.toArray();
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleConnectionHighlighter.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleConnectionHighlighter.java
index f320923..754c7fd 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleConnectionHighlighter.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleConnectionHighlighter.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.views.resolution;
 
+
 import java.util.Set;
 
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
@@ -31,89 +32,117 @@
 import org.eclipse.zest.core.widgets.GraphItem;
 import org.eclipse.zest.core.widgets.GraphNode;
 
-public class BundleConnectionHighlighter implements ISelectionChangedListener {
 
-	private BundleResolverView view;
-	
-	public BundleConnectionHighlighter(BundleResolverView view) {
-		this.view = view;
-	}
-	
-	public void selectionChanged(SelectionChangedEvent event) {
-		ISelection selection = event.getSelection();
-		if ( !selection.isEmpty() ) {
-			IStructuredSelection str = (IStructuredSelection) selection;
+public class BundleConnectionHighlighter implements ISelectionChangedListener
+{
 
-			Object sel = str.getFirstElement();
-			
-			if ( sel instanceof ISigilBundle ) {
-				BundleGraph graph = (BundleGraph) view.getBundlegraph();
+    private BundleResolverView view;
 
-				ISigilBundle selected = (ISigilBundle) sel;
-				Set<ISigilBundle> connected = graph.getTargets(selected);
 
-				highlightLinks(graph, selected, connected);
-				highlightBundles(graph, selected, connected);
-			}
-			else if ( sel instanceof Link ) {
-				GraphConnection c = (GraphConnection) findGraphItem(sel);
-				if ( c != null ) {
-					c.unhighlight();
-					c.setHighlightColor(ColorConstants.blue);
-					c.highlight();
-				}
-			}
-		}
-		else {
-			// TODO clear highlights...
-		}
-	}
+    public BundleConnectionHighlighter( BundleResolverView view )
+    {
+        this.view = view;
+    }
 
-	private void highlightBundles(BundleGraph graph, ISigilBundle selected, Set<ISigilBundle> connected) {
-		for ( ISigilBundle bundle : graph.getBundles() ) {
-			GraphNode node = (GraphNode) findGraphItem(bundle);
-			if ( node != null ) {
-				node.unhighlight();
 
-				if ( bundle == selected ) {
-					node.setHighlightColor(ColorConstants.yellow);
-					node.highlight();
-				}
-				else if ( view.isDisplayed(BundleResolverView.DEPENDENTS) ) {
-					if ( connected.contains(bundle) ) {
-						node.setHighlightColor(ColorConstants.lightBlue);
-						node.highlight();
-					}
-				}
-			}
-		}
-	}
-	
-	private void highlightLinks(BundleGraph graph, ISigilBundle selected, Set<ISigilBundle> connected) {
-		for ( Link l : graph.getLinks() ) {
-			GraphConnection c = (GraphConnection) findGraphItem(l);
-			if ( c != null ) {
-				c.unhighlight();
+    public void selectionChanged( SelectionChangedEvent event )
+    {
+        ISelection selection = event.getSelection();
+        if ( !selection.isEmpty() )
+        {
+            IStructuredSelection str = ( IStructuredSelection ) selection;
 
-				if ( view.isDisplayed(BundleResolverView.DEPENDENTS) ) {
-					if ( l.getSource() == selected && connected.contains( l.getTarget() ) ) {
-						c.setHighlightColor(ColorConstants.lightBlue);
-						c.highlight();
-					}
-				}
-			}
-		}
-	}
+            Object sel = str.getFirstElement();
 
-	private GraphItem findGraphItem(Object l) {
-		try {
-			return view.getGraphViewer().findGraphItem(l);
-		}
-		catch (ArrayIndexOutOfBoundsException e) {
-			// temporary fix for issue 
-			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=242523
-			return null;
-		}
-	}
+            if ( sel instanceof ISigilBundle )
+            {
+                BundleGraph graph = ( BundleGraph ) view.getBundlegraph();
+
+                ISigilBundle selected = ( ISigilBundle ) sel;
+                Set<ISigilBundle> connected = graph.getTargets( selected );
+
+                highlightLinks( graph, selected, connected );
+                highlightBundles( graph, selected, connected );
+            }
+            else if ( sel instanceof Link )
+            {
+                GraphConnection c = ( GraphConnection ) findGraphItem( sel );
+                if ( c != null )
+                {
+                    c.unhighlight();
+                    c.setHighlightColor( ColorConstants.blue );
+                    c.highlight();
+                }
+            }
+        }
+        else
+        {
+            // TODO clear highlights...
+        }
+    }
+
+
+    private void highlightBundles( BundleGraph graph, ISigilBundle selected, Set<ISigilBundle> connected )
+    {
+        for ( ISigilBundle bundle : graph.getBundles() )
+        {
+            GraphNode node = ( GraphNode ) findGraphItem( bundle );
+            if ( node != null )
+            {
+                node.unhighlight();
+
+                if ( bundle == selected )
+                {
+                    node.setHighlightColor( ColorConstants.yellow );
+                    node.highlight();
+                }
+                else if ( view.isDisplayed( BundleResolverView.DEPENDENTS ) )
+                {
+                    if ( connected.contains( bundle ) )
+                    {
+                        node.setHighlightColor( ColorConstants.lightBlue );
+                        node.highlight();
+                    }
+                }
+            }
+        }
+    }
+
+
+    private void highlightLinks( BundleGraph graph, ISigilBundle selected, Set<ISigilBundle> connected )
+    {
+        for ( Link l : graph.getLinks() )
+        {
+            GraphConnection c = ( GraphConnection ) findGraphItem( l );
+            if ( c != null )
+            {
+                c.unhighlight();
+
+                if ( view.isDisplayed( BundleResolverView.DEPENDENTS ) )
+                {
+                    if ( l.getSource() == selected && connected.contains( l.getTarget() ) )
+                    {
+                        c.setHighlightColor( ColorConstants.lightBlue );
+                        c.highlight();
+                    }
+                }
+            }
+        }
+    }
+
+
+    private GraphItem findGraphItem( Object l )
+    {
+        try
+        {
+            return view.getGraphViewer().findGraphItem( l );
+        }
+        catch ( ArrayIndexOutOfBoundsException e )
+        {
+            // temporary fix for issue 
+            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=242523
+            return null;
+        }
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraph.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraph.java
index db26f1f..c26b5e9 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraph.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraph.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.views.resolution;
 
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -30,79 +31,102 @@
 import org.apache.felix.sigil.model.IModelElement;
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
 
-public class BundleGraph {
 
-	private HashMap<ISigilBundle, LinkedList<Link>> lookup = new HashMap<ISigilBundle, LinkedList<Link>>();
-	private LinkedList<Link> links = new LinkedList<Link>();
-	private HashSet<ISigilBundle> bundles = new HashSet<ISigilBundle>();
-	
-	public void startResolution(IModelElement requirement) {
-	}
+public class BundleGraph
+{
 
-	public void endResolution(IModelElement requirement, ISigilBundle target) {
-		ISigilBundle source = requirement.getAncestor(ISigilBundle.class);
+    private HashMap<ISigilBundle, LinkedList<Link>> lookup = new HashMap<ISigilBundle, LinkedList<Link>>();
+    private LinkedList<Link> links = new LinkedList<Link>();
+    private HashSet<ISigilBundle> bundles = new HashSet<ISigilBundle>();
 
-		bundles.add(source);
-		bundles.add(target);
 
-		LinkedList<Link> links = lookup.get(source);
+    public void startResolution( IModelElement requirement )
+    {
+    }
 
-		if ( links == null ) {
-			links = new LinkedList<Link>();
-			lookup.put(source, links);
-		}
 
-		Link l = null;
-		for ( Link c : links ) {
-			if ( c.getTarget() == target ) {
-				l = c;
-				break;
-			}
-		}
+    public void endResolution( IModelElement requirement, ISigilBundle target )
+    {
+        ISigilBundle source = requirement.getAncestor( ISigilBundle.class );
 
-		if ( l == null ) {
-			l = new Link(source, target);
-			links.add(l);
-			this.links.add(l);
-		}
+        bundles.add( source );
+        bundles.add( target );
 
-		l.addRequirement(requirement);
-	}
-	
-	public List<Link> getLinks() {
-		return links;
-	}
+        LinkedList<Link> links = lookup.get( source );
 
-	public Set<ISigilBundle> getBundles() {
-		return bundles;
-	}
+        if ( links == null )
+        {
+            links = new LinkedList<Link>();
+            lookup.put( source, links );
+        }
 
-	public Set<ISigilBundle> getTargets(ISigilBundle bundle) {
-		HashSet<ISigilBundle> targets = new HashSet<ISigilBundle>();
-		
-		for ( Link l : getLinks(bundle) ) {
-			targets.add(l.getTarget());
-		}
-		
-		return targets;
-	}
+        Link l = null;
+        for ( Link c : links )
+        {
+            if ( c.getTarget() == target )
+            {
+                l = c;
+                break;
+            }
+        }
 
-	public List<Link> getLinks(ISigilBundle selected) {
-		List<Link> l = lookup.get(selected);
-		return l == null ? Collections.<Link>emptyList() : l;
-	}
+        if ( l == null )
+        {
+            l = new Link( source, target );
+            links.add( l );
+            this.links.add( l );
+        }
 
-	public List<Link> getDependentLinks(ISigilBundle bundle) {
-		ArrayList<Link> found = new ArrayList<Link>(links.size());
-		
-		for  (Link l : links) {
-			if ( l.getTarget() == bundle ) {
-				found.add( l );
-			}
-		}
-		
-		found.trimToSize();
-		
-		return found;
-	}
+        l.addRequirement( requirement );
+    }
+
+
+    public List<Link> getLinks()
+    {
+        return links;
+    }
+
+
+    public Set<ISigilBundle> getBundles()
+    {
+        return bundles;
+    }
+
+
+    public Set<ISigilBundle> getTargets( ISigilBundle bundle )
+    {
+        HashSet<ISigilBundle> targets = new HashSet<ISigilBundle>();
+
+        for ( Link l : getLinks( bundle ) )
+        {
+            targets.add( l.getTarget() );
+        }
+
+        return targets;
+    }
+
+
+    public List<Link> getLinks( ISigilBundle selected )
+    {
+        List<Link> l = lookup.get( selected );
+        return l == null ? Collections.<Link> emptyList() : l;
+    }
+
+
+    public List<Link> getDependentLinks( ISigilBundle bundle )
+    {
+        ArrayList<Link> found = new ArrayList<Link>( links.size() );
+
+        for ( Link l : links )
+        {
+            if ( l.getTarget() == bundle )
+            {
+                found.add( l );
+            }
+        }
+
+        found.trimToSize();
+
+        return found;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraphContentProvider.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraphContentProvider.java
index f319046..fc47ab3 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraphContentProvider.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraphContentProvider.java
@@ -19,33 +19,45 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.views.resolution;
 
+
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.zest.core.viewers.IGraphContentProvider;
 
-public class BundleGraphContentProvider implements IGraphContentProvider {
 
-	public Object[] getElements(Object input) {
-		BundleGraph graph = (BundleGraph) input;
-		return graph.getLinks().toArray();
-	}
+public class BundleGraphContentProvider implements IGraphContentProvider
+{
 
-	public Object getDestination(Object element) {
-		Link l = (Link) element;
-		return l.isSatisfied() ? l.getTarget() : new Link.Unsatisfied();
-	}
+    public Object[] getElements( Object input )
+    {
+        BundleGraph graph = ( BundleGraph ) input;
+        return graph.getLinks().toArray();
+    }
 
-	public Object getSource(Object element) {
-		Link l = (Link) element;
-		return l.getSource();
-	}
 
-	public void dispose() {
-		// TODO Auto-generated method stub
-		
-	}
+    public Object getDestination( Object element )
+    {
+        Link l = ( Link ) element;
+        return l.isSatisfied() ? l.getTarget() : new Link.Unsatisfied();
+    }
 
-	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-		
-	}
+
+    public Object getSource( Object element )
+    {
+        Link l = ( Link ) element;
+        return l.getSource();
+    }
+
+
+    public void dispose()
+    {
+        // TODO Auto-generated method stub
+
+    }
+
+
+    public void inputChanged( Viewer viewer, Object oldInput, Object newInput )
+    {
+
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraphLabelProvider.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraphLabelProvider.java
index ca5041f..ad4e8d6 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraphLabelProvider.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraphLabelProvider.java
@@ -19,57 +19,76 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.views.resolution;
 
+
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
 import org.apache.felix.sigil.ui.eclipse.ui.SigilUI;
 import org.eclipse.jface.viewers.LabelProvider;
 import org.eclipse.swt.graphics.Image;
 
-public class BundleGraphLabelProvider extends LabelProvider {
 
-	private BundleResolverView view;
-	
-	public BundleGraphLabelProvider(BundleResolverView view) {
-		this.view = view;
-	}
+public class BundleGraphLabelProvider extends LabelProvider
+{
 
-	@Override
-	public String getText(Object element) {
-		if ( element instanceof Link ) {
-			Link l = (Link) element;
-			if ( l.isSatisfied() ) {
-				if ( view.isDisplayed(BundleResolverView.LINK_LABELS) ) {
-					return view.getLinkText((Link) element);
-				}
-				else {
-					return "";
-				}
-			}
-			else {
-				return view.getLinkText((Link) element);				
-			}
-		}
-		else if ( element instanceof ISigilBundle ) {
-			ISigilBundle b = (ISigilBundle) element;
-			return b.getBundleInfo().getSymbolicName() + ": " + b.getBundleInfo().getVersion();
-		}
-		else if ( element instanceof Link.Unsatisfied ) {
-			return "unsatisfied";
-		}
-		else {
-			return "unknown:" + element;
-		}
-	}
-	
-	@Override
-	public Image getImage(Object element) {
-		Image result = null;
-		if ( element instanceof ISigilBundle ) {
-			result = SigilUI.cacheImage("icons/jar_obj.png", BundleGraphLabelProvider.class.getClassLoader());
-		}
-		else if ( element instanceof Link.Unsatisfied ) {
-			result = SigilUI.cacheImage("icons/error.gif", BundleGraphLabelProvider.class.getClassLoader());
-		}
-		
-		return result;
-	}	
+    private BundleResolverView view;
+
+
+    public BundleGraphLabelProvider( BundleResolverView view )
+    {
+        this.view = view;
+    }
+
+
+    @Override
+    public String getText( Object element )
+    {
+        if ( element instanceof Link )
+        {
+            Link l = ( Link ) element;
+            if ( l.isSatisfied() )
+            {
+                if ( view.isDisplayed( BundleResolverView.LINK_LABELS ) )
+                {
+                    return view.getLinkText( ( Link ) element );
+                }
+                else
+                {
+                    return "";
+                }
+            }
+            else
+            {
+                return view.getLinkText( ( Link ) element );
+            }
+        }
+        else if ( element instanceof ISigilBundle )
+        {
+            ISigilBundle b = ( ISigilBundle ) element;
+            return b.getBundleInfo().getSymbolicName() + ": " + b.getBundleInfo().getVersion();
+        }
+        else if ( element instanceof Link.Unsatisfied )
+        {
+            return "unsatisfied";
+        }
+        else
+        {
+            return "unknown:" + element;
+        }
+    }
+
+
+    @Override
+    public Image getImage( Object element )
+    {
+        Image result = null;
+        if ( element instanceof ISigilBundle )
+        {
+            result = SigilUI.cacheImage( "icons/jar_obj.png", BundleGraphLabelProvider.class.getClassLoader() );
+        }
+        else if ( element instanceof Link.Unsatisfied )
+        {
+            result = SigilUI.cacheImage( "icons/error.gif", BundleGraphLabelProvider.class.getClassLoader() );
+        }
+
+        return result;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraphViewFilter.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraphViewFilter.java
index 5d55ac8..51f2e76 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraphViewFilter.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleGraphViewFilter.java
@@ -19,52 +19,69 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.views.resolution;
 
+
 import org.apache.felix.sigil.model.eclipse.ISigilBundle;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerFilter;
 
-public class BundleGraphViewFilter extends ViewerFilter {
 
-	private BundleResolverView view;
-	
-	public BundleGraphViewFilter(BundleResolverView view) {
-		this.view = view;
-	}
+public class BundleGraphViewFilter extends ViewerFilter
+{
 
-	@Override
-	public boolean select(Viewer viewer, Object parentElement, Object element) {
-		if ( !view.isDisplayed(BundleResolverView.LOCAL_LINKS) ) {
-			if ( element instanceof Link ) {
-				Link l = (Link) element;
-				return l.getSource() != l.getTarget();
-			}
-		}
-		if ( !view.isDisplayed(BundleResolverView.SATISFIED) ) {
-			if ( element instanceof Link ) {
-				Link l = (Link) element;
-				return !l.isSatisfied();
-			}
-			else if ( element instanceof ISigilBundle ) {
-				ISigilBundle bundle = (ISigilBundle) element;
-				for ( Link l : view.getBundlegraph().getLinks(bundle)) {
-					if ( !l.isSatisfied() ) {
-						return true;
-					}
-				}
-				return false;
-			}
-		}
-		
-		if ( !view.isDisplayed(BundleResolverView.UNSATISFIED) ) {
-			if ( element instanceof Link ) {
-				Link l = (Link) element;
-				return l.isSatisfied();
-			}
-			else if ( element instanceof Link.Unsatisfied ) {
-				return false;
-			}
-		}
-		return true;
-	}
+    private BundleResolverView view;
+
+
+    public BundleGraphViewFilter( BundleResolverView view )
+    {
+        this.view = view;
+    }
+
+
+    @Override
+    public boolean select( Viewer viewer, Object parentElement, Object element )
+    {
+        if ( !view.isDisplayed( BundleResolverView.LOCAL_LINKS ) )
+        {
+            if ( element instanceof Link )
+            {
+                Link l = ( Link ) element;
+                return l.getSource() != l.getTarget();
+            }
+        }
+        if ( !view.isDisplayed( BundleResolverView.SATISFIED ) )
+        {
+            if ( element instanceof Link )
+            {
+                Link l = ( Link ) element;
+                return !l.isSatisfied();
+            }
+            else if ( element instanceof ISigilBundle )
+            {
+                ISigilBundle bundle = ( ISigilBundle ) element;
+                for ( Link l : view.getBundlegraph().getLinks( bundle ) )
+                {
+                    if ( !l.isSatisfied() )
+                    {
+                        return true;
+                    }
+                }
+                return false;
+            }
+        }
+
+        if ( !view.isDisplayed( BundleResolverView.UNSATISFIED ) )
+        {
+            if ( element instanceof Link )
+            {
+                Link l = ( Link ) element;
+                return l.isSatisfied();
+            }
+            else if ( element instanceof Link.Unsatisfied )
+            {
+                return false;
+            }
+        }
+        return true;
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleResolverView.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleResolverView.java
index 0e77c12..d72e18a 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleResolverView.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/BundleResolverView.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.views.resolution;
 
+
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -59,264 +60,340 @@
 import org.eclipse.zest.layouts.algorithms.RadialLayoutAlgorithm;
 import org.eclipse.zest.layouts.algorithms.TreeLayoutAlgorithm;
 
-public class BundleResolverView extends ViewPart {
 
-	private static final String SHOW_LINK_LABELS = "Show link labels";
-	private static final String HIDE_LINK_LABELS = "Hide link labels";
-	private static final String SHOW_LOCAL_LINKS = "Show local links";
-	private static final String HIDE_LOCAL_LINKS = "Hide local links";
-	private static final String SHOW_DEPENDENTS = "Show dependents";
-	private static final String HIDE_DEPENDENTS = "Hide dependents";
-	private static final String SHOW_SATISFIED = "Show satisfied bundles";
-	private static final String HIDE_SATISFIED = "Hide satisfied bundles";
-	private static final String SHOW_UNSATISFIED = "Show unsatisfied bundles";
-	private static final String HIDE_UNSATISFIED = "Hide unsatisfied bundles";
-	private static final String SHOW_OPTIONAL = "Show optional dependencies";
-	private static final String HIDE_OPTIONAL = "Hide optional dependencies";
-	
-	public static final String LINK_LABELS = "link.labels";
-	public static final String LOCAL_LINKS = "local.links";
-	public static final String DEPENDENTS = "dependents";
-	public static final String SATISFIED = "satisified";
-	public static final String UNSATISFIED = "unsatisfied";
-	public static final String OPTIONAL = "optional";
+public class BundleResolverView extends ViewPart
+{
 
-	private GraphViewer viewer;
-	private IModelElement current;
-	private Job job;
-	private int lastX;
-	private int lastY;	
-	
-	private Map<String, Boolean> displayed = new HashMap<String, Boolean>();
-		
-	private class ToggleDisplayAction extends Action {	
-		private String key;
-		private String showMsg;
-		private String hideMsg;
+    private static final String SHOW_LINK_LABELS = "Show link labels";
+    private static final String HIDE_LINK_LABELS = "Hide link labels";
+    private static final String SHOW_LOCAL_LINKS = "Show local links";
+    private static final String HIDE_LOCAL_LINKS = "Hide local links";
+    private static final String SHOW_DEPENDENTS = "Show dependents";
+    private static final String HIDE_DEPENDENTS = "Hide dependents";
+    private static final String SHOW_SATISFIED = "Show satisfied bundles";
+    private static final String HIDE_SATISFIED = "Hide satisfied bundles";
+    private static final String SHOW_UNSATISFIED = "Show unsatisfied bundles";
+    private static final String HIDE_UNSATISFIED = "Hide unsatisfied bundles";
+    private static final String SHOW_OPTIONAL = "Show optional dependencies";
+    private static final String HIDE_OPTIONAL = "Hide optional dependencies";
 
-		ToggleDisplayAction(String key, String showMsg, String hideMsg) {
-			this.key = key;
-			this.showMsg = showMsg;
-			this.hideMsg = hideMsg;
-			setText(BundleResolverView.this.isDisplayed(key) ? hideMsg : showMsg);
-		}
-		
-		@Override
-		public void run() {
-			BundleResolverView.this.setDisplayed( key, !BundleResolverView.this.isDisplayed(key) );
-			setText(BundleResolverView.this.isDisplayed(key) ? hideMsg : showMsg);
-		}
-	}
-	
-	public void setInput(final IModelElement element) {
-		if ( current == null || !current.equals(element) ) {
-			SigilCore.log( "Set input " + element );
-			current = element;
-			redraw();
-		}
-	}
-	
-	public void setDisplayed(String key, boolean b) {
-		displayed.put(key, b);
-		
-		if ( key == DEPENDENTS ) {
-			int style = LayoutStyles.NO_LAYOUT_NODE_RESIZING;
-			viewer.setLayoutAlgorithm( b ? new TreeLayoutAlgorithm(style) : new RadialLayoutAlgorithm(style));
-			redraw();
-		}
-		else if ( key == OPTIONAL ) {
-			redraw();
-		}
-		else if ( key == SATISFIED || key == UNSATISFIED ) {
-			viewer.refresh();
-		}
-	}
+    public static final String LINK_LABELS = "link.labels";
+    public static final String LOCAL_LINKS = "local.links";
+    public static final String DEPENDENTS = "dependents";
+    public static final String SATISFIED = "satisified";
+    public static final String UNSATISFIED = "unsatisfied";
+    public static final String OPTIONAL = "optional";
 
-	public boolean isDisplayed(String key) {
-		return displayed.get(key);
-	}
+    private GraphViewer viewer;
+    private IModelElement current;
+    private Job job;
+    private int lastX;
+    private int lastY;
 
-	@Override
-	public void setFocus() {
-	}
-	
-	@Override
-    public void createPartControl( Composite parent ) {
-		init();
-		createViewer(parent);
-		createListeners();
-		createMenu();
+    private Map<String, Boolean> displayed = new HashMap<String, Boolean>();
+
+    private class ToggleDisplayAction extends Action
+    {
+        private String key;
+        private String showMsg;
+        private String hideMsg;
+
+
+        ToggleDisplayAction( String key, String showMsg, String hideMsg )
+        {
+            this.key = key;
+            this.showMsg = showMsg;
+            this.hideMsg = hideMsg;
+            setText( BundleResolverView.this.isDisplayed( key ) ? hideMsg : showMsg );
+        }
+
+
+        @Override
+        public void run()
+        {
+            BundleResolverView.this.setDisplayed( key, !BundleResolverView.this.isDisplayed( key ) );
+            setText( BundleResolverView.this.isDisplayed( key ) ? hideMsg : showMsg );
+        }
     }
-	
-	private void init() {
-		displayed.put(LINK_LABELS, false);
-		displayed.put(LOCAL_LINKS, false);
-		displayed.put(DEPENDENTS, false);
-		displayed.put(OPTIONAL, false);
-		displayed.put(SATISFIED, true);
-		displayed.put(UNSATISFIED, true);
-	}
 
-	public BundleGraph getBundlegraph() {
-		return (BundleGraph) viewer.getInput();
-	}
 
-	GraphViewer getGraphViewer() {
-		return viewer;
-	}
+    public void setInput( final IModelElement element )
+    {
+        if ( current == null || !current.equals( element ) )
+        {
+            SigilCore.log( "Set input " + element );
+            current = element;
+            redraw();
+        }
+    }
 
-	String getLinkText(Link link) {
-		StringBuffer buf = new StringBuffer();
 
-		for ( IModelElement e : link.getRequirements() ) {
-			if ( buf.length() > 0 ) {
-				buf.append( "\n" );
-			}
-			if ( e instanceof IPackageImport ) {
-				IPackageImport pi = (IPackageImport) e;
-				buf.append( "import " + pi.getPackageName() + " : " + pi.getVersions() + ": " + (pi.isOptional() ? "optional" : "mandatory" ) );
-			}
-			else if ( e instanceof IRequiredBundle ) {
-				IRequiredBundle rb = (IRequiredBundle) e;
-				buf.append( "required bundle " + rb.getSymbolicName() + " : " + rb.getVersions() + ": " + (rb.isOptional() ? "optional" : "mandatory" ) );
-			}
-		}
-		
-		return buf.toString();
-	}	
+    public void setDisplayed( String key, boolean b )
+    {
+        displayed.put( key, b );
 
-	private synchronized void redraw() {
-		final IModelElement element = current;
-		if ( job != null ) {
-			job.cancel();
-		}
-		
-		job = new Job("Resolving " + current) {
-			@Override
-			protected IStatus run(IProgressMonitor progress) {
-				try {
-					resolve(element, progress);
-					return Status.OK_STATUS;
-				} catch (CoreException e) {
-					return e.getStatus();
-				}
-			}
-		};
-		job.schedule();
-	}
+        if ( key == DEPENDENTS )
+        {
+            int style = LayoutStyles.NO_LAYOUT_NODE_RESIZING;
+            viewer.setLayoutAlgorithm( b ? new TreeLayoutAlgorithm( style ) : new RadialLayoutAlgorithm( style ) );
+            redraw();
+        }
+        else if ( key == OPTIONAL )
+        {
+            redraw();
+        }
+        else if ( key == SATISFIED || key == UNSATISFIED )
+        {
+            viewer.refresh();
+        }
+    }
 
-	private void resolve(IModelElement element, IProgressMonitor progress) throws CoreException {
-		final BundleGraph graph = new BundleGraph();
-		
-		IResolutionMonitor monitor = new ResolutionMonitorAdapter(progress) {
-			@Override
-			public void startResolution(IModelElement requirement) {
-				graph.startResolution(requirement);
-			}
 
-			@Override
-			public void endResolution(IModelElement requirement, ISigilBundle provider) {
-				graph.endResolution(requirement, provider);
-			}
-		};
+    public boolean isDisplayed( String key )
+    {
+        return displayed.get( key );
+    }
 
-		ISigilProjectModel project = findProject(element);
-		IRepositoryManager repository = SigilCore.getRepositoryManager(project);
-		
-		int options = ResolutionConfig.IGNORE_ERRORS;
-		
-		if ( isDisplayed(DEPENDENTS) ) {
-			options |= ResolutionConfig.INCLUDE_DEPENDENTS;
-		}
-		if ( isDisplayed(OPTIONAL) ) {
-			options |= ResolutionConfig.INCLUDE_OPTIONAL;
-		}
-		
-		ResolutionConfig config = new ResolutionConfig(options);
-		
-		try {
-			repository.getBundleResolver().resolve(element, config, monitor);
-		} catch (ResolutionException e) {
-			throw SigilCore.newCoreException("Failed to resolve " + element, e);
-		}
-		
-		SigilUI.runInUI( new Runnable() {
-			public void run() {
-				viewer.setInput(graph);
-				addCustomUIElements();
-			}			
-		} );
-	}
 
-	private static ISigilProjectModel findProject(IModelElement element) {
-		if ( element == null ) {
-			return null;
-		}
-		if ( element instanceof ISigilProjectModel ) {
-			return (ISigilProjectModel) element;
-		}
-		
-		return element.getAncestor(ISigilProjectModel.class);
-	}
+    @Override
+    public void setFocus()
+    {
+    }
 
-	@SuppressWarnings("unchecked")
-	private void addCustomUIElements() {
-		if ( !isDisplayed(LINK_LABELS) ) {
-			for ( GraphConnection c : (List<GraphConnection>) viewer.getGraphControl().getConnections() ) {
-				if ( c.getData() instanceof Link ) {
-					c.setTooltip(buildToolTip((Link) c.getData()));
-				}
-			}
-		}
-	}
 
-	private IFigure buildToolTip(Link link) {
-		Label l = new Label();
-		l.setText(getLinkText(link));
-		return l;
-	}
+    @Override
+    public void createPartControl( Composite parent )
+    {
+        init();
+        createViewer( parent );
+        createListeners();
+        createMenu();
+    }
 
-	private void createViewer(Composite parent) {
-		parent.setLayout( new FillLayout() );
-    	viewer = new GraphViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL);
-    	IContentProvider contentProvider = new BundleGraphContentProvider();
-		viewer.setContentProvider(contentProvider);
-		viewer.setLabelProvider(new BundleGraphLabelProvider(this));
-		viewer.addFilter( new BundleGraphViewFilter(this) );
-		
-		
-		int style = LayoutStyles.NO_LAYOUT_NODE_RESIZING;
-		viewer.setLayoutAlgorithm( isDisplayed(DEPENDENTS) ? new TreeLayoutAlgorithm(style) : new RadialLayoutAlgorithm(style));
-		viewer.addSelectionChangedListener( new BundleConnectionHighlighter(this) );
-		viewer.setInput(new BundleGraph());
-	}
 
-	private void createMenu() {
-		IActionBars action = getViewSite().getActionBars(); 
-		action.getMenuManager().add(new ToggleDisplayAction( LINK_LABELS, SHOW_LINK_LABELS, HIDE_LINK_LABELS ));
-		action.getMenuManager().add(new ToggleDisplayAction( LOCAL_LINKS, SHOW_LOCAL_LINKS, HIDE_LOCAL_LINKS ));
-		action.getMenuManager().add(new ToggleDisplayAction( DEPENDENTS, SHOW_DEPENDENTS, HIDE_DEPENDENTS ));
-		action.getMenuManager().add(new ToggleDisplayAction( OPTIONAL, SHOW_OPTIONAL, HIDE_OPTIONAL ));
-		action.getMenuManager().add(new ToggleDisplayAction( SATISFIED, SHOW_SATISFIED, HIDE_SATISFIED ));
-		action.getMenuManager().add(new ToggleDisplayAction( UNSATISFIED, SHOW_UNSATISFIED, HIDE_UNSATISFIED ));
-		action.updateActionBars();
-	}
+    private void init()
+    {
+        displayed.put( LINK_LABELS, false );
+        displayed.put( LOCAL_LINKS, false );
+        displayed.put( DEPENDENTS, false );
+        displayed.put( OPTIONAL, false );
+        displayed.put( SATISFIED, true );
+        displayed.put( UNSATISFIED, true );
+    }
 
-	private void createListeners() {
-		IPartService ps = (IPartService) getViewSite().getService(IPartService.class);
-		ps.addPartListener( new EditorViewPartListener(this) );
-		viewer.getGraphControl().addControlListener( new ControlAdapter() {
-			@Override
-			public void controlResized(ControlEvent e) {
-				Graph g = (Graph) e.getSource();
-				int x = g.getSize().x;
-				int y = g.getSize().y;
-				if ( lastX != x || lastY != y ) {
-					lastX = x;
-					lastY = y;
-					redraw();
-				}
-			}
-		} );
-	}
+
+    public BundleGraph getBundlegraph()
+    {
+        return ( BundleGraph ) viewer.getInput();
+    }
+
+
+    GraphViewer getGraphViewer()
+    {
+        return viewer;
+    }
+
+
+    String getLinkText( Link link )
+    {
+        StringBuffer buf = new StringBuffer();
+
+        for ( IModelElement e : link.getRequirements() )
+        {
+            if ( buf.length() > 0 )
+            {
+                buf.append( "\n" );
+            }
+            if ( e instanceof IPackageImport )
+            {
+                IPackageImport pi = ( IPackageImport ) e;
+                buf.append( "import " + pi.getPackageName() + " : " + pi.getVersions() + ": "
+                    + ( pi.isOptional() ? "optional" : "mandatory" ) );
+            }
+            else if ( e instanceof IRequiredBundle )
+            {
+                IRequiredBundle rb = ( IRequiredBundle ) e;
+                buf.append( "required bundle " + rb.getSymbolicName() + " : " + rb.getVersions() + ": "
+                    + ( rb.isOptional() ? "optional" : "mandatory" ) );
+            }
+        }
+
+        return buf.toString();
+    }
+
+
+    private synchronized void redraw()
+    {
+        final IModelElement element = current;
+        if ( job != null )
+        {
+            job.cancel();
+        }
+
+        job = new Job( "Resolving " + current )
+        {
+            @Override
+            protected IStatus run( IProgressMonitor progress )
+            {
+                try
+                {
+                    resolve( element, progress );
+                    return Status.OK_STATUS;
+                }
+                catch ( CoreException e )
+                {
+                    return e.getStatus();
+                }
+            }
+        };
+        job.schedule();
+    }
+
+
+    private void resolve( IModelElement element, IProgressMonitor progress ) throws CoreException
+    {
+        final BundleGraph graph = new BundleGraph();
+
+        IResolutionMonitor monitor = new ResolutionMonitorAdapter( progress )
+        {
+            @Override
+            public void startResolution( IModelElement requirement )
+            {
+                graph.startResolution( requirement );
+            }
+
+
+            @Override
+            public void endResolution( IModelElement requirement, ISigilBundle provider )
+            {
+                graph.endResolution( requirement, provider );
+            }
+        };
+
+        ISigilProjectModel project = findProject( element );
+        IRepositoryManager repository = SigilCore.getRepositoryManager( project );
+
+        int options = ResolutionConfig.IGNORE_ERRORS;
+
+        if ( isDisplayed( DEPENDENTS ) )
+        {
+            options |= ResolutionConfig.INCLUDE_DEPENDENTS;
+        }
+        if ( isDisplayed( OPTIONAL ) )
+        {
+            options |= ResolutionConfig.INCLUDE_OPTIONAL;
+        }
+
+        ResolutionConfig config = new ResolutionConfig( options );
+
+        try
+        {
+            repository.getBundleResolver().resolve( element, config, monitor );
+        }
+        catch ( ResolutionException e )
+        {
+            throw SigilCore.newCoreException( "Failed to resolve " + element, e );
+        }
+
+        SigilUI.runInUI( new Runnable()
+        {
+            public void run()
+            {
+                viewer.setInput( graph );
+                addCustomUIElements();
+            }
+        } );
+    }
+
+
+    private static ISigilProjectModel findProject( IModelElement element )
+    {
+        if ( element == null )
+        {
+            return null;
+        }
+        if ( element instanceof ISigilProjectModel )
+        {
+            return ( ISigilProjectModel ) element;
+        }
+
+        return element.getAncestor( ISigilProjectModel.class );
+    }
+
+
+    @SuppressWarnings("unchecked")
+    private void addCustomUIElements()
+    {
+        if ( !isDisplayed( LINK_LABELS ) )
+        {
+            for ( GraphConnection c : ( List<GraphConnection> ) viewer.getGraphControl().getConnections() )
+            {
+                if ( c.getData() instanceof Link )
+                {
+                    c.setTooltip( buildToolTip( ( Link ) c.getData() ) );
+                }
+            }
+        }
+    }
+
+
+    private IFigure buildToolTip( Link link )
+    {
+        Label l = new Label();
+        l.setText( getLinkText( link ) );
+        return l;
+    }
+
+
+    private void createViewer( Composite parent )
+    {
+        parent.setLayout( new FillLayout() );
+        viewer = new GraphViewer( parent, SWT.H_SCROLL | SWT.V_SCROLL );
+        IContentProvider contentProvider = new BundleGraphContentProvider();
+        viewer.setContentProvider( contentProvider );
+        viewer.setLabelProvider( new BundleGraphLabelProvider( this ) );
+        viewer.addFilter( new BundleGraphViewFilter( this ) );
+
+        int style = LayoutStyles.NO_LAYOUT_NODE_RESIZING;
+        viewer.setLayoutAlgorithm( isDisplayed( DEPENDENTS ) ? new TreeLayoutAlgorithm( style )
+            : new RadialLayoutAlgorithm( style ) );
+        viewer.addSelectionChangedListener( new BundleConnectionHighlighter( this ) );
+        viewer.setInput( new BundleGraph() );
+    }
+
+
+    private void createMenu()
+    {
+        IActionBars action = getViewSite().getActionBars();
+        action.getMenuManager().add( new ToggleDisplayAction( LINK_LABELS, SHOW_LINK_LABELS, HIDE_LINK_LABELS ) );
+        action.getMenuManager().add( new ToggleDisplayAction( LOCAL_LINKS, SHOW_LOCAL_LINKS, HIDE_LOCAL_LINKS ) );
+        action.getMenuManager().add( new ToggleDisplayAction( DEPENDENTS, SHOW_DEPENDENTS, HIDE_DEPENDENTS ) );
+        action.getMenuManager().add( new ToggleDisplayAction( OPTIONAL, SHOW_OPTIONAL, HIDE_OPTIONAL ) );
+        action.getMenuManager().add( new ToggleDisplayAction( SATISFIED, SHOW_SATISFIED, HIDE_SATISFIED ) );
+        action.getMenuManager().add( new ToggleDisplayAction( UNSATISFIED, SHOW_UNSATISFIED, HIDE_UNSATISFIED ) );
+        action.updateActionBars();
+    }
+
+
+    private void createListeners()
+    {
+        IPartService ps = ( IPartService ) getViewSite().getService( IPartService.class );
+        ps.addPartListener( new EditorViewPartListener( this ) );
+        viewer.getGraphControl().addControlListener( new ControlAdapter()
+        {
+            @Override
+            public void controlResized( ControlEvent e )
+            {
+                Graph g = ( Graph ) e.getSource();
+                int x = g.getSize().x;
+                int y = g.getSize().y;
+                if ( lastX != x || lastY != y )
+                {
+                    lastX = x;
+                    lastY = y;
+                    redraw();
+                }
+            }
+        } );
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/EditorViewPartListener.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/EditorViewPartListener.java
index ad1f7ea..117f88d 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/EditorViewPartListener.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/EditorViewPartListener.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.views.resolution;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
 import org.eclipse.core.resources.IProject;
@@ -29,64 +30,92 @@
 import org.eclipse.ui.IPartListener2;
 import org.eclipse.ui.IWorkbenchPartReference;
 
-public class EditorViewPartListener implements IPartListener2 {
 
-	private BundleResolverView bundleResolverView;
-	
-	public EditorViewPartListener(BundleResolverView bundleResolverView) {
-		this.bundleResolverView = bundleResolverView;
-	}
+public class EditorViewPartListener implements IPartListener2
+{
 
-	public void partActivated(IWorkbenchPartReference partRef) {
-		checkRef(partRef);
-	}
+    private BundleResolverView bundleResolverView;
 
-	public void partBroughtToTop(IWorkbenchPartReference partRef) {
-		// no action
-	}
 
-	public void partClosed(IWorkbenchPartReference partRef) {
-		// no action
-	}
+    public EditorViewPartListener( BundleResolverView bundleResolverView )
+    {
+        this.bundleResolverView = bundleResolverView;
+    }
 
-	public void partDeactivated(IWorkbenchPartReference partRef) {
-		// no action
-	}
 
-	public void partHidden(IWorkbenchPartReference partRef) {
-		// no action
-	}
+    public void partActivated( IWorkbenchPartReference partRef )
+    {
+        checkRef( partRef );
+    }
 
-	public void partInputChanged(IWorkbenchPartReference partRef) {
-		// no action
-	}
 
-	public void partOpened(IWorkbenchPartReference partRef) {
-		// no action
-	}
+    public void partBroughtToTop( IWorkbenchPartReference partRef )
+    {
+        // no action
+    }
 
-	public void partVisible(IWorkbenchPartReference partRef) {
-		// no action
-	}
 
-	private void checkRef(IWorkbenchPartReference partRef) {
-		IEditorPart editor = partRef.getPage().getActiveEditor();
-		if ( editor != null ) {
-			IEditorInput input = editor.getEditorInput();
-			if ( input instanceof IFileEditorInput ) {
-				IFileEditorInput f = (IFileEditorInput) input;
-				IProject project = f.getFile().getProject();
-				try {
-					ISigilProjectModel model = SigilCore.create(project);
-					if ( model != null ) {
-						bundleResolverView.setInput(model);
-					}
-				} catch (CoreException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-			}
-		}
-	}
+    public void partClosed( IWorkbenchPartReference partRef )
+    {
+        // no action
+    }
+
+
+    public void partDeactivated( IWorkbenchPartReference partRef )
+    {
+        // no action
+    }
+
+
+    public void partHidden( IWorkbenchPartReference partRef )
+    {
+        // no action
+    }
+
+
+    public void partInputChanged( IWorkbenchPartReference partRef )
+    {
+        // no action
+    }
+
+
+    public void partOpened( IWorkbenchPartReference partRef )
+    {
+        // no action
+    }
+
+
+    public void partVisible( IWorkbenchPartReference partRef )
+    {
+        // no action
+    }
+
+
+    private void checkRef( IWorkbenchPartReference partRef )
+    {
+        IEditorPart editor = partRef.getPage().getActiveEditor();
+        if ( editor != null )
+        {
+            IEditorInput input = editor.getEditorInput();
+            if ( input instanceof IFileEditorInput )
+            {
+                IFileEditorInput f = ( IFileEditorInput ) input;
+                IProject project = f.getFile().getProject();
+                try
+                {
+                    ISigilProjectModel model = SigilCore.create( project );
+                    if ( model != null )
+                    {
+                        bundleResolverView.setInput( model );
+                    }
+                }
+                catch ( CoreException e )
+                {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
 
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/Link.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/Link.java
index 9550a2f..a4f1890 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/Link.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/views/resolution/Link.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.views.resolution;
 
+
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.LinkedList;
@@ -29,110 +30,154 @@
 import org.apache.felix.sigil.model.osgi.IPackageImport;
 import org.apache.felix.sigil.model.osgi.IRequiredBundle;
 
-public class Link {	
-	public static class Unsatisfied {
 
-	}
+public class Link
+{
+    public static class Unsatisfied
+    {
 
-	private ISigilBundle source;
-	private ISigilBundle target;
-	
-	private LinkedList<IModelElement> requirements = new LinkedList<IModelElement>();
-	private static final Comparator<IModelElement> comparator = new Comparator<IModelElement>() {
+    }
 
-		public int compare(IModelElement o1, IModelElement o2) {
-			if (o1 instanceof IRequiredBundle) {
-				if ( o2 instanceof IRequiredBundle) {
-					return compareBundles( (IRequiredBundle) o1, (IRequiredBundle) o2 );
-				}
-				else {
-					return -1;
-				}
-			}
-			else {
-				if ( o2 instanceof IRequiredBundle ) {
-					return 1;
-				}
-				else {
-					return compareNonBundles( o1, o2 );
-				}
-			}
-		}
+    private ISigilBundle source;
+    private ISigilBundle target;
 
-		private int compareNonBundles(IModelElement o1, IModelElement o2) {
-			if (o1 instanceof IPackageImport) {
-				if ( o2 instanceof IPackageImport) {
-					return compareImports( (IPackageImport) o1, (IPackageImport) o2 );
-				}
-				else {
-					return -1;
-				}
-			}
-			else {
-				if ( o2 instanceof IPackageImport ) {
-					return 1;
-				}
-				else {
-					return 0;
-				}
-			}
-		}
+    private LinkedList<IModelElement> requirements = new LinkedList<IModelElement>();
+    private static final Comparator<IModelElement> comparator = new Comparator<IModelElement>()
+    {
 
-		private int compareImports(IPackageImport o1, IPackageImport o2) {
-			return o1.getPackageName().compareTo( o2.getPackageName() );
-		}
+        public int compare( IModelElement o1, IModelElement o2 )
+        {
+            if ( o1 instanceof IRequiredBundle )
+            {
+                if ( o2 instanceof IRequiredBundle )
+                {
+                    return compareBundles( ( IRequiredBundle ) o1, ( IRequiredBundle ) o2 );
+                }
+                else
+                {
+                    return -1;
+                }
+            }
+            else
+            {
+                if ( o2 instanceof IRequiredBundle )
+                {
+                    return 1;
+                }
+                else
+                {
+                    return compareNonBundles( o1, o2 );
+                }
+            }
+        }
 
-		private int compareBundles(IRequiredBundle o1, IRequiredBundle o2) {
-			return o1.getSymbolicName().compareTo( o2.getSymbolicName() );
-		}
-		
-	};
-	
-	public Link(ISigilBundle source, ISigilBundle target) {
-		this.source = source;
-		this.target = target;
-	}
 
-	public ISigilBundle getSource() {
-		return source;
-	}
-	
-	public ISigilBundle getTarget() {
-		return target;
-	}
-	
-	public boolean isSatisfied() {
-		return target != null;
-	}
+        private int compareNonBundles( IModelElement o1, IModelElement o2 )
+        {
+            if ( o1 instanceof IPackageImport )
+            {
+                if ( o2 instanceof IPackageImport )
+                {
+                    return compareImports( ( IPackageImport ) o1, ( IPackageImport ) o2 );
+                }
+                else
+                {
+                    return -1;
+                }
+            }
+            else
+            {
+                if ( o2 instanceof IPackageImport )
+                {
+                    return 1;
+                }
+                else
+                {
+                    return 0;
+                }
+            }
+        }
 
-	public void addRequirement(IModelElement requirement) {
-		requirements.add(requirement);
-		Collections.sort(requirements, comparator);
-	}
-	
-	public String toString() {
-		return "Link[" + source + "->" + target + "]";
-	}
 
-	public List<IModelElement> getRequirements() {
-		return requirements;
-	}
+        private int compareImports( IPackageImport o1, IPackageImport o2 )
+        {
+            return o1.getPackageName().compareTo( o2.getPackageName() );
+        }
 
-	public boolean isOptional() {
-		for ( IModelElement e : requirements ) {
-			if ( e instanceof IPackageImport ) {
-				IPackageImport pi = (IPackageImport) e;
-				if ( !pi.isOptional() ) {
-					return false;
-				}
-			}
-			else if ( e instanceof IRequiredBundle ) {
-				IRequiredBundle rb = (IRequiredBundle) e;
-				if ( !rb.isOptional() ) {
-					return false;
-				}
-			}
-		}
-		return true;
-	}
+
+        private int compareBundles( IRequiredBundle o1, IRequiredBundle o2 )
+        {
+            return o1.getSymbolicName().compareTo( o2.getSymbolicName() );
+        }
+
+    };
+
+
+    public Link( ISigilBundle source, ISigilBundle target )
+    {
+        this.source = source;
+        this.target = target;
+    }
+
+
+    public ISigilBundle getSource()
+    {
+        return source;
+    }
+
+
+    public ISigilBundle getTarget()
+    {
+        return target;
+    }
+
+
+    public boolean isSatisfied()
+    {
+        return target != null;
+    }
+
+
+    public void addRequirement( IModelElement requirement )
+    {
+        requirements.add( requirement );
+        Collections.sort( requirements, comparator );
+    }
+
+
+    public String toString()
+    {
+        return "Link[" + source + "->" + target + "]";
+    }
+
+
+    public List<IModelElement> getRequirements()
+    {
+        return requirements;
+    }
+
+
+    public boolean isOptional()
+    {
+        for ( IModelElement e : requirements )
+        {
+            if ( e instanceof IPackageImport )
+            {
+                IPackageImport pi = ( IPackageImport ) e;
+                if ( !pi.isOptional() )
+                {
+                    return false;
+                }
+            }
+            else if ( e instanceof IRequiredBundle )
+            {
+                IRequiredBundle rb = ( IRequiredBundle ) e;
+                if ( !rb.isOptional() )
+                {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/SigilNewResourceWizard.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/SigilNewResourceWizard.java
index b4b40db..960a37b 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/SigilNewResourceWizard.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/SigilNewResourceWizard.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.wizard;
 
+
 import org.eclipse.core.resources.IFile;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.swt.widgets.Display;
@@ -29,28 +30,35 @@
 import org.eclipse.ui.ide.IDE;
 import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
 
+
 /**
  * @author dave
  *
  */
-public abstract class SigilNewResourceWizard extends BasicNewResourceWizard implements INewWizard {
+public abstract class SigilNewResourceWizard extends BasicNewResourceWizard implements INewWizard
+{
 
-    protected void selectRevealAndShow(IFile file) {
-        selectAndReveal(file);
-    
+    protected void selectRevealAndShow( IFile file )
+    {
+        selectAndReveal( file );
+
         // Open editor on new file.
         IWorkbenchWindow dw = getWorkbench().getActiveWorkbenchWindow();
-        try {
-            if (dw != null) {
+        try
+        {
+            if ( dw != null )
+            {
                 IWorkbenchPage page = dw.getActivePage();
-                if (page != null) {
-                    IDE.openEditor(page, file, true);
+                if ( page != null )
+                {
+                    IDE.openEditor( page, file, true );
                 }
             }
         }
-        catch (PartInitException e) {
-            MessageDialog.openError(Display.getCurrent().getActiveShell(), "Initialisation error",
-                    "Failed to open " + file);
+        catch ( PartInitException e )
+        {
+            MessageDialog.openError( Display.getCurrent().getActiveShell(), "Initialisation error", "Failed to open "
+                + file );
         }
     }
 
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/WorkspaceContentProvider.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/WorkspaceContentProvider.java
index eb57a7c..884b790 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/WorkspaceContentProvider.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/WorkspaceContentProvider.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.wizard;
 
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -31,80 +32,115 @@
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.Viewer;
 
-public class WorkspaceContentProvider implements ITreeContentProvider {
-	
-	private final boolean includeNonSigil;
-	private final boolean includeClosed;
 
-	public WorkspaceContentProvider(boolean includeNonSigil, boolean includeClosed) {
-		this.includeNonSigil = includeNonSigil;
-		this.includeClosed = includeClosed;
-	}
+public class WorkspaceContentProvider implements ITreeContentProvider
+{
 
-	public Object[] getChildren(Object parentElement) {
-		Object[] result = null;
-		
-		if(parentElement instanceof IWorkspace) {
-			IProject[] projects = ((IWorkspace) parentElement).getRoot().getProjects();
-			if(includeNonSigil && includeClosed) {
-				result = projects;
-			} else {
-				List<IProject> includedProjects = new ArrayList<IProject>(projects.length);
-				for (IProject project : projects) {
-					if(!includeClosed && !project.isOpen()) {
-						continue;
-					}
-					
-					if(!includeNonSigil) {
-						try {
-							if(project.getNature(SigilCore.NATURE_ID) == null) {
-								continue;
-							}
-						} catch (CoreException e) {
-							continue;
-						}
-					}
-					
-					includedProjects.add(project);
-				}
-				result = includedProjects.toArray(new IProject[includedProjects.size()]);
-			}
-		} else if(parentElement instanceof IContainer) {
-			try {
-				IResource[] members = ((IContainer) parentElement).members();
-				List<IResource> children = new ArrayList<IResource>(members.length);
-				for (int i = 0; i < members.length; i++) {
-				    if (members[i].getType() != IResource.FILE) {
-				        children.add(members[i]);
-				    }
-				}
-				result = children.toArray(new IResource[children.size()]);
-			} catch (CoreException e) {
-				// Shouldn't happen
-			}
-		}
-		
-		return result;
-	}
+    private final boolean includeNonSigil;
+    private final boolean includeClosed;
 
-	public Object getParent(Object element) {
-		if(element instanceof IResource) {
-			return ((IResource) element).getParent();
-		}
-		return null;
-	}
 
-	public boolean hasChildren(Object element) {
-		return (element instanceof IContainer) && ((IContainer) element).isAccessible();
-	}
+    public WorkspaceContentProvider( boolean includeNonSigil, boolean includeClosed )
+    {
+        this.includeNonSigil = includeNonSigil;
+        this.includeClosed = includeClosed;
+    }
 
-	public Object[] getElements(Object inputElement) {
-		return getChildren(inputElement);
-	}
 
-	public void dispose() {
-	}
+    public Object[] getChildren( Object parentElement )
+    {
+        Object[] result = null;
 
-	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-	}
+        if ( parentElement instanceof IWorkspace )
+        {
+            IProject[] projects = ( ( IWorkspace ) parentElement ).getRoot().getProjects();
+            if ( includeNonSigil && includeClosed )
+            {
+                result = projects;
+            }
+            else
+            {
+                List<IProject> includedProjects = new ArrayList<IProject>( projects.length );
+                for ( IProject project : projects )
+                {
+                    if ( !includeClosed && !project.isOpen() )
+                    {
+                        continue;
+                    }
+
+                    if ( !includeNonSigil )
+                    {
+                        try
+                        {
+                            if ( project.getNature( SigilCore.NATURE_ID ) == null )
+                            {
+                                continue;
+                            }
+                        }
+                        catch ( CoreException e )
+                        {
+                            continue;
+                        }
+                    }
+
+                    includedProjects.add( project );
+                }
+                result = includedProjects.toArray( new IProject[includedProjects.size()] );
+            }
+        }
+        else if ( parentElement instanceof IContainer )
+        {
+            try
+            {
+                IResource[] members = ( ( IContainer ) parentElement ).members();
+                List<IResource> children = new ArrayList<IResource>( members.length );
+                for ( int i = 0; i < members.length; i++ )
+                {
+                    if ( members[i].getType() != IResource.FILE )
+                    {
+                        children.add( members[i] );
+                    }
+                }
+                result = children.toArray( new IResource[children.size()] );
+            }
+            catch ( CoreException e )
+            {
+                // Shouldn't happen
+            }
+        }
+
+        return result;
+    }
+
+
+    public Object getParent( Object element )
+    {
+        if ( element instanceof IResource )
+        {
+            return ( ( IResource ) element ).getParent();
+        }
+        return null;
+    }
+
+
+    public boolean hasChildren( Object element )
+    {
+        return ( element instanceof IContainer ) && ( ( IContainer ) element ).isAccessible();
+    }
+
+
+    public Object[] getElements( Object inputElement )
+    {
+        return getChildren( inputElement );
+    }
+
+
+    public void dispose()
+    {
+    }
+
+
+    public void inputChanged( Viewer viewer, Object oldInput, Object newInput )
+    {
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/project/SigilProjectWizard.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/project/SigilProjectWizard.java
index 8b3dbc5..7a1c71e 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/project/SigilProjectWizard.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/project/SigilProjectWizard.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.wizard.project;
 
+
 import org.apache.felix.sigil.eclipse.SigilCore;
 import org.apache.felix.sigil.ui.eclipse.ui.wizard.SigilNewResourceWizard;
 import org.eclipse.core.resources.IFile;
@@ -40,97 +41,123 @@
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard;
 
+
 /**
  * @author dave
  *
  */
-public class SigilProjectWizard extends SigilNewResourceWizard implements IExecutableExtension {
+public class SigilProjectWizard extends SigilNewResourceWizard implements IExecutableExtension
+{
 
     private SigilProjectWizardFirstPage firstPage;
     private SigilProjectWizardSecondPage secondPage;
-    
+
     private String name;
-    
+
     public static final IPath SIGIL_PROJECT_PATH = new Path( SigilCore.SIGIL_PROJECT_FILE );
-	private IConfigurationElement config;
-    
-    public void init(IWorkbench workbench, IStructuredSelection currentSelection) {
-        super.init(workbench, currentSelection);
+    private IConfigurationElement config;
+
+
+    public void init( IWorkbench workbench, IStructuredSelection currentSelection )
+    {
+        super.init( workbench, currentSelection );
 
         firstPage = new SigilProjectWizardFirstPage();
-        firstPage.setInitialProjectName(name);
-        secondPage = new SigilProjectWizardSecondPage(firstPage);
-        
-        addPage(firstPage);
-        addPage(secondPage);
+        firstPage.setInitialProjectName( name );
+        secondPage = new SigilProjectWizardSecondPage( firstPage );
+
+        addPage( firstPage );
+        addPage( secondPage );
     }
-    
-    private void finishPage(IProgressMonitor monitor) throws CoreException, InterruptedException {
-        secondPage.performFinish(monitor);
-        
+
+
+    private void finishPage( IProgressMonitor monitor ) throws CoreException, InterruptedException
+    {
+        secondPage.performFinish( monitor );
+
         IProject newProject = firstPage.getProjectHandle();
-        
-        if ( newProject != null && newProject.exists() ) {
+
+        if ( newProject != null && newProject.exists() )
+        {
             IFile file = newProject.getFile( SigilProjectWizard.SIGIL_PROJECT_PATH );
-            
-            selectRevealAndShow( file ); 
-           
-            new Job("Check OSGi Install" ) {
-				@Override
-				protected IStatus run(IProgressMonitor monitor) {
+
+            selectRevealAndShow( file );
+
+            new Job( "Check OSGi Install" )
+            {
+                @Override
+                protected IStatus run( IProgressMonitor monitor )
+                {
                     // prompt for osgi home if not already set.
-            		SigilCore.getInstallManager().getDefaultInstall();
-            		return Status.OK_STATUS;
-				}
+                    SigilCore.getInstallManager().getDefaultInstall();
+                    return Status.OK_STATUS;
+                }
             }.schedule();
         }
     }
 
+
     /* (non-Javadoc)
      * @see org.eclipse.jface.wizard.Wizard#performFinish()
      */
     @Override
-    public boolean performFinish() {
+    public boolean performFinish()
+    {
         IWorkspace workspace = ResourcesPlugin.getWorkspace();
-        
-        IWorkspaceRunnable op= new IWorkspaceRunnable() {
-            public void run(IProgressMonitor monitor) throws CoreException {
-                try {
-                    finishPage(monitor);
-                } catch (InterruptedException e) {
-                    throw new OperationCanceledException(e.getMessage());
+
+        IWorkspaceRunnable op = new IWorkspaceRunnable()
+        {
+            public void run( IProgressMonitor monitor ) throws CoreException
+            {
+                try
+                {
+                    finishPage( monitor );
+                }
+                catch ( InterruptedException e )
+                {
+                    throw new OperationCanceledException( e.getMessage() );
                 }
             }
         };
-        
-        try {
-            workspace.run(op, Job.getJobManager().createProgressGroup());
+
+        try
+        {
+            workspace.run( op, Job.getJobManager().createProgressGroup() );
         }
-        catch (CoreException e) {
-            SigilCore.error( "Failed to complete project wizard", e);
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Failed to complete project wizard", e );
             return false;
         }
-        
-        BasicNewProjectResourceWizard.updatePerspective(config);
+
+        BasicNewProjectResourceWizard.updatePerspective( config );
         return true;
     }
 
-	public void setName(String name) {
-		this.name = name;
-	}
-	
-	public String getName() {
-		return name;
-	}
-    
-    @Override
-    public boolean performCancel() {
-    	secondPage.performCancel();
-    	return super.performCancel();
+
+    public void setName( String name )
+    {
+        this.name = name;
     }
 
-	public void setInitializationData(IConfigurationElement config, String propertyName, Object data)
-			throws CoreException {
-		this.config = config;
-	}
+
+    public String getName()
+    {
+        return name;
+    }
+
+
+    @Override
+    public boolean performCancel()
+    {
+        secondPage.performCancel();
+        return super.performCancel();
+    }
+
+
+    public void setInitializationData( IConfigurationElement config, String propertyName, Object data )
+        throws CoreException
+    {
+        this.config = config;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/project/SigilProjectWizardFirstPage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/project/SigilProjectWizardFirstPage.java
index c4779a9..8301e5a 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/project/SigilProjectWizardFirstPage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/project/SigilProjectWizardFirstPage.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.wizard.project;
 
+
 import org.eclipse.core.resources.IWorkspace;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IPath;
@@ -37,135 +38,161 @@
 import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
 import org.osgi.framework.Version;
 
+
 /**
  * @author dave
  *
  */
-public class SigilProjectWizardFirstPage extends WizardNewProjectCreationPage {
+public class SigilProjectWizardFirstPage extends WizardNewProjectCreationPage
+{
 
-	private volatile String description = "";
-	private volatile Version version = new Version(1, 0, 0);
-	private volatile String vendor = "";
-	private volatile String name = "";
-	
-	private Text txtDescription;
+    private volatile String description = "";
+    private volatile Version version = new Version( 1, 0, 0 );
+    private volatile String vendor = "";
+    private volatile String name = "";
+
+    private Text txtDescription;
     private Text txtVersion;
-	private Text txtVendor;
-	private Text txtName;
+    private Text txtVendor;
+    private Text txtName;
 
-	public SigilProjectWizardFirstPage() {
-        super("newSigilProjectPage");
+
+    public SigilProjectWizardFirstPage()
+    {
+        super( "newSigilProjectPage" );
         setTitle( "Sigil Project" );
         setDescription( "Create a new Sigil project" );
     }
 
-    public boolean isInWorkspace() {
+
+    public boolean isInWorkspace()
+    {
         IWorkspace workspace = ResourcesPlugin.getWorkspace();
-        
+
         IPath defaultDefaultLocation = workspace.getRoot().getLocation();
-        
+
         return defaultDefaultLocation.isPrefixOf( getLocationPath() );
     }
-    
+
+
     @Override
-    public boolean isPageComplete() {
-    	boolean result = super.isPageComplete();
-    	return result;
-    }
-    
-    @Override
-    public void createControl(Composite parent) {
-    	FieldDecoration infoDecor = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_INFORMATION);
-    	
-    	// Create controls
-    	super.createControl(parent);
-    	Composite control = (Composite) getControl();
-    	
-    	Group grpProjectSettings = new Group(control, SWT.NONE);
-    	grpProjectSettings.setText("Project Settings");
-    	
-    	new Label(grpProjectSettings, SWT.NONE).setText("Version:");
-    	txtVersion = new Text(grpProjectSettings, SWT.BORDER);
-    	
-    	new Label(grpProjectSettings, SWT.NONE).setText("Name:");
-    	txtName = new Text(grpProjectSettings, SWT.BORDER);
-    	
-    	ControlDecoration txtNameDecor = new ControlDecoration(txtName, SWT.LEFT | SWT.CENTER);
-    	txtNameDecor.setImage(infoDecor.getImage());
-    	txtNameDecor.setDescriptionText("Defines a human-readable name for the bundle");
-    	
-    	new Label(grpProjectSettings, SWT.NONE).setText("Description:");
-    	txtDescription = new Text(grpProjectSettings, SWT.BORDER);
-    	
-    	ControlDecoration txtDescDecor = new ControlDecoration(txtDescription, SWT.LEFT | SWT.CENTER);
-    	txtDescDecor.setImage(infoDecor.getImage());
-    	txtDescDecor.setDescriptionText("Defines a short human-readable description for the bundle");
-    	
-    	new Label(grpProjectSettings, SWT.NONE).setText("Provider:");
-    	txtVendor = new Text(grpProjectSettings, SWT.BORDER);
-    	
-    	ControlDecoration txtVendorDecor = new ControlDecoration(txtVendor, SWT.LEFT | SWT.CENTER);
-    	txtVendorDecor.setImage(infoDecor.getImage());
-    	txtVendorDecor.setDescriptionText("The name of the company, organisation or individual providing the bundle");
-    	    	
-    	// Set values
-    	txtDescription.setText(description);
-    	txtVersion.setText(version.toString());
-    	txtVendor.setText(vendor);
-    	txtName.setText(name);
-    	
-    	// Add listeners
-    	ModifyListener txtModListener = new ModifyListener() {
-			public void modifyText(ModifyEvent e) {
-				description = txtDescription.getText();
-				vendor = txtVendor.getText();
-				name = txtName.getText();
-				
-				validateSettings();
-			}
-    	};
-    	txtDescription.addModifyListener(txtModListener);
-    	txtVersion.addModifyListener(txtModListener);
-    	txtVendor.addModifyListener(txtModListener);
-    	txtName.addModifyListener(txtModListener);
-    	
-    	// Layout
-    	control.setLayout(new GridLayout());
-    	grpProjectSettings.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-    	grpProjectSettings.setLayout(new GridLayout(2, false));
-    	txtDescription.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-    	txtVersion.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-    	txtVendor.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-    	txtName.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+    public boolean isPageComplete()
+    {
+        boolean result = super.isPageComplete();
+        return result;
     }
 
-    private void validateSettings() {
-    	try {
-			version = new Version(txtVersion.getText());
-		} catch (IllegalArgumentException e) {
-			version = null;
-			setErrorMessage("Invalid version");
-			setPageComplete(false);
-			return;
-		}
-		
-		setErrorMessage(null);
-		setPageComplete(true);
-	}
 
-	public Version getVersion() {
-		return version;
-	}
+    @Override
+    public void createControl( Composite parent )
+    {
+        FieldDecoration infoDecor = FieldDecorationRegistry.getDefault().getFieldDecoration(
+            FieldDecorationRegistry.DEC_INFORMATION );
 
-	public String getVendor() {
-		return vendor;
-	}
-	
-	public String getDescription() {
-		return description;
-	}
-	
-	public String getName() {
-		return name;
-	}
+        // Create controls
+        super.createControl( parent );
+        Composite control = ( Composite ) getControl();
+
+        Group grpProjectSettings = new Group( control, SWT.NONE );
+        grpProjectSettings.setText( "Project Settings" );
+
+        new Label( grpProjectSettings, SWT.NONE ).setText( "Version:" );
+        txtVersion = new Text( grpProjectSettings, SWT.BORDER );
+
+        new Label( grpProjectSettings, SWT.NONE ).setText( "Name:" );
+        txtName = new Text( grpProjectSettings, SWT.BORDER );
+
+        ControlDecoration txtNameDecor = new ControlDecoration( txtName, SWT.LEFT | SWT.CENTER );
+        txtNameDecor.setImage( infoDecor.getImage() );
+        txtNameDecor.setDescriptionText( "Defines a human-readable name for the bundle" );
+
+        new Label( grpProjectSettings, SWT.NONE ).setText( "Description:" );
+        txtDescription = new Text( grpProjectSettings, SWT.BORDER );
+
+        ControlDecoration txtDescDecor = new ControlDecoration( txtDescription, SWT.LEFT | SWT.CENTER );
+        txtDescDecor.setImage( infoDecor.getImage() );
+        txtDescDecor.setDescriptionText( "Defines a short human-readable description for the bundle" );
+
+        new Label( grpProjectSettings, SWT.NONE ).setText( "Provider:" );
+        txtVendor = new Text( grpProjectSettings, SWT.BORDER );
+
+        ControlDecoration txtVendorDecor = new ControlDecoration( txtVendor, SWT.LEFT | SWT.CENTER );
+        txtVendorDecor.setImage( infoDecor.getImage() );
+        txtVendorDecor.setDescriptionText( "The name of the company, organisation or individual providing the bundle" );
+
+        // Set values
+        txtDescription.setText( description );
+        txtVersion.setText( version.toString() );
+        txtVendor.setText( vendor );
+        txtName.setText( name );
+
+        // Add listeners
+        ModifyListener txtModListener = new ModifyListener()
+        {
+            public void modifyText( ModifyEvent e )
+            {
+                description = txtDescription.getText();
+                vendor = txtVendor.getText();
+                name = txtName.getText();
+
+                validateSettings();
+            }
+        };
+        txtDescription.addModifyListener( txtModListener );
+        txtVersion.addModifyListener( txtModListener );
+        txtVendor.addModifyListener( txtModListener );
+        txtName.addModifyListener( txtModListener );
+
+        // Layout
+        control.setLayout( new GridLayout() );
+        grpProjectSettings.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        grpProjectSettings.setLayout( new GridLayout( 2, false ) );
+        txtDescription.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        txtVersion.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        txtVendor.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+        txtName.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false ) );
+    }
+
+
+    private void validateSettings()
+    {
+        try
+        {
+            version = new Version( txtVersion.getText() );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            version = null;
+            setErrorMessage( "Invalid version" );
+            setPageComplete( false );
+            return;
+        }
+
+        setErrorMessage( null );
+        setPageComplete( true );
+    }
+
+
+    public Version getVersion()
+    {
+        return version;
+    }
+
+
+    public String getVendor()
+    {
+        return vendor;
+    }
+
+
+    public String getDescription()
+    {
+        return description;
+    }
+
+
+    public String getName()
+    {
+        return name;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/project/SigilProjectWizardSecondPage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/project/SigilProjectWizardSecondPage.java
index 910ed9e..6e34c9e 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/project/SigilProjectWizardSecondPage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/project/SigilProjectWizardSecondPage.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.wizard.project;
 
+
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -47,164 +48,214 @@
 import org.eclipse.jdt.ui.wizards.JavaCapabilityConfigurationPage;
 import org.osgi.framework.Version;
 
+
 /**
  * @author dave
  *
  */
-public class SigilProjectWizardSecondPage extends JavaCapabilityConfigurationPage {
-    
+public class SigilProjectWizardSecondPage extends JavaCapabilityConfigurationPage
+{
+
     private SigilProjectWizardFirstPage firstPage;
     private IProject currentProject;
     private URI currentProjectLocation;
     private boolean created;
-    
-    public SigilProjectWizardSecondPage(SigilProjectWizardFirstPage firstPage) {
+
+
+    public SigilProjectWizardSecondPage( SigilProjectWizardFirstPage firstPage )
+    {
         this.firstPage = firstPage;
     }
 
+
     @Override
-    public void setVisible(boolean visible) {
-    	super.setVisible(visible);
-        if (visible) {
+    public void setVisible( boolean visible )
+    {
+        super.setVisible( visible );
+        if ( visible )
+        {
             changeToNewProject();
-        } else {
+        }
+        else
+        {
             removeProject();
         }
     }
-    
+
+
     @Override
-    protected boolean useNewSourcePage() {
+    protected boolean useNewSourcePage()
+    {
         return true;
     }
-    
-    protected void performFinish(IProgressMonitor monitor) throws CoreException, InterruptedException {
-    	changeToNewProject();
-        updateProject(monitor);
+
+
+    protected void performFinish( IProgressMonitor monitor ) throws CoreException, InterruptedException
+    {
+        changeToNewProject();
+        updateProject( monitor );
     }
-    
-    private void changeToNewProject() {
-    	if ( !created ) {
+
+
+    private void changeToNewProject()
+    {
+        if ( !created )
+        {
             IWorkspace workspace = ResourcesPlugin.getWorkspace();
-            
-            IWorkspaceRunnable op= new IWorkspaceRunnable() {
-                public void run(IProgressMonitor monitor) throws CoreException {
-                    try {
-                        updateProject(monitor);
-                    } catch (InterruptedException e) {
-                        throw new OperationCanceledException(e.getMessage());
+
+            IWorkspaceRunnable op = new IWorkspaceRunnable()
+            {
+                public void run( IProgressMonitor monitor ) throws CoreException
+                {
+                    try
+                    {
+                        updateProject( monitor );
+                    }
+                    catch ( InterruptedException e )
+                    {
+                        throw new OperationCanceledException( e.getMessage() );
                     }
                 }
             };
-            
-            try {
-                workspace.run(op, Job.getJobManager().createProgressGroup());
-                setErrorMessage(null);
-                setPageComplete(true);
+
+            try
+            {
+                workspace.run( op, Job.getJobManager().createProgressGroup() );
+                setErrorMessage( null );
+                setPageComplete( true );
                 created = true;
             }
-            catch (CoreException e) {
-            	SigilCore.error("Failed to run workspace job", e);
-            }        
-    	}
+            catch ( CoreException e )
+            {
+                SigilCore.error( "Failed to run workspace job", e );
+            }
+        }
     }
-    
-    private void removeProject() {
-        if (currentProject == null || !currentProject.exists()) {
+
+
+    private void removeProject()
+    {
+        if ( currentProject == null || !currentProject.exists() )
+        {
             return;
         }
-        
-        IWorkspaceRunnable op= new IWorkspaceRunnable() {
-            public void run(IProgressMonitor monitor) throws CoreException {
-                doRemoveProject(monitor);
+
+        IWorkspaceRunnable op = new IWorkspaceRunnable()
+        {
+            public void run( IProgressMonitor monitor ) throws CoreException
+            {
+                doRemoveProject( monitor );
             }
         };
-    
+
         IWorkspace workspace = ResourcesPlugin.getWorkspace();
-        
-        try {
-            workspace.run(op, Job.getJobManager().createProgressGroup());
+
+        try
+        {
+            workspace.run( op, Job.getJobManager().createProgressGroup() );
         }
-        catch (CoreException e) {
-        	SigilCore.error("Failed to run workspace job", e);
+        catch ( CoreException e )
+        {
+            SigilCore.error( "Failed to run workspace job", e );
         }
-        finally {
-        	created = false;
+        finally
+        {
+            created = false;
         }
     }
-    
-    private void updateProject(IProgressMonitor monitor) throws CoreException, InterruptedException {
+
+
+    private void updateProject( IProgressMonitor monitor ) throws CoreException, InterruptedException
+    {
         currentProject = firstPage.getProjectHandle();
-        currentProjectLocation= getProjectLocationURI();
-        
+        currentProjectLocation = getProjectLocationURI();
+
         String description = firstPage.getDescription();
         Version projectVersion = firstPage.getVersion();
         String vendor = firstPage.getVendor();
         String name = firstPage.getName();
-        
-        createProject( currentProject, currentProjectLocation, monitor);
+
+        createProject( currentProject, currentProjectLocation, monitor );
 
         IPath src = createSourcePath();
-        
-        IPath output = getOutputLocation();
-        
-        if ( output.segmentCount() == 0 ) {
-        	output = new Path( currentProject.getName() ).append( "build" ).append( "classes" );
-        }
-        
-        IClasspathEntry[] entries = getProjectClassPath(src);
-        
-    	SigilCore.makeSigilProject(currentProject, monitor);
-    	
-        init(JavaCore.create(currentProject), output.makeRelative(), entries, false);
 
-        configureJavaProject(new SubProgressMonitor(monitor, 3));
-        
+        IPath output = getOutputLocation();
+
+        if ( output.segmentCount() == 0 )
+        {
+            output = new Path( currentProject.getName() ).append( "build" ).append( "classes" );
+        }
+
+        IClasspathEntry[] entries = getProjectClassPath( src );
+
+        SigilCore.makeSigilProject( currentProject, monitor );
+
+        init( JavaCore.create( currentProject ), output.makeRelative(), entries, false );
+
+        configureJavaProject( new SubProgressMonitor( monitor, 3 ) );
+
         configureSigilProject( currentProject, description, projectVersion, vendor, name, src, monitor );
     }
-    
-	private IPath createSourcePath() throws CoreException {
+
+
+    private IPath createSourcePath() throws CoreException
+    {
         IPath projectPath = currentProject.getFullPath();
         IPath src = new Path( "src" );
         IFolder f = currentProject.getFolder( src );
-        if ( !f.getLocation().toFile().exists() ) {
-        	f.create(true, true, null);
+        if ( !f.getLocation().toFile().exists() )
+        {
+            f.create( true, true, null );
         }
-        
-        return projectPath.append(src);
-	}
 
-	final void doRemoveProject(IProgressMonitor monitor) throws CoreException {
-        final boolean noProgressMonitor= (currentProjectLocation == null); // inside workspace
-        
-        if (monitor == null || noProgressMonitor) {
-            monitor= new NullProgressMonitor();
-        }
-        monitor.beginTask("Remove project", 3); 
-        try {
-            try {
-                boolean removeContent= currentProject.isSynchronized(IResource.DEPTH_INFINITE);
-                currentProject.delete(removeContent, false, new SubProgressMonitor(monitor, 2));
-                
-            } finally {
-            }
-        } finally {
-            monitor.done();
-            currentProject= null;
-        }        
+        return projectPath.append( src );
     }
-        
-    private IClasspathEntry[] getProjectClassPath(IPath src) throws CoreException {
-        List<IClasspathEntry> cpEntries= new ArrayList<IClasspathEntry>();
-        cpEntries.add(JavaCore.newSourceEntry(src));
-        cpEntries.addAll(Arrays.asList(getDefaultClasspathEntry()));
-        cpEntries.add(JavaCore.newContainerEntry(new Path(SigilCore.CLASSPATH_CONTAINER_PATH)));
-        IClasspathEntry[] entries= cpEntries.toArray(new IClasspathEntry[cpEntries.size()]);
-        
+
+
+    final void doRemoveProject( IProgressMonitor monitor ) throws CoreException
+    {
+        final boolean noProgressMonitor = ( currentProjectLocation == null ); // inside workspace
+
+        if ( monitor == null || noProgressMonitor )
+        {
+            monitor = new NullProgressMonitor();
+        }
+        monitor.beginTask( "Remove project", 3 );
+        try
+        {
+            try
+            {
+                boolean removeContent = currentProject.isSynchronized( IResource.DEPTH_INFINITE );
+                currentProject.delete( removeContent, false, new SubProgressMonitor( monitor, 2 ) );
+
+            }
+            finally
+            {
+            }
+        }
+        finally
+        {
+            monitor.done();
+            currentProject = null;
+        }
+    }
+
+
+    private IClasspathEntry[] getProjectClassPath( IPath src ) throws CoreException
+    {
+        List<IClasspathEntry> cpEntries = new ArrayList<IClasspathEntry>();
+        cpEntries.add( JavaCore.newSourceEntry( src ) );
+        cpEntries.addAll( Arrays.asList( getDefaultClasspathEntry() ) );
+        cpEntries.add( JavaCore.newContainerEntry( new Path( SigilCore.CLASSPATH_CONTAINER_PATH ) ) );
+        IClasspathEntry[] entries = cpEntries.toArray( new IClasspathEntry[cpEntries.size()] );
+
         return entries;
     }
-    
-    private IClasspathEntry[] getDefaultClasspathEntry() {
-        IClasspathEntry[] defaultJRELibrary= PreferenceConstants.getDefaultJRELibrary();
+
+
+    private IClasspathEntry[] getDefaultClasspathEntry()
+    {
+        IClasspathEntry[] defaultJRELibrary = PreferenceConstants.getDefaultJRELibrary();
         /*String compliance= firstPage.getCompilerCompliance();
         IPath jreContainerPath= new Path(JavaRuntime.JRE_CONTAINER);
         if (compliance == null || defaultJRELibrary.length > 1 || !jreContainerPath.isPrefixOf(defaultJRELibrary[0].getPath())) {
@@ -218,48 +269,61 @@
         }*/
         return defaultJRELibrary;
     }
-    
-    
-    private void configureSigilProject( IProject project, String description, Version projectVersion, String vendorName, String bundleName, IPath src, IProgressMonitor monitor ) throws CoreException {
-        ISigilProjectModel sigil = SigilCore.create(project);
-        IClasspathEntry cp = JavaCore.newSourceEntry(src);
-        String encodedClasspath = sigil.getJavaModel().encodeClasspathEntry(cp );
-        
+
+
+    private void configureSigilProject( IProject project, String description, Version projectVersion,
+        String vendorName, String bundleName, IPath src, IProgressMonitor monitor ) throws CoreException
+    {
+        ISigilProjectModel sigil = SigilCore.create( project );
+        IClasspathEntry cp = JavaCore.newSourceEntry( src );
+        String encodedClasspath = sigil.getJavaModel().encodeClasspathEntry( cp );
+
         ISigilBundle bundle = sigil.getBundle();
-        bundle.addClasspathEntry(encodedClasspath);
-        
-        if(description != null) {
-        	bundle.getBundleInfo().setDescription(description);
+        bundle.addClasspathEntry( encodedClasspath );
+
+        if ( description != null )
+        {
+            bundle.getBundleInfo().setDescription( description );
         }
-		if(projectVersion != null) {
-        	bundle.setVersion(projectVersion);
+        if ( projectVersion != null )
+        {
+            bundle.setVersion( projectVersion );
         }
-		if(vendorName != null) {
-			bundle.getBundleInfo().setVendor(vendorName);
-		}
-		if(bundleName != null) {
-			bundle.getBundleInfo().setName(bundleName);
-		}
-        sigil.save(monitor);
+        if ( vendorName != null )
+        {
+            bundle.getBundleInfo().setVendor( vendorName );
+        }
+        if ( bundleName != null )
+        {
+            bundle.getBundleInfo().setName( bundleName );
+        }
+        sigil.save( monitor );
     }
-    
-    
-    private URI getProjectLocationURI() throws CoreException {
-        if (firstPage.isInWorkspace()) {
+
+
+    private URI getProjectLocationURI() throws CoreException
+    {
+        if ( firstPage.isInWorkspace() )
+        {
             return null;
         }
         return firstPage.getLocationURI();
     }
-    
+
+
     @Override
-    public boolean isPageComplete() {
-    	boolean result = super.isPageComplete();
-    	return result;
+    public boolean isPageComplete()
+    {
+        boolean result = super.isPageComplete();
+        return result;
     }
-    
-    protected void performCancel() {
-    	if(currentProject != null) {
-    		removeProject();
-    	}
+
+
+    protected void performCancel()
+    {
+        if ( currentProject != null )
+        {
+            removeProject();
+        }
     }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/repository/RepositoryWizard.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/repository/RepositoryWizard.java
index abf618d..df03285 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/repository/RepositoryWizard.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/repository/RepositoryWizard.java
@@ -19,30 +19,41 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.wizard.repository;
 
+
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
 import org.eclipse.jface.wizard.IWizardPage;
 import org.eclipse.jface.wizard.Wizard;
 
-public class RepositoryWizard extends Wizard {
-	
-	private IRepositoryModel model;
-	
-	@Override
-	public boolean performFinish() {
-		for ( IWizardPage page : getPages() ) {
-			if ( page instanceof RepositoryWizardPage ) {
-				RepositoryWizardPage rwp = (RepositoryWizardPage) page;
-				rwp.storeFields();
-			}
-		}
-		return true;
-	}
-	
-	public IRepositoryModel getModel() {
-		return model;
-	}
 
-	public void init(IRepositoryModel model) {
-		this.model = model;
-	}
+public class RepositoryWizard extends Wizard
+{
+
+    private IRepositoryModel model;
+
+
+    @Override
+    public boolean performFinish()
+    {
+        for ( IWizardPage page : getPages() )
+        {
+            if ( page instanceof RepositoryWizardPage )
+            {
+                RepositoryWizardPage rwp = ( RepositoryWizardPage ) page;
+                rwp.storeFields();
+            }
+        }
+        return true;
+    }
+
+
+    public IRepositoryModel getModel()
+    {
+        return model;
+    }
+
+
+    public void init( IRepositoryModel model )
+    {
+        this.model = model;
+    }
 }
diff --git a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/repository/RepositoryWizardPage.java b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/repository/RepositoryWizardPage.java
index 4502a71..1b773ac 100644
--- a/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/repository/RepositoryWizardPage.java
+++ b/sigil/eclipse/ui/src/org/apache/felix/sigil/ui/eclipse/ui/wizard/repository/RepositoryWizardPage.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ui.eclipse.ui.wizard.repository;
 
+
 import java.util.ArrayList;
 
 import org.apache.felix.sigil.eclipse.model.repository.IRepositoryModel;
@@ -31,79 +32,104 @@
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
 
-public abstract class RepositoryWizardPage extends WizardPage {
 
-	private StringFieldEditor nameEditor;
-	private ArrayList<FieldEditor> editors = new ArrayList<FieldEditor>();
-	private RepositoryWizard wizard;
-	
-	protected RepositoryWizardPage(String pageName, RepositoryWizard parent) {
-		super(pageName);
-		setTitle(pageName);
-		this.wizard = parent;
-	}
-	
-	public abstract void createFieldEditors();
+public abstract class RepositoryWizardPage extends WizardPage
+{
 
-	public void addField(FieldEditor editor) {
-		editors.add( editor );
-	}
-	
-	public void createControl(Composite parent) {
-		Composite control = new Composite(parent, SWT.NONE);
-		setControl(control);
-		
-		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();
-				}
-			});
-		}
-		
-		createFieldEditors();
+    private StringFieldEditor nameEditor;
+    private ArrayList<FieldEditor> editors = new ArrayList<FieldEditor>();
+    private RepositoryWizard wizard;
 
-		int cols = nameEditor == null ? 0 : nameEditor.getNumberOfControls();
-		for ( FieldEditor e : editors ) {
-			cols = Math.max(cols, e.getNumberOfControls());
-		}
-		
-		control.setLayout( new GridLayout(cols, false) );
-		
-		if ( nameEditor != null ) {
-			nameEditor.fillIntoGrid(getFieldEditorParent(), cols);
-		}
 
-		for ( FieldEditor e : editors ) {
-			e.fillIntoGrid(getFieldEditorParent(), cols);
-			e.setPreferenceStore(getModel().getPreferences());
-			e.load();
-		}
-		
-		checkPageComplete();
-	}
+    protected RepositoryWizardPage( String pageName, RepositoryWizard parent )
+    {
+        super( pageName );
+        setTitle( pageName );
+        this.wizard = parent;
+    }
 
-	protected void checkPageComplete() {
-		if ( nameEditor != null ) {
-			setPageComplete(nameEditor.getStringValue().length() > 0);
-		}
-	}
 
-	public IRepositoryModel getModel() {
-		return wizard.getModel();
-	}
+    public abstract void createFieldEditors();
 
-	protected Composite getFieldEditorParent() {
-		return (Composite) getControl();
-	}
 
-	public void storeFields() {
-		getModel().setName(nameEditor.getStringValue());
-		for ( FieldEditor e : editors ) {
-			e.store();
-		}
-	}
-	
+    public void addField( FieldEditor editor )
+    {
+        editors.add( editor );
+    }
+
+
+    public void createControl( Composite parent )
+    {
+        Composite control = new Composite( parent, SWT.NONE );
+        setControl( control );
+
+        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();
+                }
+            } );
+        }
+
+        createFieldEditors();
+
+        int cols = nameEditor == null ? 0 : nameEditor.getNumberOfControls();
+        for ( FieldEditor e : editors )
+        {
+            cols = Math.max( cols, e.getNumberOfControls() );
+        }
+
+        control.setLayout( new GridLayout( cols, false ) );
+
+        if ( nameEditor != null )
+        {
+            nameEditor.fillIntoGrid( getFieldEditorParent(), cols );
+        }
+
+        for ( FieldEditor e : editors )
+        {
+            e.fillIntoGrid( getFieldEditorParent(), cols );
+            e.setPreferenceStore( getModel().getPreferences() );
+            e.load();
+        }
+
+        checkPageComplete();
+    }
+
+
+    protected void checkPageComplete()
+    {
+        if ( nameEditor != null )
+        {
+            setPageComplete( nameEditor.getStringValue().length() > 0 );
+        }
+    }
+
+
+    public IRepositoryModel getModel()
+    {
+        return wizard.getModel();
+    }
+
+
+    protected Composite getFieldEditorParent()
+    {
+        return ( Composite ) getControl();
+    }
+
+
+    public void storeFields()
+    {
+        getModel().setName( nameEditor.getStringValue() );
+        for ( FieldEditor e : editors )
+        {
+            e.store();
+        }
+    }
+
 }
diff --git a/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/GlobCompiler.java b/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/GlobCompiler.java
index d531370..4f47962 100644
--- a/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/GlobCompiler.java
+++ b/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/GlobCompiler.java
@@ -19,36 +19,44 @@
 
 package org.apache.felix.sigil.utils;
 
+
 import java.util.regex.Pattern;
 
-public class GlobCompiler {
-	public static final Pattern compile(String glob) {
-		char[] chars = glob.toCharArray();
-		if ( chars.length > 0 ) {
-			StringBuilder builder = new StringBuilder(chars.length + 5);
-	
-			builder.append('^');
-			
-			for (char c : chars) {
-				switch ( c ) {
-				case '*':
-					builder.append(".*");
-					break;
-				case '.':
-					builder.append("\\.");
-					break;
-				case '$':
-					builder.append( "\\$" );
-					break;
-				default:
-					builder.append( c );
-				}
-			}
-	
-			return Pattern.compile(builder.toString());
-		}
-		else {
-			return Pattern.compile(glob);
-		}
-	}
+
+public class GlobCompiler
+{
+    public static final Pattern compile( String glob )
+    {
+        char[] chars = glob.toCharArray();
+        if ( chars.length > 0 )
+        {
+            StringBuilder builder = new StringBuilder( chars.length + 5 );
+
+            builder.append( '^' );
+
+            for ( char c : chars )
+            {
+                switch ( c )
+                {
+                    case '*':
+                        builder.append( ".*" );
+                        break;
+                    case '.':
+                        builder.append( "\\." );
+                        break;
+                    case '$':
+                        builder.append( "\\$" );
+                        break;
+                    default:
+                        builder.append( c );
+                }
+            }
+
+            return Pattern.compile( builder.toString() );
+        }
+        else
+        {
+            return Pattern.compile( glob );
+        }
+    }
 }
diff --git a/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/PathHelper.java b/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/PathHelper.java
index 54325f8..f40929d 100644
--- a/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/PathHelper.java
+++ b/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/PathHelper.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.utils;
 
+
 import java.io.File;
 import java.util.List;
 import java.util.regex.Pattern;
@@ -26,18 +27,24 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
 
-public class PathHelper {
 
-	public static void scanFiles(List<IPath> paths, IPath path, String pattern, boolean recurse) {
-		Pattern p = GlobCompiler.compile(pattern);
-		
-		for ( File f : path.toFile().listFiles() ) {
-			if ( f.isDirectory() && recurse ) {
-				scanFiles( paths, new Path(f.getAbsolutePath()), pattern, recurse);
-			}
-			else if ( f.isFile() && p.matcher(f.getName()).matches() ) {
-				paths.add( new Path(f.getAbsolutePath()) );
-			}
-		}
-	}
+public class PathHelper
+{
+
+    public static void scanFiles( List<IPath> paths, IPath path, String pattern, boolean recurse )
+    {
+        Pattern p = GlobCompiler.compile( pattern );
+
+        for ( File f : path.toFile().listFiles() )
+        {
+            if ( f.isDirectory() && recurse )
+            {
+                scanFiles( paths, new Path( f.getAbsolutePath() ), pattern, recurse );
+            }
+            else if ( f.isFile() && p.matcher( f.getName() ).matches() )
+            {
+                paths.add( new Path( f.getAbsolutePath() ) );
+            }
+        }
+    }
 }
diff --git a/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/SigilUtils.java b/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/SigilUtils.java
index caa5840..51524e1 100644
--- a/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/SigilUtils.java
+++ b/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/SigilUtils.java
@@ -19,21 +19,29 @@
 
 package org.apache.felix.sigil.utils;
 
+
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.content.IContentType;
 
-public final class SigilUtils {
-	private SigilUtils () {
-	}
-	
-	public static boolean isResourceType(IResource resource, String type) {
-		IContentType[] types = Platform.getContentTypeManager().findContentTypesFor(resource.getName());
-		for (IContentType contentType : types) {
-			if(contentType.getId().equals(type)) {
-				return true;
-			}
-		}
-		return false;
-	}
+
+public final class SigilUtils
+{
+    private SigilUtils()
+    {
+    }
+
+
+    public static boolean isResourceType( IResource resource, String type )
+    {
+        IContentType[] types = Platform.getContentTypeManager().findContentTypesFor( resource.getName() );
+        for ( IContentType contentType : types )
+        {
+            if ( contentType.getId().equals( type ) )
+            {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/properties/EditorPropertyTester.java b/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/properties/EditorPropertyTester.java
index c23c16b..a94f511 100644
--- a/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/properties/EditorPropertyTester.java
+++ b/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/properties/EditorPropertyTester.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.utils.properties;
 
+
 import org.apache.felix.sigil.utils.SigilUtils;
 import org.eclipse.core.expressions.PropertyTester;
 import org.eclipse.core.resources.IFile;
@@ -27,25 +28,31 @@
 import org.eclipse.ui.IFileEditorInput;
 import org.eclipse.ui.IWorkbenchPart;
 
-public class EditorPropertyTester extends PropertyTester {
 
-	public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
-		IWorkbenchPart part = (IWorkbenchPart) receiver;
+public class EditorPropertyTester extends PropertyTester
+{
 
-		boolean result = false;
-		
-		if(part instanceof IEditorPart) {
-			IEditorInput input = ((IEditorPart) part).getEditorInput();
-			if(input instanceof IFileEditorInput) {
-				IFile file = ((IFileEditorInput) input).getFile();
-				
-				if("isEditorOfType".equals(property)) {
-					result = SigilUtils.isResourceType(file, (String) expectedValue);
-				}
-			}
-		}
-		
-		return result;
-	}
+    public boolean test( Object receiver, String property, Object[] args, Object expectedValue )
+    {
+        IWorkbenchPart part = ( IWorkbenchPart ) receiver;
+
+        boolean result = false;
+
+        if ( part instanceof IEditorPart )
+        {
+            IEditorInput input = ( ( IEditorPart ) part ).getEditorInput();
+            if ( input instanceof IFileEditorInput )
+            {
+                IFile file = ( ( IFileEditorInput ) input ).getFile();
+
+                if ( "isEditorOfType".equals( property ) )
+                {
+                    result = SigilUtils.isResourceType( file, ( String ) expectedValue );
+                }
+            }
+        }
+
+        return result;
+    }
 
 }
diff --git a/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/properties/PartKindPropertyTester.java b/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/properties/PartKindPropertyTester.java
index 7a9e0f9..92653b1 100644
--- a/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/properties/PartKindPropertyTester.java
+++ b/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/properties/PartKindPropertyTester.java
@@ -19,32 +19,46 @@
 
 package org.apache.felix.sigil.utils.properties;
 
+
 import org.eclipse.core.expressions.PropertyTester;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IViewPart;
 import org.eclipse.ui.IWorkbenchPart;
 
-public class PartKindPropertyTester extends PropertyTester{
 
-	public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
-		IWorkbenchPart part = (IWorkbenchPart) receiver;
-		
-		Object value;
-		if("partKind".equals(property)) {
-			if(part instanceof IEditorPart) {
-				value = "editor";
-			} else if(part instanceof IViewPart) {
-				value = "view";
-			} else {
-				value = null;
-			}
-		} else if("partId".equals(property)) {
-			value = part.getSite().getId();
-		} else {
-			value = null;
-		}
-		
-		return expectedValue.equals(value);
-	}
-	
+public class PartKindPropertyTester extends PropertyTester
+{
+
+    public boolean test( Object receiver, String property, Object[] args, Object expectedValue )
+    {
+        IWorkbenchPart part = ( IWorkbenchPart ) receiver;
+
+        Object value;
+        if ( "partKind".equals( property ) )
+        {
+            if ( part instanceof IEditorPart )
+            {
+                value = "editor";
+            }
+            else if ( part instanceof IViewPart )
+            {
+                value = "view";
+            }
+            else
+            {
+                value = null;
+            }
+        }
+        else if ( "partId".equals( property ) )
+        {
+            value = part.getSite().getId();
+        }
+        else
+        {
+            value = null;
+        }
+
+        return expectedValue.equals( value );
+    }
+
 }
diff --git a/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/properties/ResourceTypePropertyTester.java b/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/properties/ResourceTypePropertyTester.java
index fc56df1..3c35b5d 100644
--- a/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/properties/ResourceTypePropertyTester.java
+++ b/sigil/eclipse/utils/src/org/apache/felix/sigil/utils/properties/ResourceTypePropertyTester.java
@@ -19,34 +19,41 @@
 
 package org.apache.felix.sigil.utils.properties;
 
+
 import org.eclipse.core.expressions.PropertyTester;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.content.IContentType;
 
-public class ResourceTypePropertyTester extends PropertyTester {
 
-	public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
-		if (!(receiver instanceof IResource)) {
-			return false;
-		}
+public class ResourceTypePropertyTester extends PropertyTester
+{
 
-		boolean result = false;
+    public boolean test( Object receiver, String property, Object[] args, Object expectedValue )
+    {
+        if ( !( receiver instanceof IResource ) )
+        {
+            return false;
+        }
 
-		IResource resource = (IResource) receiver;
-		if ("isResourceOfType".equals(property)) {
-			IContentType[] types = Platform.getContentTypeManager().findContentTypesFor(
-					resource.getName());
+        boolean result = false;
 
-			for (IContentType type : types) {
-				if (type.getId().equals(expectedValue)) {
-					result = true;
-					break;
-				}
-			}
-		}
+        IResource resource = ( IResource ) receiver;
+        if ( "isResourceOfType".equals( property ) )
+        {
+            IContentType[] types = Platform.getContentTypeManager().findContentTypesFor( resource.getName() );
 
-		return result;
-	}
+            for ( IContentType type : types )
+            {
+                if ( type.getId().equals( expectedValue ) )
+                {
+                    result = true;
+                    break;
+                }
+            }
+        }
+
+        return result;
+    }
 
 }
diff --git a/sigil/ivy/resolver/src/org/apache/felix/sigil/ant/BundleInfoTask.java b/sigil/ivy/resolver/src/org/apache/felix/sigil/ant/BundleInfoTask.java
index 5971ddf..20791d2 100644
--- a/sigil/ivy/resolver/src/org/apache/felix/sigil/ant/BundleInfoTask.java
+++ b/sigil/ivy/resolver/src/org/apache/felix/sigil/ant/BundleInfoTask.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ant;
 
+
 import java.io.File;
 import java.io.IOException;
 import java.util.jar.JarFile;
@@ -27,58 +28,78 @@
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Task;
 
-public class BundleInfoTask extends Task {
-	private File bundle;
-	private String header;
-	private String property;
-	private String defaultValue;
-	
-	@Override
-	public void execute() throws BuildException {
-		if (bundle == null)
-			throw new BuildException("missing attribute: bundle");
-		if (header == null)
-			throw new BuildException("missing attribute: header");
-		
-		try {
-			JarFile jar = new JarFile(bundle);
-			Manifest mf = jar.getManifest();
-			String value = mf.getMainAttributes().getValue(header);
-			if ( property == null ) {
-				log(header + "=" + value);
-			}
-			else {
-			    if ("Bundle-SymbolicName".equals(header) && value != null) {
-			        // remove singleton flag
-			        int semi = value.indexOf(';');
-			        if (semi > 0)
-			            value = value.substring(0, semi);
-			    }
-				if ( value == null ) {
-					value = defaultValue;
-				}
-				if ( value != null ) {
-					getProject().setNewProperty(property, value);
-				}
-			}
-		} catch (IOException e) {
-			throw new BuildException( "Failed to access bundle", e);
-		}
-	}
-	
-	public void setBundle(String bundle) {
-		this.bundle = new File( bundle );
-	}
-	
-	public void setHeader(String header) {
-		this.header = header;
-	}
-	
-	public void setProperty(String property) {
-		this.property = property;
-	}
-	
-	public void setDefaultValue(String defaultValue) {
-		this.defaultValue = defaultValue;
-	}
+
+public class BundleInfoTask extends Task
+{
+    private File bundle;
+    private String header;
+    private String property;
+    private String defaultValue;
+
+
+    @Override
+    public void execute() throws BuildException
+    {
+        if ( bundle == null )
+            throw new BuildException( "missing attribute: bundle" );
+        if ( header == null )
+            throw new BuildException( "missing attribute: header" );
+
+        try
+        {
+            JarFile jar = new JarFile( bundle );
+            Manifest mf = jar.getManifest();
+            String value = mf.getMainAttributes().getValue( header );
+            if ( property == null )
+            {
+                log( header + "=" + value );
+            }
+            else
+            {
+                if ( "Bundle-SymbolicName".equals( header ) && value != null )
+                {
+                    // remove singleton flag
+                    int semi = value.indexOf( ';' );
+                    if ( semi > 0 )
+                        value = value.substring( 0, semi );
+                }
+                if ( value == null )
+                {
+                    value = defaultValue;
+                }
+                if ( value != null )
+                {
+                    getProject().setNewProperty( property, value );
+                }
+            }
+        }
+        catch ( IOException e )
+        {
+            throw new BuildException( "Failed to access bundle", e );
+        }
+    }
+
+
+    public void setBundle( String bundle )
+    {
+        this.bundle = new File( bundle );
+    }
+
+
+    public void setHeader( String header )
+    {
+        this.header = header;
+    }
+
+
+    public void setProperty( String property )
+    {
+        this.property = property;
+    }
+
+
+    public void setDefaultValue( String defaultValue )
+    {
+        this.defaultValue = defaultValue;
+    }
 }
diff --git a/sigil/ivy/resolver/src/org/apache/felix/sigil/ant/BundleTask.java b/sigil/ivy/resolver/src/org/apache/felix/sigil/ant/BundleTask.java
index ba75de1..6354e1e 100644
--- a/sigil/ivy/resolver/src/org/apache/felix/sigil/ant/BundleTask.java
+++ b/sigil/ivy/resolver/src/org/apache/felix/sigil/ant/BundleTask.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ant;
 
+
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
@@ -35,119 +36,164 @@
 import org.apache.tools.ant.Task;
 import org.apache.tools.ant.types.Path;
 
-public class BundleTask extends Task {
-	private File[] classpath;
-	private String destPattern;
-	private boolean force;
-	private String property;
-	private String sigilFile;
 
-	@Override
-	public void execute() throws BuildException {
-		if (classpath == null)
-			throw new BuildException("missing: attribute: classpathref");
-		if (destPattern == null)
-			throw new BuildException("missing attribute: destpattern");
-		
-		IBldProject project;
+public class BundleTask extends Task
+{
+    private File[] classpath;
+    private String destPattern;
+    private boolean force;
+    private String property;
+    private String sigilFile;
 
-		try {
-			project = BldFactory.getProject(getSigilFileURI());
 
-		} catch (IOException e) {
-			throw new BuildException("failed to get project file: " + e);
-		}
-		
-		Properties env = new Properties();
-		@SuppressWarnings("unchecked") Hashtable<String, String> properties = getProject().getProperties();
-		for (String key : properties.keySet()) {
-			if (key.matches("^[a-z].*")) {    // avoid props starting with Uppercase - bnd adds them to manifest
-				env.setProperty(key, properties.get(key));
-			}
-		}
-		
-		BundleBuilder bb = new BundleBuilder(project, classpath, destPattern, env);
-		boolean anyModified = false;
+    @Override
+    public void execute() throws BuildException
+    {
+        if ( classpath == null )
+            throw new BuildException( "missing: attribute: classpathref" );
+        if ( destPattern == null )
+            throw new BuildException( "missing attribute: destpattern" );
 
-		for (IBldBundle bundle : project.getBundles()) {
-			String id = bundle.getId();
-			log("creating bundle: " + id);
-			int nWarn = 0;
-			int nErr = 0;
-			String msg = "";
-			
-			try {
-				boolean modified = (bb.createBundle(bundle, force, new BundleBuilder.Log() {
-					public void warn(String msg) {
-						log(msg, Project.MSG_WARN);
-					}
-					public void verbose(String msg) {
-						log(msg, Project.MSG_VERBOSE);
-					}
-				}));
-				nWarn = bb.warnings().size();
-				if (modified) {
-					anyModified = true;
-				} else {
-					msg = " (not modified)";
-				}
-			} catch (Exception e) {
-				List<String> errors = bb.errors();
-				if (errors != null) {
-    				nErr = errors.size();
-    				for (String err : errors) {
-    					log(err, Project.MSG_ERR);
-    				}
-				}
-				throw new BuildException("failed to create: " + id + ": " + e, e);
-			} finally {
-				log(id + ": " + count(nErr, "error") + ", " + count(nWarn, "warning") + msg);
-			}
-		}
-		
-		if (anyModified && property != null) {
-			getProject().setProperty(property, "true");
-		}
-	}
-	
-	private URI getSigilFileURI() {
-		File file = sigilFile == null ? new File(getProject().getBaseDir(), IBldProject.PROJECT_FILE) : new File(sigilFile);
-		if ( !file.isFile() ) {
-			throw new BuildException( "File not found " + file.getAbsolutePath() );
-		}
-		return file.toURI();
-	}
+        IBldProject project;
 
-	private String count(int count, String msg) {
-		return count + " " + msg + (count == 1 ? "" : "s");
-	}
+        try
+        {
+            project = BldFactory.getProject( getSigilFileURI() );
 
-	public void setDestpattern(String pattern) {
-		this.destPattern = pattern;
-	}
-	
-	public void setForce(String force) {
-		this.force = Boolean.parseBoolean(force);
-	}
-	
-	public void setProperty(String property) {
-		this.property = property;
-	}
+        }
+        catch ( IOException e )
+        {
+            throw new BuildException( "failed to get project file: " + e );
+        }
 
-	public void setClasspathref(String value) {
-		Path p = (Path) getProject().getReference(value);
-		if (p == null) {
-			throw new BuildException(value + "is not a path reference.");
-		}
+        Properties env = new Properties();
+        @SuppressWarnings("unchecked")
+        Hashtable<String, String> properties = getProject().getProperties();
+        for ( String key : properties.keySet() )
+        {
+            if ( key.matches( "^[a-z].*" ) )
+            { // avoid props starting with Uppercase - bnd adds them to manifest
+                env.setProperty( key, properties.get( key ) );
+            }
+        }
 
-		String[] paths = p.list();
-		classpath = new File[paths.length];
-		for (int i = 0; i < paths.length; ++i) {
-			classpath[i] = new File(paths[i]);
-		}
-	}
+        BundleBuilder bb = new BundleBuilder( project, classpath, destPattern, env );
+        boolean anyModified = false;
 
-	public void setSigilFile(String sigilFile) {
-		this.sigilFile = sigilFile;
-	}
+        for ( IBldBundle bundle : project.getBundles() )
+        {
+            String id = bundle.getId();
+            log( "creating bundle: " + id );
+            int nWarn = 0;
+            int nErr = 0;
+            String msg = "";
+
+            try
+            {
+                boolean modified = ( bb.createBundle( bundle, force, new BundleBuilder.Log()
+                {
+                    public void warn( String msg )
+                    {
+                        log( msg, Project.MSG_WARN );
+                    }
+
+
+                    public void verbose( String msg )
+                    {
+                        log( msg, Project.MSG_VERBOSE );
+                    }
+                } ) );
+                nWarn = bb.warnings().size();
+                if ( modified )
+                {
+                    anyModified = true;
+                }
+                else
+                {
+                    msg = " (not modified)";
+                }
+            }
+            catch ( Exception e )
+            {
+                List<String> errors = bb.errors();
+                if ( errors != null )
+                {
+                    nErr = errors.size();
+                    for ( String err : errors )
+                    {
+                        log( err, Project.MSG_ERR );
+                    }
+                }
+                throw new BuildException( "failed to create: " + id + ": " + e, e );
+            }
+            finally
+            {
+                log( id + ": " + count( nErr, "error" ) + ", " + count( nWarn, "warning" ) + msg );
+            }
+        }
+
+        if ( anyModified && property != null )
+        {
+            getProject().setProperty( property, "true" );
+        }
+    }
+
+
+    private URI getSigilFileURI()
+    {
+        File file = sigilFile == null ? new File( getProject().getBaseDir(), IBldProject.PROJECT_FILE ) : new File(
+            sigilFile );
+        if ( !file.isFile() )
+        {
+            throw new BuildException( "File not found " + file.getAbsolutePath() );
+        }
+        return file.toURI();
+    }
+
+
+    private String count( int count, String msg )
+    {
+        return count + " " + msg + ( count == 1 ? "" : "s" );
+    }
+
+
+    public void setDestpattern( String pattern )
+    {
+        this.destPattern = pattern;
+    }
+
+
+    public void setForce( String force )
+    {
+        this.force = Boolean.parseBoolean( force );
+    }
+
+
+    public void setProperty( String property )
+    {
+        this.property = property;
+    }
+
+
+    public void setClasspathref( String value )
+    {
+        Path p = ( Path ) getProject().getReference( value );
+        if ( p == null )
+        {
+            throw new BuildException( value + "is not a path reference." );
+        }
+
+        String[] paths = p.list();
+        classpath = new File[paths.length];
+        for ( int i = 0; i < paths.length; ++i )
+        {
+            classpath[i] = new File( paths[i] );
+        }
+    }
+
+
+    public void setSigilFile( String sigilFile )
+    {
+        this.sigilFile = sigilFile;
+    }
 }
diff --git a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/BldRepositoryManager.java b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/BldRepositoryManager.java
index d558415..5cf7b94 100644
--- a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/BldRepositoryManager.java
+++ b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/BldRepositoryManager.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ivy;
 
+
 import java.io.File;
 import java.util.HashMap;
 import java.util.Map;
@@ -29,59 +30,73 @@
 import org.apache.felix.sigil.repository.IBundleRepository;
 import org.apache.felix.sigil.repository.IRepositoryProvider;
 
-public class BldRepositoryManager extends AbstractRepositoryManager {
-	private static Map<String, String> aliases = new HashMap<String, String>();
 
-	static {
-		aliases.put("filesystem", "org.cauldron.bld.core.repository.FileSystemRepositoryProvider");
-		aliases.put("obr", "org.cauldron.bld.obr.OBRRepositoryProvider");
-		aliases.put("project", "org.cauldron.bld.ivy.ProjectRepositoryProvider");
-		aliases.put("system", "org.cauldron.bld.core.repository.SystemRepositoryProvider");
-	};
+public class BldRepositoryManager extends AbstractRepositoryManager
+{
+    private static Map<String, String> aliases = new HashMap<String, String>();
 
-	private Map<String, Properties> repos;
+    static
+    {
+        aliases.put( "filesystem", "org.cauldron.bld.core.repository.FileSystemRepositoryProvider" );
+        aliases.put( "obr", "org.cauldron.bld.obr.OBRRepositoryProvider" );
+        aliases.put( "project", "org.cauldron.bld.ivy.ProjectRepositoryProvider" );
+        aliases.put( "system", "org.cauldron.bld.core.repository.SystemRepositoryProvider" );
+    };
 
-	public BldRepositoryManager(Map<String, Properties> repos) {
-		this.repos = repos;
-	}
+    private Map<String, Properties> repos;
 
-	@Override
-	protected void loadRepositories() {
-		for (String name : repos.keySet()) {
-			Properties repo = repos.get(name);
 
-			String alias = repo.getProperty(IRepositoryConfig.REPOSITORY_PROVIDER);
-			if (alias == null) {
-				Log.error("provider not specified for repository: " + name);
-				continue;
-			}
-			
-			String provider = (aliases.containsKey(alias) ? aliases.get(alias) : alias);
+    public BldRepositoryManager( Map<String, Properties> repos )
+    {
+        this.repos = repos;
+    }
 
-            if (alias.equals("obr")) {
-				// cache is directory where synchronized bundles are stored;
-				// not needed in ivy.
-				repo.setProperty("cache", "/no-cache");
-				
-				if (!repo.containsKey("index")) {
-    				// index is created as copy of url
-    				File indexFile = new File(System.getProperty("java.io.tmpdir"), "obr-index-" + name);
-    				indexFile.deleteOnExit();
-    				repo.setProperty("index", indexFile.getAbsolutePath());
-				}
-			}
 
-			int level = Integer.parseInt(repo.getProperty(IRepositoryConfig.REPOSITORY_LEVEL,
-					IBundleRepository.NORMAL_PRIORITY + ""));
+    @Override
+    protected void loadRepositories()
+    {
+        for ( String name : repos.keySet() )
+        {
+            Properties repo = repos.get( name );
 
-			try {
-				IRepositoryProvider instance = (IRepositoryProvider) (Class.forName(provider).newInstance());
-				IBundleRepository repository = instance.createRepository(name, repo);
-				addRepository(repository, level);
-				Log.verbose("added repository: " + repository);
-			} catch (Exception e) {
-				throw new Error("createRepository() failed: " + repo + " : " + e, e);
-			}
-		}
-	}
+            String alias = repo.getProperty( IRepositoryConfig.REPOSITORY_PROVIDER );
+            if ( alias == null )
+            {
+                Log.error( "provider not specified for repository: " + name );
+                continue;
+            }
+
+            String provider = ( aliases.containsKey( alias ) ? aliases.get( alias ) : alias );
+
+            if ( alias.equals( "obr" ) )
+            {
+                // cache is directory where synchronized bundles are stored;
+                // not needed in ivy.
+                repo.setProperty( "cache", "/no-cache" );
+
+                if ( !repo.containsKey( "index" ) )
+                {
+                    // index is created as copy of url
+                    File indexFile = new File( System.getProperty( "java.io.tmpdir" ), "obr-index-" + name );
+                    indexFile.deleteOnExit();
+                    repo.setProperty( "index", indexFile.getAbsolutePath() );
+                }
+            }
+
+            int level = Integer.parseInt( repo.getProperty( IRepositoryConfig.REPOSITORY_LEVEL,
+                IBundleRepository.NORMAL_PRIORITY + "" ) );
+
+            try
+            {
+                IRepositoryProvider instance = ( IRepositoryProvider ) ( Class.forName( provider ).newInstance() );
+                IBundleRepository repository = instance.createRepository( name, repo );
+                addRepository( repository, level );
+                Log.verbose( "added repository: " + repository );
+            }
+            catch ( Exception e )
+            {
+                throw new Error( "createRepository() failed: " + repo + " : " + e, e );
+            }
+        }
+    }
 }
diff --git a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/BldResolver.java b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/BldResolver.java
index 9f1a6f0..34e5a70 100644
--- a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/BldResolver.java
+++ b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/BldResolver.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ivy;
 
+
 import java.util.Map;
 import java.util.Properties;
 
@@ -30,59 +31,85 @@
 import org.apache.felix.sigil.repository.ResolutionConfig;
 import org.apache.felix.sigil.repository.ResolutionException;
 
-public class BldResolver implements IBldResolver {
-	private Map<String, Properties> repos;
-	private BldRepositoryManager manager;
-	
-	static {
-		try {
-			BldCore.init();
-		} catch (Exception e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	};
-	
-	public BldResolver(Map<String,Properties> repos) {
-		this.repos = repos;
-	}
 
-	public IResolution resolve(IModelElement element, boolean transitive) {
-		int options = ResolutionConfig.IGNORE_ERRORS | ResolutionConfig.INCLUDE_OPTIONAL;
-		if (transitive) options |= ResolutionConfig.INCLUDE_DEPENDENTS;
-		
-		ResolutionConfig config = new ResolutionConfig(options);
-		try {
-			return resolve(element, config);
-		} catch (ResolutionException e) {
-			throw new IllegalStateException("eek! this shouldn't happen when ignoreErrors=true", e);
-		}
-	}
-		
-	public IResolution resolveOrFail(IModelElement element, boolean transitive) throws ResolutionException {
-		int options = 0;
-		if ( transitive ) options |= ResolutionConfig.INCLUDE_DEPENDENTS;
-		ResolutionConfig config = new ResolutionConfig(options);
-		return resolve(element, config);
-	}
-	
-	private IResolution resolve(IModelElement element, ResolutionConfig config) throws ResolutionException {
-		if (manager == null) {
-			manager = new BldRepositoryManager(repos);
-		}
+public class BldResolver implements IBldResolver
+{
+    private Map<String, Properties> repos;
+    private BldRepositoryManager manager;
 
-		IResolutionMonitor nullMonitor = new IResolutionMonitor() {
-			public void endResolution(IModelElement requirement, ISigilBundle sigilBundle) {
-			}
+    static
+    {
+        try
+        {
+            BldCore.init();
+        }
+        catch ( Exception e )
+        {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    };
 
-			public boolean isCanceled() {
-				return false;
-			}
 
-			public void startResolution(IModelElement requirement) {
-			}
-		};
+    public BldResolver( Map<String, Properties> repos )
+    {
+        this.repos = repos;
+    }
 
-		return manager.getBundleResolver().resolve(element, config, nullMonitor);
-	}
+
+    public IResolution resolve( IModelElement element, boolean transitive )
+    {
+        int options = ResolutionConfig.IGNORE_ERRORS | ResolutionConfig.INCLUDE_OPTIONAL;
+        if ( transitive )
+            options |= ResolutionConfig.INCLUDE_DEPENDENTS;
+
+        ResolutionConfig config = new ResolutionConfig( options );
+        try
+        {
+            return resolve( element, config );
+        }
+        catch ( ResolutionException e )
+        {
+            throw new IllegalStateException( "eek! this shouldn't happen when ignoreErrors=true", e );
+        }
+    }
+
+
+    public IResolution resolveOrFail( IModelElement element, boolean transitive ) throws ResolutionException
+    {
+        int options = 0;
+        if ( transitive )
+            options |= ResolutionConfig.INCLUDE_DEPENDENTS;
+        ResolutionConfig config = new ResolutionConfig( options );
+        return resolve( element, config );
+    }
+
+
+    private IResolution resolve( IModelElement element, ResolutionConfig config ) throws ResolutionException
+    {
+        if ( manager == null )
+        {
+            manager = new BldRepositoryManager( repos );
+        }
+
+        IResolutionMonitor nullMonitor = new IResolutionMonitor()
+        {
+            public void endResolution( IModelElement requirement, ISigilBundle sigilBundle )
+            {
+            }
+
+
+            public boolean isCanceled()
+            {
+                return false;
+            }
+
+
+            public void startResolution( IModelElement requirement )
+            {
+            }
+        };
+
+        return manager.getBundleResolver().resolve( element, config, nullMonitor );
+    }
 }
diff --git a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/FindUtil.java b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/FindUtil.java
index e8f1a99..98525ad 100644
--- a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/FindUtil.java
+++ b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/FindUtil.java
@@ -19,79 +19,107 @@
 
 package org.apache.felix.sigil.ivy;
 
+
 import java.io.File;
 import java.io.FileFilter;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 
-public class FindUtil {
-	static final String WILD_ANY = "[^.].*";
-	static final String WILD_ONE = "[^.][^;]*";    // WILD_ONE.endsWith(WILD_ANY) == false
-	
-	// example pattern: ${repository}/projects/abc*/*/project.sigil
-	public static Collection<File> findFiles(String pattern) throws IOException {
-		int star = pattern.indexOf("*");
-		if (star == -1) {
-			throw new IOException("pattern doesn't contain '*': " + pattern);
-		}
-		int slash = pattern.lastIndexOf('/', star);
-		
-		String regex = pattern.substring(slash + 1);
-		regex = regex.replaceAll("\\*\\*", "-wildany-");
-		regex = regex.replaceAll("\\*", "-wildone-");
-		regex = regex.replaceAll("-wildany-", WILD_ANY);
-		regex = regex.replaceAll("-wildone-", WILD_ONE);
-		
-		String[] patterns = regex.split("/");
-		
-		ArrayList<File> list = new ArrayList<File>();
-		File root = new File(pattern.substring(0, slash));
-		
-		if (root.isDirectory()) {
-    		findFiles(root, 0, patterns, list);
-		} else {
-			throw new IOException("pattern root directory does not exist: " + root);
-		}
-		
-		return list;
-	}
-	
-	private static void findFiles(File dir, int level, String[] patterns, Collection<File> list) {
-		final String filePattern = patterns[patterns.length-1];
-		final String dirPattern;
-		
-		if (level < patterns.length-1) {
-			dirPattern = patterns[level];
-		} else {
-			dirPattern = "/";    // impossible to match marker
-		}
-		
-		final boolean stillWild;
-		if ((level > 0) && (level < patterns.length) && patterns[level-1].endsWith(WILD_ANY)) {
-			stillWild = true;
-		} else {
-			stillWild = false;
-		}
-		
-		for (File path : dir.listFiles(new FileFilter() {
-			public boolean accept(File pathname) {
-				String name = pathname.getName();
-				if (pathname.isDirectory()) {
-					return name.matches(dirPattern) || (stillWild && name.matches(WILD_ANY));
-				} else if (dirPattern.equals("/") || dirPattern.equals(WILD_ANY)) {
-					return name.matches(filePattern);
-				} else {
-					return false;
-				}
-			}
-		})) {
-			if (path.isDirectory()) {
-				int inc = path.getName().matches(dirPattern) ? 1 : 0;
-				findFiles(path, level + inc, patterns, list);
-			} else {
-				list.add(path);
-			}
-		}
-	}
+
+public class FindUtil
+{
+    static final String WILD_ANY = "[^.].*";
+    static final String WILD_ONE = "[^.][^;]*"; // WILD_ONE.endsWith(WILD_ANY) == false
+
+
+    // example pattern: ${repository}/projects/abc*/*/project.sigil
+    public static Collection<File> findFiles( String pattern ) throws IOException
+    {
+        int star = pattern.indexOf( "*" );
+        if ( star == -1 )
+        {
+            throw new IOException( "pattern doesn't contain '*': " + pattern );
+        }
+        int slash = pattern.lastIndexOf( '/', star );
+
+        String regex = pattern.substring( slash + 1 );
+        regex = regex.replaceAll( "\\*\\*", "-wildany-" );
+        regex = regex.replaceAll( "\\*", "-wildone-" );
+        regex = regex.replaceAll( "-wildany-", WILD_ANY );
+        regex = regex.replaceAll( "-wildone-", WILD_ONE );
+
+        String[] patterns = regex.split( "/" );
+
+        ArrayList<File> list = new ArrayList<File>();
+        File root = new File( pattern.substring( 0, slash ) );
+
+        if ( root.isDirectory() )
+        {
+            findFiles( root, 0, patterns, list );
+        }
+        else
+        {
+            throw new IOException( "pattern root directory does not exist: " + root );
+        }
+
+        return list;
+    }
+
+
+    private static void findFiles( File dir, int level, String[] patterns, Collection<File> list )
+    {
+        final String filePattern = patterns[patterns.length - 1];
+        final String dirPattern;
+
+        if ( level < patterns.length - 1 )
+        {
+            dirPattern = patterns[level];
+        }
+        else
+        {
+            dirPattern = "/"; // impossible to match marker
+        }
+
+        final boolean stillWild;
+        if ( ( level > 0 ) && ( level < patterns.length ) && patterns[level - 1].endsWith( WILD_ANY ) )
+        {
+            stillWild = true;
+        }
+        else
+        {
+            stillWild = false;
+        }
+
+        for ( File path : dir.listFiles( new FileFilter()
+        {
+            public boolean accept( File pathname )
+            {
+                String name = pathname.getName();
+                if ( pathname.isDirectory() )
+                {
+                    return name.matches( dirPattern ) || ( stillWild && name.matches( WILD_ANY ) );
+                }
+                else if ( dirPattern.equals( "/" ) || dirPattern.equals( WILD_ANY ) )
+                {
+                    return name.matches( filePattern );
+                }
+                else
+                {
+                    return false;
+                }
+            }
+        } ) )
+        {
+            if ( path.isDirectory() )
+            {
+                int inc = path.getName().matches( dirPattern ) ? 1 : 0;
+                findFiles( path, level + inc, patterns, list );
+            }
+            else
+            {
+                list.add( path );
+            }
+        }
+    }
 }
diff --git a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/IBldResolver.java b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/IBldResolver.java
index d94aaac..25a3bcf 100644
--- a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/IBldResolver.java
+++ b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/IBldResolver.java
@@ -19,11 +19,16 @@
 
 package org.apache.felix.sigil.ivy;
 
+
 import org.apache.felix.sigil.model.IModelElement;
 import org.apache.felix.sigil.repository.IResolution;
 import org.apache.felix.sigil.repository.ResolutionException;
 
-public interface IBldResolver {
-	IResolution resolveOrFail(IModelElement element, boolean transitive) throws ResolutionException;
-	IResolution resolve(IModelElement element, boolean transitive);
+
+public interface IBldResolver
+{
+    IResolution resolveOrFail( IModelElement element, boolean transitive ) throws ResolutionException;
+
+
+    IResolution resolve( IModelElement element, boolean transitive );
 }
diff --git a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/Log.java b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/Log.java
index 3e7fece..45171b5 100644
--- a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/Log.java
+++ b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/Log.java
@@ -19,43 +19,56 @@
 
 package org.apache.felix.sigil.ivy;
 
+
 import org.apache.ivy.util.Message;
 
+
 // ensure common prefix to all sigil messages
-public class Log {
-	public static final String PREFIX = "Sigil: ";
-	
-	private static final boolean highlight = false;
-	
-	public static void error(String msg) {
-		if (highlight)
-    		Message.deprecated(PREFIX + "[error] " + msg);
-		Message.error(PREFIX + msg);
-	}
+public class Log
+{
+    public static final String PREFIX = "Sigil: ";
 
-	public static void warn(String msg) {
-		if (highlight)
-    		Message.deprecated(PREFIX + "[warn] " + msg);
-		else
-    		Message.warn(PREFIX + msg);
-	}
-	
-	public static void info(String msg) {
-		if (highlight)
-    		Message.deprecated(PREFIX + "[info] " + msg);
-		else
-    		Message.info(PREFIX + msg);
-	}
+    private static final boolean highlight = false;
 
-	public static void verbose(String msg) {
-		Message.verbose(PREFIX + "[verbose] " + msg);
-	}
-	
-	public static void debug(String msg) {
-		if (highlight)
-    		Message.deprecated(PREFIX + "[debug] " + msg);
-		else
-    		Message.debug(PREFIX + msg);
-	}
+
+    public static void error( String msg )
+    {
+        if ( highlight )
+            Message.deprecated( PREFIX + "[error] " + msg );
+        Message.error( PREFIX + msg );
+    }
+
+
+    public static void warn( String msg )
+    {
+        if ( highlight )
+            Message.deprecated( PREFIX + "[warn] " + msg );
+        else
+            Message.warn( PREFIX + msg );
+    }
+
+
+    public static void info( String msg )
+    {
+        if ( highlight )
+            Message.deprecated( PREFIX + "[info] " + msg );
+        else
+            Message.info( PREFIX + msg );
+    }
+
+
+    public static void verbose( String msg )
+    {
+        Message.verbose( PREFIX + "[verbose] " + msg );
+    }
+
+
+    public static void debug( String msg )
+    {
+        if ( highlight )
+            Message.deprecated( PREFIX + "[debug] " + msg );
+        else
+            Message.debug( PREFIX + msg );
+    }
 
 }
diff --git a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/ProjectRepository.java b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/ProjectRepository.java
index 24d1c78..dec8b2b 100644
--- a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/ProjectRepository.java
+++ b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/ProjectRepository.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ivy;
 
+
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
@@ -46,75 +47,96 @@
 
 import org.osgi.framework.Version;
 
-public class ProjectRepository extends AbstractBundleRepository {
+
+public class ProjectRepository extends AbstractBundleRepository
+{
     private ArrayList<ISigilBundle> bundles;
     private ArrayList<ISigilBundle> wildBundles;
     private String projectFilePattern;
 
-    /* package */ProjectRepository(String id, String projectFilePattern) {
-        super(id);
-        this.projectFilePattern = projectFilePattern.replaceAll("\\[sigilproject\\]",
-                IBldProject.PROJECT_FILE);
+
+    /* package */ProjectRepository( String id, String projectFilePattern )
+    {
+        super( id );
+        this.projectFilePattern = projectFilePattern.replaceAll( "\\[sigilproject\\]", IBldProject.PROJECT_FILE );
     }
 
+
     @Override
-    public void accept(IRepositoryVisitor visitor, int options) {
-        for (ISigilBundle b : getBundles()) {
-            if (!visitor.visit(b)) {
+    public void accept( IRepositoryVisitor visitor, int options )
+    {
+        for ( ISigilBundle b : getBundles() )
+        {
+            if ( !visitor.visit( b ) )
+            {
                 break;
             }
         }
     }
 
+
     // override to provide fuzzy matching for wild-card exports.
     @Override
-    public Collection<ISigilBundle> findAllProviders(final IPackageImport pi, int options) {
-        return findProviders(pi, options, false);
+    public Collection<ISigilBundle> findAllProviders( final IPackageImport pi, int options )
+    {
+        return findProviders( pi, options, false );
     }
 
+
     @Override
-    public ISigilBundle findProvider(IPackageImport pi, int options) {
-        Collection<ISigilBundle> found = findProviders(pi, options, true);
+    public ISigilBundle findProvider( IPackageImport pi, int options )
+    {
+        Collection<ISigilBundle> found = findProviders( pi, options, true );
         return found.isEmpty() ? null : found.iterator().next();
     }
 
-    private Collection<ISigilBundle> findProviders(final IPackageImport pi, int options,
-            boolean findFirst) {
+
+    private Collection<ISigilBundle> findProviders( final IPackageImport pi, int options, boolean findFirst )
+    {
         ArrayList<ISigilBundle> found = new ArrayList<ISigilBundle>();
-        ILicensePolicy policy = findPolicy(pi);
+        ILicensePolicy policy = findPolicy( pi );
         String name = pi.getPackageName();
         VersionRange versions = pi.getVersions();
 
         // find exact match(es)
-        for (ISigilBundle bundle : getBundles()) {
-            if (policy.accept(bundle)) {
-                for (IPackageExport exp : bundle.getBundleInfo().getExports()) {
-                    if (name.equals(exp.getPackageName())
-                            && versions.contains(exp.getVersion())) {
-                        found.add(bundle);
-                        if (findFirst)
+        for ( ISigilBundle bundle : getBundles() )
+        {
+            if ( policy.accept( bundle ) )
+            {
+                for ( IPackageExport exp : bundle.getBundleInfo().getExports() )
+                {
+                    if ( name.equals( exp.getPackageName() ) && versions.contains( exp.getVersion() ) )
+                    {
+                        found.add( bundle );
+                        if ( findFirst )
                             return found;
                     }
                 }
             }
         }
 
-        if (!found.isEmpty())
+        if ( !found.isEmpty() )
             return found;
 
         // find best fuzzy match
         ISigilBundle fuzzyMatch = null;
         int fuzzyLen = 0;
 
-        for (ISigilBundle bundle : getWildBundles()) {
-            if (policy.accept(bundle)) {
-                for (IPackageExport exp : bundle.getBundleInfo().getExports()) {
+        for ( ISigilBundle bundle : getWildBundles() )
+        {
+            if ( policy.accept( bundle ) )
+            {
+                for ( IPackageExport exp : bundle.getBundleInfo().getExports() )
+                {
                     String export = exp.getPackageName();
-                    if (export.endsWith("*")) {
-                        String export1 = export.substring(0, export.length() - 1);
-                        if ((name.startsWith(export1) || export1.equals(name + "."))
-                                && versions.contains(exp.getVersion())) {
-                            if (export1.length() > fuzzyLen) {
+                    if ( export.endsWith( "*" ) )
+                    {
+                        String export1 = export.substring( 0, export.length() - 1 );
+                        if ( ( name.startsWith( export1 ) || export1.equals( name + "." ) )
+                            && versions.contains( exp.getVersion() ) )
+                        {
+                            if ( export1.length() > fuzzyLen )
+                            {
                                 fuzzyLen = export1.length();
                                 fuzzyMatch = bundle;
                             }
@@ -124,65 +146,89 @@
             }
         }
 
-        if (fuzzyMatch != null)
-            found.add(fuzzyMatch);
+        if ( fuzzyMatch != null )
+            found.add( fuzzyMatch );
 
         return found;
     }
 
-    private synchronized void init() {
-        System.out.println("Sigil: loading Project Repository: " + projectFilePattern);
+
+    private synchronized void init()
+    {
+        System.out.println( "Sigil: loading Project Repository: " + projectFilePattern );
 
         ArrayList<File> projects = new ArrayList<File>();
 
-        for (String pattern : projectFilePattern.split("\\s+")) {
-            try {
-                Collection<File> files = FindUtil.findFiles(pattern);
-                if (files.isEmpty()) {
-                    Log.warn("ProjectRepository: no projects match: " + pattern);
-                } else {
-                    projects.addAll(files);
+        for ( String pattern : projectFilePattern.split( "\\s+" ) )
+        {
+            try
+            {
+                Collection<File> files = FindUtil.findFiles( pattern );
+                if ( files.isEmpty() )
+                {
+                    Log.warn( "ProjectRepository: no projects match: " + pattern );
                 }
-            } catch (IOException e) {
+                else
+                {
+                    projects.addAll( files );
+                }
+            }
+            catch ( IOException e )
+            {
                 // pattern root dir does not exist
-                Log.error("ProjectRepository: " + pattern + ": " + e.getMessage());
+                Log.error( "ProjectRepository: " + pattern + ": " + e.getMessage() );
             }
         }
 
-        if (projects.isEmpty()) {
-            throw new IllegalArgumentException(
-                    "ProjectRepository: no projects found using pattern: "
-                            + projectFilePattern);
+        if ( projects.isEmpty() )
+        {
+            throw new IllegalArgumentException( "ProjectRepository: no projects found using pattern: "
+                + projectFilePattern );
         }
 
         bundles = new ArrayList<ISigilBundle>();
 
-        for (File proj : projects) {
-            try {
-                addBundles(proj, bundles);
-            } catch (IOException e) {
-                Log.warn("Skipping project: " + proj + ": " + e.getMessage());
-            } catch (ParseException e) {
-                Log.warn("Skipping project: " + proj + ": " + e.getMessage());
+        for ( File proj : projects )
+        {
+            try
+            {
+                addBundles( proj, bundles );
+            }
+            catch ( IOException e )
+            {
+                Log.warn( "Skipping project: " + proj + ": " + e.getMessage() );
+            }
+            catch ( ParseException e )
+            {
+                Log.warn( "Skipping project: " + proj + ": " + e.getMessage() );
             }
         }
     }
 
-    private List<ISigilBundle> getBundles() {
-        if (bundles == null) {
+
+    private List<ISigilBundle> getBundles()
+    {
+        if ( bundles == null )
+        {
             init();
         }
         return bundles;
     }
 
-    private List<ISigilBundle> getWildBundles() {
-        if (wildBundles == null) {
+
+    private List<ISigilBundle> getWildBundles()
+    {
+        if ( wildBundles == null )
+        {
             wildBundles = new ArrayList<ISigilBundle>();
-            for (ISigilBundle bundle : getBundles()) {
-                for (IPackageExport exp : bundle.getBundleInfo().getExports()) {
+            for ( ISigilBundle bundle : getBundles() )
+            {
+                for ( IPackageExport exp : bundle.getBundleInfo().getExports() )
+                {
                     String export = exp.getPackageName();
-                    if (export.endsWith("*")) {
-                        wildBundles.add(bundle);
+                    if ( export.endsWith( "*" ) )
+                    {
+                        wildBundles.add( bundle );
                         break;
                     }
                 }
@@ -191,100 +237,125 @@
         return wildBundles;
     }
 
-    public void refresh() {
+
+    public void refresh()
+    {
         bundles = null;
         wildBundles = null;
         notifyChange();
     }
 
-    private void addBundles(File file, List<ISigilBundle> list) throws IOException,
-            ParseException {
-        URI uri = file.getCanonicalFile().toURI();
-        IBldProject project = BldFactory.getProject(uri);
 
-        for (IBldBundle bb : project.getBundles()) {
+    private void addBundles( File file, List<ISigilBundle> list ) throws IOException, ParseException
+    {
+        URI uri = file.getCanonicalFile().toURI();
+        IBldProject project = BldFactory.getProject( uri );
+
+        for ( IBldBundle bb : project.getBundles() )
+        {
             IBundleModelElement info = new BundleModelElement();
 
-            for (IPackageExport pexport : bb.getExports()) {
-                info.addExport(pexport);
+            for ( IPackageExport pexport : bb.getExports() )
+            {
+                info.addExport( pexport );
             }
 
-            for (IPackageImport import1 : bb.getImports()) {
-                IPackageImport clone = (IPackageImport) import1.clone();
-                clone.setParent(null);
-                info.addImport(clone);
+            for ( IPackageImport import1 : bb.getImports() )
+            {
+                IPackageImport clone = ( IPackageImport ) import1.clone();
+                clone.setParent( null );
+                info.addImport( clone );
             }
 
-            for (IRequiredBundle require : bb.getRequires()) {
-                IRequiredBundle clone = (IRequiredBundle) require.clone();
-                clone.setParent(null);
-                info.addRequiredBundle(clone);
+            for ( IRequiredBundle require : bb.getRequires() )
+            {
+                IRequiredBundle clone = ( IRequiredBundle ) require.clone();
+                clone.setParent( null );
+                info.addRequiredBundle( clone );
             }
 
-            info.setSymbolicName(bb.getSymbolicName());
+            info.setSymbolicName( bb.getSymbolicName() );
 
-            Version version = new Version(bb.getVersion());
-            info.setVersion(version);
+            Version version = new Version( bb.getVersion() );
+            info.setVersion( version );
 
             ProjectBundle pb = new ProjectBundle();
-            pb.setBundleInfo(info);
-            pb.setId(bb.getId());
+            pb.setBundleInfo( info );
+            pb.setId( bb.getId() );
 
-            ModuleDescriptor md = SigilParser.instance().parseDescriptor(uri.toURL());
+            ModuleDescriptor md = SigilParser.instance().parseDescriptor( uri.toURL() );
 
             ModuleRevisionId mrid = md.getModuleRevisionId();
-            pb.setModule(mrid.getName());
-            pb.setOrg(mrid.getOrganisation());
+            pb.setModule( mrid.getName() );
+            pb.setOrg( mrid.getOrganisation() );
             // XXX: should revision be configurable?
-            pb.setRevision("latest." + md.getStatus());
+            pb.setRevision( "latest." + md.getStatus() );
 
-            list.add(pb);
-            Log.debug("ProjectRepository: added " + pb);
-            Log.debug("ProjectRepository: exports " + bb.getExports());
+            list.add( pb );
+            Log.debug( "ProjectRepository: added " + pb );
+            Log.debug( "ProjectRepository: exports " + bb.getExports() );
         }
     }
 
-    public static class ProjectBundle extends SigilBundle {
+    public static class ProjectBundle extends SigilBundle
+    {
         private String id;
         private String module;
         private String org;
         private String revision;
 
+
         @Override
-        public String toString() {
-            return "ProjectBundle[" + org + "@" + module + (id == null ? "" : "$" + id)
-                    + "#" + revision + "]";
+        public String toString()
+        {
+            return "ProjectBundle[" + org + "@" + module + ( id == null ? "" : "$" + id ) + "#" + revision + "]";
         }
 
-        public String getModule() {
+
+        public String getModule()
+        {
             return module;
         }
 
-        public void setModule(String module) {
+
+        public void setModule( String module )
+        {
             this.module = module;
         }
 
-        public String getId() {
+
+        public String getId()
+        {
             return id;
         }
 
-        public void setId(String id) {
+
+        public void setId( String id )
+        {
             this.id = id;
         }
 
-        public String getRevision() {
+
+        public String getRevision()
+        {
             return revision;
         }
 
-        public void setRevision(String rev) {
+
+        public void setRevision( String rev )
+        {
             this.revision = rev;
         }
 
-        public String getOrg() {
+
+        public String getOrg()
+        {
             return org;
         }
 
-        public void setOrg(String org) {
+
+        public void setOrg( String org )
+        {
             this.org = org;
         }
     }
diff --git a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/ProjectRepositoryProvider.java b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/ProjectRepositoryProvider.java
index 346d464..e47b0f3 100644
--- a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/ProjectRepositoryProvider.java
+++ b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/ProjectRepositoryProvider.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ivy;
 
+
 import java.util.HashMap;
 import java.util.Properties;
 
@@ -26,21 +27,27 @@
 import org.apache.felix.sigil.repository.IRepositoryProvider;
 import org.apache.felix.sigil.repository.RepositoryException;
 
-public class ProjectRepositoryProvider implements IRepositoryProvider{
-	private static HashMap<String, ProjectRepository> cache = new HashMap<String, ProjectRepository>();
-	
-	public IBundleRepository createRepository(String id, Properties properties) throws RepositoryException {
-		ProjectRepository repository = cache.get(id);
-		
-		if (repository == null) {
-    		String pattern = properties.getProperty("pattern");
-    		if (pattern == null) {
-    		    throw new RepositoryException("property 'pattern' not specified.");
-    		}
-            repository = new ProjectRepository(id, pattern);
-            cache.put(id, repository);
-		}
-		
+
+public class ProjectRepositoryProvider implements IRepositoryProvider
+{
+    private static HashMap<String, ProjectRepository> cache = new HashMap<String, ProjectRepository>();
+
+
+    public IBundleRepository createRepository( String id, Properties properties ) throws RepositoryException
+    {
+        ProjectRepository repository = cache.get( id );
+
+        if ( repository == null )
+        {
+            String pattern = properties.getProperty( "pattern" );
+            if ( pattern == null )
+            {
+                throw new RepositoryException( "property 'pattern' not specified." );
+            }
+            repository = new ProjectRepository( id, pattern );
+            cache.put( id, repository );
+        }
+
         return repository;
     }
 }
diff --git a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/SigilParser.java b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/SigilParser.java
index 5d8e29e..99e7ac9 100644
--- a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/SigilParser.java
+++ b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/SigilParser.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ivy;
 
+
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -60,518 +61,636 @@
 import org.apache.ivy.plugins.repository.url.URLResource;
 import org.apache.ivy.plugins.resolver.DependencyResolver;
 
-public class SigilParser implements ModuleDescriptorParser {
 
-	private static DelegateParser instance;
+public class SigilParser implements ModuleDescriptorParser
+{
 
-	// used by ProjectRepository
-    static DelegateParser instance() {
-		if (instance == null)
-			throw new IllegalStateException("SigilParser is not instantiated.");
-		return instance;
-	}
+    private static DelegateParser instance;
 
-	public SigilParser() {
-		if (instance == null) {
-			instance = new DelegateParser();
-		}
-	}
-	
-	/**
-	 * In IvyDE, IvyContext is not available, so we can't find the SigilResolver.
-	 * This allows us to construct one.
-	 * @deprecated temporary to support IvyDE
-	 */
-	public void setConfig(String config) {
-		instance.config = config;
-	}
 
-	/**
-	 * sets delegate parser.
-	 * If not set, we delegate to the default Ivy parser.
-	 * @param type name returned by desired parser's getType() method.
-	 */
-	public void setDelegateType(String type) {
-		for (ModuleDescriptorParser parser : ModuleDescriptorParserRegistry.getInstance().getParsers()) {
-			if (parser.getType().equals(type)) {
-				instance.delegate = parser;
-				break;
-			}
-		}
+    // used by ProjectRepository
+    static DelegateParser instance()
+    {
+        if ( instance == null )
+            throw new IllegalStateException( "SigilParser is not instantiated." );
+        return instance;
+    }
 
-		if (instance.delegate == null) {
-			throw new IllegalArgumentException("Can't find parser delegateType=" + type);
-		}
-	}
 
-	/**
-	 * sets default file name the delegate parser accepts.
-	 * If not set, defaults to "ivy.xml".
-	 * @param name
-	 */
-	public void setDelegateFile(String name) {
-		instance.ivyFile = name;
-	}
+    public SigilParser()
+    {
+        if ( instance == null )
+        {
+            instance = new DelegateParser();
+        }
+    }
 
-	/**
-	 * sets the dependencies to keep from the delegate parser.
-	 * If not set, all existing dependencies are dropped.
-	 * @param regex pattern matching dependency names to keep.
-	 */
-	public void setKeepDependencies(String regex) {
-		instance.keepDependencyPattern = Pattern.compile(regex);
-	}
-	
-	/**
-	 * reduce level of info logging.
-	 * @param quiet
-	 */
-	public void setQuiet(String quiet) {
-		instance.quiet = Boolean.parseBoolean(quiet);
-	}
 
-	/**
-	 * sets the SigilResolver we use.
-	 * If not set, we use the first SigilResolver we find.
-	 * @param name
-	 */
-	public void setResolver(String name) {
-		instance.resolverName = name;
-	}
+    /**
+     * In IvyDE, IvyContext is not available, so we can't find the SigilResolver.
+     * This allows us to construct one.
+     * @deprecated temporary to support IvyDE
+     */
+    public void setConfig( String config )
+    {
+        instance.config = config;
+    }
 
-	/**
-	 * adds override element: <override name="X" pattern="Y" replace="Z"/>. Overrides
-	 * Ivy variables using a pattern substitution on the resource directory path.
-	 * 
-	 * @deprecated
-	 * This is only needed when a delegate parser expects Ant variables to be set
-	 * during the ivy:buildlist task (or the ProjectRepository initialisation),
-	 * which they are not. The delegate parser should really be fixed, as otherwise
-	 * the ivy:buildlist task won't work without this workaround.
-	 */
-	// e.g. <override name="ant.project.name" pattern=".*/([^/]+)/([^/]+)$" replace="$1-$2"/>
-	public void addConfiguredOverride(Map<String, String> var) {
-		final String name = var.get("name");
-		final String regex = var.get("pattern");
-		final String replace = var.get("replace");
 
-		if (name == null || regex == null || replace == null)
-			throw new IllegalArgumentException("override must contain name, pattern and replace attributes.");
+    /**
+     * sets delegate parser.
+     * If not set, we delegate to the default Ivy parser.
+     * @param type name returned by desired parser's getType() method.
+     */
+    public void setDelegateType( String type )
+    {
+        for ( ModuleDescriptorParser parser : ModuleDescriptorParserRegistry.getInstance().getParsers() )
+        {
+            if ( parser.getType().equals( type ) )
+            {
+                instance.delegate = parser;
+                break;
+            }
+        }
 
-		instance.varRegex.put(name, Pattern.compile(regex));
-		instance.varReplace.put(name, replace);
-	}
+        if ( instance.delegate == null )
+        {
+            throw new IllegalArgumentException( "Can't find parser delegateType=" + type );
+        }
+    }
 
-	// implement ModuleDescriptorParser interface by delegation to singleton instance.
 
-	public boolean accept(Resource res) {
-		return instance.accept(res);
-	}
+    /**
+     * sets default file name the delegate parser accepts.
+     * If not set, defaults to "ivy.xml".
+     * @param name
+     */
+    public void setDelegateFile( String name )
+    {
+        instance.ivyFile = name;
+    }
 
-	public Artifact getMetadataArtifact(ModuleRevisionId mrid, Resource res) {
-		return instance.getMetadataArtifact(mrid, res);
-	}
 
-	public String getType() {
-		return instance.getType();
-	}
+    /**
+     * sets the dependencies to keep from the delegate parser.
+     * If not set, all existing dependencies are dropped.
+     * @param regex pattern matching dependency names to keep.
+     */
+    public void setKeepDependencies( String regex )
+    {
+        instance.keepDependencyPattern = Pattern.compile( regex );
+    }
 
-	public ModuleDescriptor parseDescriptor(ParserSettings settings, URL xmlURL, boolean validate)
-			throws ParseException, IOException {
-		return instance.parseDescriptor(settings, xmlURL, validate);
-	}
 
-	public ModuleDescriptor parseDescriptor(ParserSettings settings, URL xmlURL, Resource res, boolean validate)
-			throws ParseException, IOException {
-		return instance.parseDescriptor(settings, xmlURL, res, validate);
-	}
+    /**
+     * reduce level of info logging.
+     * @param quiet
+     */
+    public void setQuiet( String quiet )
+    {
+        instance.quiet = Boolean.parseBoolean( quiet );
+    }
 
-	public void toIvyFile(InputStream source, Resource res, File destFile, ModuleDescriptor md) throws ParseException,
-			IOException {
-		instance.toIvyFile(source, res, destFile, md);
-	}
 
-	/**
-	 * delegating parser.
-	 * (optionally) removes original dependencies and augments with sigil-determined dependencies.
-	 */
-	static class DelegateParser extends XmlModuleDescriptorParser {
+    /**
+     * sets the SigilResolver we use.
+     * If not set, we use the first SigilResolver we find.
+     * @param name
+     */
+    public void setResolver( String name )
+    {
+        instance.resolverName = name;
+    }
 
-		private static final String SIGIL_BUILDLIST = IBldProject.PROJECT_FILE;
-		private static final String KEEP_ALL = ".*";
-		
-		private IBldResolver resolver;
-		private ParserSettings defaultSettings;
-		private Map<String, DefaultModuleDescriptor> rawCache = new HashMap<String, DefaultModuleDescriptor>();
-		private Map<String, DefaultModuleDescriptor> augmentedCache = new HashMap<String, DefaultModuleDescriptor>();
 
-		private HashMap<String, String> varReplace = new HashMap<String, String>();
-		private HashMap<String, Pattern> varRegex = new HashMap<String, Pattern>();
+    /**
+     * adds override element: <override name="X" pattern="Y" replace="Z"/>. Overrides
+     * Ivy variables using a pattern substitution on the resource directory path.
+     * 
+     * @deprecated
+     * This is only needed when a delegate parser expects Ant variables to be set
+     * during the ivy:buildlist task (or the ProjectRepository initialisation),
+     * which they are not. The delegate parser should really be fixed, as otherwise
+     * the ivy:buildlist task won't work without this workaround.
+     */
+    // e.g. <override name="ant.project.name" pattern=".*/([^/]+)/([^/]+)$" replace="$1-$2"/>
+    public void addConfiguredOverride( Map<String, String> var )
+    {
+        final String name = var.get( "name" );
+        final String regex = var.get( "pattern" );
+        final String replace = var.get( "replace" );
 
-		private ModuleDescriptorParser delegate;
-		private String ivyFile = "ivy.xml";
-		private String resolverName;
-		private Pattern keepDependencyPattern;
-    	private boolean quiet;
-    	private String config;
+        if ( name == null || regex == null || replace == null )
+            throw new IllegalArgumentException( "override must contain name, pattern and replace attributes." );
 
-		@Override
-		public boolean accept(Resource res) {
-			boolean accept = (res instanceof SigilResolver.SigilIvy)
-					|| res.getName().endsWith("/" + SIGIL_BUILDLIST)
-					|| ((instance.getSigilURI(res) != null) &&
-						((instance.delegate != null ? instance.delegate.accept(res) : false) || super.accept(res)));
-			if (accept)
-    			Log.verbose("accepted: " + res);
-			return accept;
-		}
+        instance.varRegex.put( name, Pattern.compile( regex ) );
+        instance.varReplace.put( name, replace );
+    }
 
-		@Override
-		public void toIvyFile(InputStream source, Resource res, File destFile, ModuleDescriptor md)
-				throws ParseException, IOException {
-			Log.verbose("writing resource: " + res + " toIvyFile: " + destFile);
-			// source allows us to keep layout and comments,
-			// but this doesn't work if source is not ivy.xml.
-			// So just write file directly from descriptor.
-			try {
-				XmlModuleDescriptorWriter.write(md, destFile);
-			} finally {
-				if (source != null)
-					source.close();
-			}
-		}
-		
-		@Override
-		public ModuleDescriptor parseDescriptor(ParserSettings settings, URL xmlURL, boolean validate)
-				throws ParseException, IOException {
-			return parseDescriptor(settings, xmlURL, new URLResource(xmlURL), validate);
-		}
 
-		@Override
-		public ModuleDescriptor parseDescriptor(ParserSettings settings, URL xmlURL, Resource res, boolean validate)
-				throws ParseException, IOException {
-			String cacheKey = xmlURL.toString() + settings.hashCode();
-			DefaultModuleDescriptor dmd = augmentedCache.get(cacheKey);
+    // implement ModuleDescriptorParser interface by delegation to singleton instance.
 
-			if (dmd == null) {
-				dmd = rawCache.get(cacheKey);
-				if (dmd == null) {
-					dmd = delegateParse(settings, xmlURL, res, validate);
-    			}
+    public boolean accept( Resource res )
+    {
+        return instance.accept( res );
+    }
 
-				if (!quiet)
-    				Log.info("augmenting module=" + dmd.getModuleRevisionId().getName() +
-						" ant.project.name=" + settings.substitute("${ant.project.name}"));
-				
-				addDependenciesToDescriptor(res, dmd);
-				augmentedCache.put(cacheKey, dmd);
-				
-				Log.verbose("augmented dependencies: " + Arrays.asList(dmd.getDependencies()));
-			}
 
-			return dmd;
-		}
-		
-		// used by ProjectRepository
-		ModuleDescriptor parseDescriptor(URL projectURL) throws ParseException, IOException {
-			if (defaultSettings == null) {
-				Ivy ivy = IvyContext.getContext().peekIvy();
-				if (ivy == null)
-					throw new IllegalStateException("can't get default settings - no ivy context.");
-				defaultSettings = ivy.getSettings();
-			}
-			
-			URL ivyURL = new URL(projectURL, ivyFile);
-			String cacheKey = ivyURL.toString() + defaultSettings.hashCode();
-			DefaultModuleDescriptor dmd = rawCache.get(cacheKey);
-			
-			if (dmd == null) {
-				URLResource res = new URLResource(ivyURL);
-				// Note: this doesn't contain the augmented dependencies, which is OK,
-				// since the ProjectRepository only needs the id and status.
-				dmd = delegateParse(defaultSettings, ivyURL, res, false);
-				rawCache.put(cacheKey, dmd);
-			}
+    public Artifact getMetadataArtifact( ModuleRevisionId mrid, Resource res )
+    {
+        return instance.getMetadataArtifact( mrid, res );
+    }
 
-			return dmd;
-		}
+
+    public String getType()
+    {
+        return instance.getType();
+    }
+
+
+    public ModuleDescriptor parseDescriptor( ParserSettings settings, URL xmlURL, boolean validate )
+        throws ParseException, IOException
+    {
+        return instance.parseDescriptor( settings, xmlURL, validate );
+    }
+
+
+    public ModuleDescriptor parseDescriptor( ParserSettings settings, URL xmlURL, Resource res, boolean validate )
+        throws ParseException, IOException
+    {
+        return instance.parseDescriptor( settings, xmlURL, res, validate );
+    }
+
+
+    public void toIvyFile( InputStream source, Resource res, File destFile, ModuleDescriptor md )
+        throws ParseException, IOException
+    {
+        instance.toIvyFile( source, res, destFile, md );
+    }
+
+    /**
+     * delegating parser.
+     * (optionally) removes original dependencies and augments with sigil-determined dependencies.
+     */
+    static class DelegateParser extends XmlModuleDescriptorParser
+    {
+
+        private static final String SIGIL_BUILDLIST = IBldProject.PROJECT_FILE;
+        private static final String KEEP_ALL = ".*";
+
+        private IBldResolver resolver;
+        private ParserSettings defaultSettings;
+        private Map<String, DefaultModuleDescriptor> rawCache = new HashMap<String, DefaultModuleDescriptor>();
+        private Map<String, DefaultModuleDescriptor> augmentedCache = new HashMap<String, DefaultModuleDescriptor>();
+
+        private HashMap<String, String> varReplace = new HashMap<String, String>();
+        private HashMap<String, Pattern> varRegex = new HashMap<String, Pattern>();
+
+        private ModuleDescriptorParser delegate;
+        private String ivyFile = "ivy.xml";
+        private String resolverName;
+        private Pattern keepDependencyPattern;
+        private boolean quiet;
+        private String config;
+
+
+        @Override
+        public boolean accept( Resource res )
+        {
+            boolean accept = ( res instanceof SigilResolver.SigilIvy )
+                || res.getName().endsWith( "/" + SIGIL_BUILDLIST )
+                || ( ( instance.getSigilURI( res ) != null ) && ( ( instance.delegate != null ? instance.delegate
+                    .accept( res ) : false ) || super.accept( res ) ) );
+            if ( accept )
+                Log.verbose( "accepted: " + res );
+            return accept;
+        }
+
+
+        @Override
+        public void toIvyFile( InputStream source, Resource res, File destFile, ModuleDescriptor md )
+            throws ParseException, IOException
+        {
+            Log.verbose( "writing resource: " + res + " toIvyFile: " + destFile );
+            // source allows us to keep layout and comments,
+            // but this doesn't work if source is not ivy.xml.
+            // So just write file directly from descriptor.
+            try
+            {
+                XmlModuleDescriptorWriter.write( md, destFile );
+            }
+            finally
+            {
+                if ( source != null )
+                    source.close();
+            }
+        }
+
+
+        @Override
+        public ModuleDescriptor parseDescriptor( ParserSettings settings, URL xmlURL, boolean validate )
+            throws ParseException, IOException
+        {
+            return parseDescriptor( settings, xmlURL, new URLResource( xmlURL ), validate );
+        }
+
+
+        @Override
+        public ModuleDescriptor parseDescriptor( ParserSettings settings, URL xmlURL, Resource res, boolean validate )
+            throws ParseException, IOException
+        {
+            String cacheKey = xmlURL.toString() + settings.hashCode();
+            DefaultModuleDescriptor dmd = augmentedCache.get( cacheKey );
+
+            if ( dmd == null )
+            {
+                dmd = rawCache.get( cacheKey );
+                if ( dmd == null )
+                {
+                    dmd = delegateParse( settings, xmlURL, res, validate );
+                }
+
+                if ( !quiet )
+                    Log.info( "augmenting module=" + dmd.getModuleRevisionId().getName() + " ant.project.name="
+                        + settings.substitute( "${ant.project.name}" ) );
+
+                addDependenciesToDescriptor( res, dmd );
+                augmentedCache.put( cacheKey, dmd );
+
+                Log.verbose( "augmented dependencies: " + Arrays.asList( dmd.getDependencies() ) );
+            }
+
+            return dmd;
+        }
+
+
+        // used by ProjectRepository
+        ModuleDescriptor parseDescriptor( URL projectURL ) throws ParseException, IOException
+        {
+            if ( defaultSettings == null )
+            {
+                Ivy ivy = IvyContext.getContext().peekIvy();
+                if ( ivy == null )
+                    throw new IllegalStateException( "can't get default settings - no ivy context." );
+                defaultSettings = ivy.getSettings();
+            }
+
+            URL ivyURL = new URL( projectURL, ivyFile );
+            String cacheKey = ivyURL.toString() + defaultSettings.hashCode();
+            DefaultModuleDescriptor dmd = rawCache.get( cacheKey );
+
+            if ( dmd == null )
+            {
+                URLResource res = new URLResource( ivyURL );
+                // Note: this doesn't contain the augmented dependencies, which is OK,
+                // since the ProjectRepository only needs the id and status.
+                dmd = delegateParse( defaultSettings, ivyURL, res, false );
+                rawCache.put( cacheKey, dmd );
+            }
+
+            return dmd;
+        }
+
+
+        private DefaultModuleDescriptor delegateParse( ParserSettings settings, URL xmlURL, Resource res,
+            boolean validate ) throws ParseException, IOException
+        {
+            String resName = res.getName();
+
+            if ( resName.endsWith( "/" + SIGIL_BUILDLIST ) )
+            {
+                String name = resName.substring( 0, resName.length() - SIGIL_BUILDLIST.length() );
+                res = res.clone( name + ivyFile );
+                xmlURL = new URL( xmlURL, ivyFile );
+            }
+
+            if ( settings instanceof IvySettings )
+            {
+                IvySettings ivySettings = ( IvySettings ) settings;
+                String dir = new File( res.getName() ).getParent();
+
+                for ( String name : varRegex.keySet() )
+                {
+                    Pattern regex = varRegex.get( name );
+                    String replace = varReplace.get( name );
+
+                    String value = regex.matcher( dir ).replaceAll( replace );
+
+                    Log.debug( "overriding variable " + name + "=" + value );
+                    ivySettings.setVariable( name, value );
+                }
+            }
+
+            ModuleDescriptor md = null;
+            if ( delegate == null || !delegate.accept( res ) )
+            {
+                md = super.parseDescriptor( settings, xmlURL, res, validate );
+            }
+            else
+            {
+                md = delegate.parseDescriptor( settings, xmlURL, res, validate );
+            }
 
-		private DefaultModuleDescriptor delegateParse(ParserSettings settings, URL xmlURL, Resource res,
-				boolean validate) throws ParseException, IOException {
-			String resName = res.getName();
+            return mungeDescriptor( md, res );
+        }
 
-			if (resName.endsWith("/" + SIGIL_BUILDLIST)) {
-				String name = resName.substring(0, resName.length() - SIGIL_BUILDLIST.length());
-				res = res.clone(name + ivyFile);
-				xmlURL = new URL(xmlURL, ivyFile);
-			}
 
-			if (settings instanceof IvySettings) {
-				IvySettings ivySettings = (IvySettings) settings;
-				String dir = new File(res.getName()).getParent();
+        /**
+         * clones descriptor and removes dependencies, as descriptor MUST have
+         * 'this' as the parser given to its constructor.
+         * Only dependency names matched by keepDependencyPattern are kept,
+         * as we're going to add our own dependencies later.
+         */
+        private DefaultModuleDescriptor mungeDescriptor( ModuleDescriptor md, Resource res )
+        {
 
-				for (String name : varRegex.keySet()) {
-					Pattern regex = varRegex.get(name);
-					String replace = varReplace.get(name);
+            if ( ( md instanceof DefaultModuleDescriptor ) && ( md.getParser() == this )
+                && ( KEEP_ALL.equals( keepDependencyPattern ) ) )
+            {
+                return ( DefaultModuleDescriptor ) md;
+            }
 
-					String value = regex.matcher(dir).replaceAll(replace);
+            DefaultModuleDescriptor dmd = new DefaultModuleDescriptor( this, res );
 
-					Log.debug("overriding variable " + name + "=" + value);
-					ivySettings.setVariable(name, value);
-				}
-			}
+            dmd.setModuleRevisionId( md.getModuleRevisionId() );
+            dmd.setPublicationDate( md.getPublicationDate() );
 
-			ModuleDescriptor md = null;
-			if (delegate == null || !delegate.accept(res)) {
-				md = super.parseDescriptor(settings, xmlURL, res, validate);
-			} else {
-				md = delegate.parseDescriptor(settings, xmlURL, res, validate);
-			}
+            for ( Configuration c : md.getConfigurations() )
+            {
+                String conf = c.getName();
 
-			return mungeDescriptor(md, res);
-		}
+                dmd.addConfiguration( c );
 
-		/**
-		 * clones descriptor and removes dependencies, as descriptor MUST have
-		 * 'this' as the parser given to its constructor.
-		 * Only dependency names matched by keepDependencyPattern are kept,
-		 * as we're going to add our own dependencies later.
-		 */
-		private DefaultModuleDescriptor mungeDescriptor(ModuleDescriptor md, Resource res) {
+                for ( Artifact a : md.getArtifacts( conf ) )
+                {
+                    dmd.addArtifact( conf, a );
+                }
+            }
 
-			if ((md instanceof DefaultModuleDescriptor) &&
-					(md.getParser() == this) &&
-					(KEEP_ALL.equals(keepDependencyPattern))) {
-				return (DefaultModuleDescriptor) md;
-			}
-				
-			DefaultModuleDescriptor dmd = new DefaultModuleDescriptor(this, res);
+            if ( keepDependencyPattern != null )
+            {
+                for ( DependencyDescriptor dependency : md.getDependencies() )
+                {
+                    String name = dependency.getDependencyId().getName();
+                    if ( keepDependencyPattern.matcher( name ).matches() )
+                    {
+                        dmd.addDependency( dependency );
+                    }
+                }
+            }
 
-			dmd.setModuleRevisionId(md.getModuleRevisionId());
-			dmd.setPublicationDate(md.getPublicationDate());
+            return dmd;
+        }
 
-			for (Configuration c : md.getConfigurations()) {
-				String conf = c.getName();
 
-				dmd.addConfiguration(c);
+        /*
+         * find URI to Sigil project file. This assumes that it is in the same
+         * directory as the ivy file.
+         */
+        private URI getSigilURI( Resource res )
+        {
+            URI uri = null;
 
-				for (Artifact a : md.getArtifacts(conf)) {
-					dmd.addArtifact(conf, a);
-				}
-			}
+            if ( res instanceof URLResource )
+            {
+                URL url = ( ( URLResource ) res ).getURL();
+                uri = URI.create( url.toString() ).resolve( IBldProject.PROJECT_FILE );
+                try
+                {
+                    InputStream stream = uri.toURL().openStream(); // check file
+                    // exists
+                    stream.close();
+                }
+                catch ( IOException e )
+                {
+                    uri = null;
+                }
+            }
+            else if ( res instanceof FileResource )
+            {
+                uri = ( ( FileResource ) res ).getFile().toURI().resolve( IBldProject.PROJECT_FILE );
+                if ( !( new File( uri ).exists() ) )
+                    uri = null;
+            }
 
-			if (keepDependencyPattern != null) {
-    			for (DependencyDescriptor dependency : md.getDependencies()) {
-    				String name = dependency.getDependencyId().getName();
-    				if (keepDependencyPattern.matcher(name).matches()) {
-    					dmd.addDependency(dependency);
-    				}
-    			}
-			}
+            return uri;
+        }
 
-			return dmd;
-		}
 
-		/*
-		 * find URI to Sigil project file. This assumes that it is in the same
-		 * directory as the ivy file.
-		 */
-		private URI getSigilURI(Resource res) {
-			URI uri = null;
+        /*
+         * add sigil dependencies to ModuleDescriptor.
+         */
+        private void addDependenciesToDescriptor( Resource res, DefaultModuleDescriptor md ) throws IOException
+        {
+            // FIXME: transitive should be configurable
+            final boolean transitive = true; // ivy default is true
+            final boolean changing = false;
+            final boolean force = false;
 
-			if (res instanceof URLResource) {
-				URL url = ((URLResource) res).getURL();
-				uri = URI.create(url.toString()).resolve(IBldProject.PROJECT_FILE);
-				try {
-					InputStream stream = uri.toURL().openStream(); // check file
-																	// exists
-					stream.close();
-				} catch (IOException e) {
-					uri = null;
-				}
-			} else if (res instanceof FileResource) {
-				uri = ((FileResource) res).getFile().toURI().resolve(IBldProject.PROJECT_FILE);
-				if (!(new File(uri).exists()))
-					uri = null;
-			}
+            URI uri = getSigilURI( res );
+            if ( uri == null )
+                return;
 
-			return uri;
-		}
+            IBldProject project;
 
-		/*
-		 * add sigil dependencies to ModuleDescriptor.
-		 */
-		private void addDependenciesToDescriptor(Resource res, DefaultModuleDescriptor md) throws IOException {
-			// FIXME: transitive should be configurable
-			final boolean transitive = true; // ivy default is true
-			final boolean changing = false;
-			final boolean force = false;
+            project = BldFactory.getProject( uri );
 
-			URI uri = getSigilURI(res);
-			if (uri == null)
-				return;
+            IBundleModelElement requirements = project.getDependencies();
+            Log.verbose( "requirements: " + Arrays.asList( requirements.children() ) );
 
-			IBldProject project;
+            // preserve version range for Require-Bundle
+            // XXX: synthesise bundle version range corresponding to package version ranges?
+            HashMap<String, VersionRange> versions = new HashMap<String, VersionRange>();
+            for ( IModelElement child : requirements.children() )
+            {
+                if ( child instanceof IRequiredBundle )
+                {
+                    IRequiredBundle bundle = ( IRequiredBundle ) child;
+                    versions.put( bundle.getSymbolicName(), bundle.getVersions() );
+                }
+            }
 
-			project = BldFactory.getProject(uri);
+            IBldResolver resolver = findResolver();
+            if ( resolver == null )
+            {
+                // this can happen in IvyDE, but it retries and is OK next time.
+                Log.warn( "failed to find resolver - IvyContext not yet available." );
+                return;
+            }
 
-			IBundleModelElement requirements = project.getDependencies();
-			Log.verbose("requirements: " + Arrays.asList(requirements.children()));
+            IResolution resolution = resolver.resolve( requirements, false );
+            Log.verbose( "resolution: " + resolution.getBundles() );
 
-			// preserve version range for Require-Bundle
-			// XXX: synthesise bundle version range corresponding to package version ranges?
-			HashMap<String, VersionRange> versions = new HashMap<String, VersionRange>();
-			for (IModelElement child : requirements.children()) {
-				if (child instanceof IRequiredBundle) {
-					IRequiredBundle bundle = (IRequiredBundle) child;
-					versions.put(bundle.getSymbolicName(), bundle.getVersions());
-				}
-			}
+            ModuleRevisionId masterMrid = md.getModuleRevisionId();
+            DefaultDependencyDescriptor dd;
+            ModuleRevisionId mrid;
 
-			IBldResolver resolver = findResolver();
-			if (resolver == null) {
-				// this can happen in IvyDE, but it retries and is OK next time.
-				Log.warn("failed to find resolver - IvyContext not yet available.");
-				return;
-			}
-			
-			IResolution resolution = resolver.resolve(requirements, false);
-			Log.verbose("resolution: " + resolution.getBundles());
+            for ( ISigilBundle bundle : resolution.getBundles() )
+            {
+                IBundleModelElement info = bundle.getBundleInfo();
+                String name = info.getSymbolicName();
 
-			ModuleRevisionId masterMrid = md.getModuleRevisionId();
-			DefaultDependencyDescriptor dd;
-			ModuleRevisionId mrid;
+                if ( name == null )
+                {
+                    // e.g. SystemProvider with framework=null
+                    continue;
+                }
 
-			for (ISigilBundle bundle : resolution.getBundles()) {
-				IBundleModelElement info = bundle.getBundleInfo();
-				String name = info.getSymbolicName();
+                if ( bundle instanceof ProjectRepository.ProjectBundle )
+                {
+                    ProjectRepository.ProjectBundle pb = ( ProjectRepository.ProjectBundle ) bundle;
+                    String org = pb.getOrg();
+                    if ( org == null )
+                        org = masterMrid.getOrganisation();
+                    String id = pb.getId();
+                    String module = pb.getModule();
+                    String rev = pb.getRevision();
 
-				if (name == null) {
-					// e.g. SystemProvider with framework=null
-					continue;
-				}
+                    mrid = ModuleRevisionId.newInstance( org, module, rev );
+                    dd = new SigilDependencyDescriptor( md, mrid, force, changing, transitive );
 
-				if (bundle instanceof ProjectRepository.ProjectBundle) {
-					ProjectRepository.ProjectBundle pb = (ProjectRepository.ProjectBundle) bundle;
-					String org = pb.getOrg();
-					if (org == null)
-						org = masterMrid.getOrganisation();
-					String id = pb.getId();
-					String module = pb.getModule();
-					String rev = pb.getRevision();
+                    if ( !id.equals( module ) )
+                    { // non-default artifact
+                        dd.addDependencyArtifact( module, new DefaultDependencyArtifactDescriptor( dd, id, "jar",
+                            "jar", null, null ) );
+                    }
+                }
+                else
+                {
+                    VersionRange version = versions.get( name );
+                    String rev = version != null ? version.toString() : info.getVersion().toString();
+                    mrid = ModuleRevisionId.newInstance( SigilResolver.ORG_SIGIL, name, rev );
+                    dd = new SigilDependencyDescriptor( md, mrid, force, changing, transitive );
+                }
 
-					mrid = ModuleRevisionId.newInstance(org, module, rev);
-					dd = new SigilDependencyDescriptor(md, mrid, force, changing, transitive);
+                int nDeps = 0;
+                boolean foundDefault = false;
 
-					if (!id.equals(module)) { // non-default artifact
-						dd.addDependencyArtifact(module,
-								new DefaultDependencyArtifactDescriptor(dd, id, "jar", "jar", null, null));
-					}
-				} else {
-					VersionRange version = versions.get(name);
-					String rev = version != null ? version.toString() : info.getVersion().toString();
-					mrid = ModuleRevisionId.newInstance(SigilResolver.ORG_SIGIL, name, rev);
-					dd = new SigilDependencyDescriptor(md, mrid, force, changing, transitive);
-				}
+                // TODO: make dependency configurations configurable SIGIL-176
+                for ( String conf : md.getConfigurationsNames() )
+                {
+                    if ( conf.equals( "default" ) )
+                    {
+                        foundDefault = true;
+                    }
+                    else if ( md.getArtifacts( conf ).length == 0 )
+                    {
+                        dd.addDependencyConfiguration( conf, conf + "(default)" );
+                        nDeps++;
+                    }
+                }
 
-				int nDeps = 0;
-				boolean foundDefault = false;
+                if ( nDeps > 0 )
+                {
+                    if ( foundDefault )
+                        dd.addDependencyConfiguration( "default", "default" );
+                }
+                else
+                {
+                    dd.addDependencyConfiguration( "*", "*" ); // all configurations
+                }
 
-				// TODO: make dependency configurations configurable SIGIL-176
-				for (String conf : md.getConfigurationsNames()) {
-					if (conf.equals("default")) {
-						foundDefault = true;
-					} else if (md.getArtifacts(conf).length == 0) {
-						dd.addDependencyConfiguration(conf, conf + "(default)");
-						nDeps++;
-					}
-				}
+                md.addDependency( dd );
+            }
 
-				if (nDeps > 0) {
-					if (foundDefault)
-						dd.addDependencyConfiguration("default", "default");
-				} else {
-					dd.addDependencyConfiguration("*", "*");    // all configurations
-				}
+            boolean resolved = true;
+            for ( IModelElement child : requirements.children() )
+            {
+                ISigilBundle provider = resolution.getProvider( child );
+                if ( provider == null )
+                {
+                    resolved = false;
+                    // this is parse phase, so only log verbose message.
+                    // error is produced during resolution phase.
+                    Log.verbose( "WARN: can't resolve: " + child );
 
-				md.addDependency(dd);
-			}
+                    String name;
+                    String version;
+                    if ( child instanceof IRequiredBundle )
+                    {
+                        IRequiredBundle rb = ( IRequiredBundle ) child;
+                        name = rb.getSymbolicName();
+                        version = rb.getVersions().toString();
+                    }
+                    else
+                    {
+                        IPackageImport pi = ( IPackageImport ) child;
+                        name = "import!" + pi.getPackageName();
+                        version = pi.getVersions().toString();
+                    }
 
-			boolean resolved = true;
-			for (IModelElement child : requirements.children()) {
-				ISigilBundle provider = resolution.getProvider(child);
-				if (provider == null) {
-					resolved = false;
-					// this is parse phase, so only log verbose message.
-					// error is produced during resolution phase.
-					Log.verbose("WARN: can't resolve: " + child);
+                    mrid = ModuleRevisionId.newInstance( "!" + SigilResolver.ORG_SIGIL, name, version );
+                    dd = new SigilDependencyDescriptor( md, mrid, force, changing, transitive );
+                    dd.addDependencyConfiguration( "*", "*" ); // all
+                    // configurations
+                    md.addDependency( dd );
+                }
+            }
 
-					String name;
-					String version;
-					if (child instanceof IRequiredBundle) {
-						IRequiredBundle rb = (IRequiredBundle) child;
-						name = rb.getSymbolicName();
-						version = rb.getVersions().toString();
-					} else {
-						IPackageImport pi = (IPackageImport) child;
-						name = "import!" + pi.getPackageName();
-						version = pi.getVersions().toString();
-					}
+            if ( !resolved )
+            {
+                // Ivy does not show warnings or errors logged from parse phase, until after resolution.
+                // but <buildlist> ant task doesn't do resolution, so errors would be silently ignored.
+                // Hence, we must use Message.info to ensure this failure is seen.
+                if ( !quiet )
+                    Log.info( "WARN: resolution failed in: " + masterMrid.getName() + ". Use -v for details." );
+            }
+        }
 
-					mrid = ModuleRevisionId.newInstance("!" + SigilResolver.ORG_SIGIL, name, version);
-					dd = new SigilDependencyDescriptor(md, mrid, force, changing, transitive);
-					dd.addDependencyConfiguration("*", "*"); // all
-					// configurations
-					md.addDependency(dd);
-				}
-			}
 
-			if (!resolved) {
-				// Ivy does not show warnings or errors logged from parse phase, until after resolution.
-				// but <buildlist> ant task doesn't do resolution, so errors would be silently ignored.
-				// Hence, we must use Message.info to ensure this failure is seen.
-				if (!quiet)
-    				Log.info("WARN: resolution failed in: " + masterMrid.getName() + ". Use -v for details.");
-			}
-		}
+        /*
+         * find named resolver, or first resolver that implements IBldResolver.
+         */
+        private IBldResolver findResolver()
+        {
+            if ( resolver == null )
+            {
+                Ivy ivy = IvyContext.getContext().peekIvy();
+                if ( ivy != null )
+                {
+                    if ( resolverName != null )
+                    {
+                        DependencyResolver r = ivy.getSettings().getResolver( resolverName );
+                        if ( r == null )
+                        {
+                            throw new Error( "SigilParser: resolver \"" + resolverName + "\" not defined." );
+                        }
+                        else if ( r instanceof IBldResolver )
+                        {
+                            resolver = ( IBldResolver ) r;
+                        }
+                        else
+                        {
+                            throw new Error( "SigilParser: resolver \"" + resolverName + "\" is not a SigilResolver." );
+                        }
+                    }
+                    else
+                    {
+                        for ( Object r : ivy.getSettings().getResolvers() )
+                        {
+                            if ( r instanceof IBldResolver )
+                            {
+                                resolver = ( IBldResolver ) r;
+                                break;
+                            }
+                        }
+                    }
 
-		/*
-		 * find named resolver, or first resolver that implements IBldResolver.
-		 */
-		private IBldResolver findResolver() {
-			if (resolver == null) {
-				Ivy ivy = IvyContext.getContext().peekIvy();
-				if (ivy != null) {
-    				if (resolverName != null) {
-    					DependencyResolver r = ivy.getSettings().getResolver(resolverName);
-    					if (r == null) {
-    						throw new Error("SigilParser: resolver \"" + resolverName + "\" not defined.");
-    					} else if (r instanceof IBldResolver) {
-    						resolver = (IBldResolver) r;
-    					} else {
-    						throw new Error("SigilParser: resolver \"" + resolverName + "\" is not a SigilResolver.");
-    					}
-    				} else {
-    					for (Object r : ivy.getSettings().getResolvers()) {
-    						if (r instanceof IBldResolver) {
-    							resolver = (IBldResolver) r;
-    							break;
-    						}
-    					}
-    				}
-    
-    				if (resolver == null) {
-    					throw new Error("SigilParser: can't find SigilResolver. Check ivysettings.xml.");
-    				}
-				} else if (config != null) {
-					Log.warn("creating duplicate resolver to support IvyDE.");
-					resolver = new SigilResolver();
-					((SigilResolver)resolver).setConfig(config);
-				}
-			}
-			return resolver;
-		}
-	}
+                    if ( resolver == null )
+                    {
+                        throw new Error( "SigilParser: can't find SigilResolver. Check ivysettings.xml." );
+                    }
+                }
+                else if ( config != null )
+                {
+                    Log.warn( "creating duplicate resolver to support IvyDE." );
+                    resolver = new SigilResolver();
+                    ( ( SigilResolver ) resolver ).setConfig( config );
+                }
+            }
+            return resolver;
+        }
+    }
 
 }
 
@@ -579,9 +698,11 @@
  * this is only needed so that we can distinguish sigil-added dependencies from
  * existing ones.
  */
-class SigilDependencyDescriptor extends DefaultDependencyDescriptor {
-	public SigilDependencyDescriptor(DefaultModuleDescriptor md, ModuleRevisionId mrid, boolean force,
-			boolean changing, boolean transitive) {
-		super(md, mrid, force, changing, transitive);
-	}
+class SigilDependencyDescriptor extends DefaultDependencyDescriptor
+{
+    public SigilDependencyDescriptor( DefaultModuleDescriptor md, ModuleRevisionId mrid, boolean force,
+        boolean changing, boolean transitive )
+    {
+        super( md, mrid, force, changing, transitive );
+    }
 }
diff --git a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/SigilResolver.java b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/SigilResolver.java
index f934d98..f41a3aa 100644
--- a/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/SigilResolver.java
+++ b/sigil/ivy/resolver/src/org/apache/felix/sigil/ivy/SigilResolver.java
@@ -19,6 +19,7 @@
 
 package org.apache.felix.sigil.ivy;
 
+
 import static java.lang.String.format;
 
 import java.io.File;
@@ -54,359 +55,464 @@
 import org.apache.ivy.plugins.resolver.util.ResolvedResource;
 import org.apache.ivy.util.FileUtil;
 
+
 /**
  * This resolver is able to work with Sigil repositories.
  * It does not allow publishing.
  */
-public class SigilResolver extends BasicResolver implements IBldResolver {
-	/** the sigil-injected dependency organisation name */
-	static final String ORG_SIGIL = "sigil";
-	
-	private IBldResolver resolver;
-	private String config;
-	private boolean extractBCP = false;
-	private Map<String, Resource> resourcesCache = new HashMap<String, Resource>();
-	
-	/**
-	 * no-args constructor required by Ivy.
-	 * 
-	 * XXX: It doesn't currently seem to matter that Ivy instantiates this many times,
-	 * since SigilParser caches it, and the ProjectRepositoryProvider static cache
-	 * prevents it being re-loaded unnecessarily.
-	 * 
-	 * If this should become a problem, then we will need to delegate to a singleton instance,
-	 * as we have done in SigilParser.
-	 */
-	public SigilResolver() {
-	}
-	
-	public void setConfig(String config) {
-		this.config = config;
-	}
-	
-	/**
-	 * if true, resolver extracts any jars embedded in Bundle-ClassPath.
-	 */
-	public void setExtractBCP(String extract) {
-		this.extractBCP = Boolean.parseBoolean(extract);
-	}
+public class SigilResolver extends BasicResolver implements IBldResolver
+{
+    /** the sigil-injected dependency organisation name */
+    static final String ORG_SIGIL = "sigil";
 
-	private IBldResolver getResolver() {
-		if (resolver == null) {
-			if (config == null) {
-				throw new Error("SigilResolver: not configured. Specify config=\"PATH\" in ivysettings.xml.");
-			}
-			try {
-				URI uri;
-				File file = new File(config);
-				
-				if (file.isAbsolute()) {
-					uri = file.toURI();
-				} else {
-    				URI cwd = new File(".").toURI();
-    				uri = cwd.resolve(config);
-				}
-				
-				Map<String, Properties> repositories = BldFactory.getConfig(uri).getRepositoryConfig();
-				resolver = new BldResolver(repositories);
-			} catch (IOException e) {
-				throw new Error("SigilResolver: failed to configure: " + e);
-			}
-		}
-		return resolver;
-	}
-
-	public IResolution resolveOrFail(IModelElement element, boolean transitive) throws ResolutionException {
-		return getResolver().resolveOrFail(element, transitive);
-	}
-
-	public IResolution resolve(IModelElement element, boolean transitive) {
-		return getResolver().resolve(element, transitive);
-	}
-
-	public String getTypeName() {
-		return "sigil";
-	}
-
-	/*
-	 * synthesize an ivy descriptor for a Sigil dependency. called after Sigil
-	 * resolution, so descriptor already contains resolved version.
-	 */
-	public ResolvedResource findIvyFileRef(DependencyDescriptor dd, ResolveData data) {
-		ResolvedResource ref = null;
-
-		ModuleRevisionId id = dd.getDependencyRevisionId();
-
-		if (!id.getOrganisation().equals(ORG_SIGIL)) {
-			return null;
-		}
-
-		ISigilBundle bundle = resolve(id);
-		if (bundle == null) {
-			Log.error( "Failed to find bundle for module " + id );
-			return null;
-		}
-
-		String symbolicName = id.getName();
-		String version = bundle.getVersion().toString();
-
-		Resource res = new SigilIvy(extractBCP ? bundle : null, symbolicName, version);
-		ref = new ResolvedResource(res, version);
-
-		Log.debug(format("findIvyFileRef: dd=%s => ref=%s", dd, ref));
-		return ref;
-	}
-
-	@Override
-	protected ResolvedResource findArtifactRef(Artifact artifact, Date date) {
-		String name = artifact.getName();
-		ModuleRevisionId id = artifact.getModuleRevisionId();
-
-		if (!id.getOrganisation().equals(ORG_SIGIL)) {
-			return null;
-		}
-		
-		ISigilBundle bundle = resolve(id);
-		if (bundle == null) {
-			return null;
-		}
-
-		IBundleModelElement info = bundle.getBundleInfo();
-		URI uri = info.getUpdateLocation();
-		Resource res = null;
-
-		try {
-			URL url =  (uri != null) ? uri.toURL() : bundle.getLocation().toFile().toURL();
-    		if (name.contains("!")) {
-    			String[] split = name.split("!");
-    			url = new URL("jar:" + url + "!/" + split[1] + "." + artifact.getExt());
-    		}
-			res = new URLResource(url);
-		} catch (MalformedURLException e) {
-			System.out.println("Oops! " + e);
-		}
-
-		String version = bundle.getVersion().toString();
-		ResolvedResource ref = new ResolvedResource(res, version);
-
-		Log.debug(format("findArtifactRef: artifact=%s, date=%s => ref=%s", artifact, date, ref));
-		return ref;
-	}
-
-	private ISigilBundle resolve(ModuleRevisionId id) {
-		String revision = id.getRevision();
-		String range = revision;
-
-		if (revision.indexOf(',') < 0) {
-			// SigilParser has already resolved the revision from the import
-			// version range.
-			// We now need to locate the same bundle to get its download URL.
-			// We must use an OSGi version range to specify the exact version,
-			// otherwise it will resolve to "specified version or above".
-			range = "[" + revision + "," + revision + "]";
-		}
-
-		RequiredBundle bundle = new RequiredBundle();
-		bundle.setSymbolicName(id.getName());
-		bundle.setVersions(VersionRange.parseVersionRange(range));
-
-		Log.verbose("searching for " + bundle);
-		
-		try {
-			IResolution resolution = resolveOrFail(bundle, false);
-			ISigilBundle[] bundles = resolution.getBundles().toArray(new ISigilBundle[0]);
-			if (bundles.length == 1) {
-				return bundles[0];
-			}
-		} catch (ResolutionException e) {
-			Log.warn( e.getMessage() );
-			return null;
-		}
-		return null;
-	}
-
-	/*
-	 * Implement BasicResolver abstract methods
-	 */
-
-	@Override
-	protected long get(Resource res, File dest) throws IOException {
-		FileUtil.copy(res.openStream(), dest, null);
-		long len = res.getContentLength();
-		Log.debug(format("get(%s, %s) = %d", res, dest, len));
-		return len;
-	}
+    private IBldResolver resolver;
+    private String config;
+    private boolean extractBCP = false;
+    private Map<String, Resource> resourcesCache = new HashMap<String, Resource>();
 
 
-	@Override
-	public Resource getResource(String source) throws IOException {
-		source = encode(source);
-		Resource res = resourcesCache.get(source);
-		if (res == null) {
-			res = new URLResource(new URL(source));
-			resourcesCache.put(source, res);
-		}
-		Log.debug(format("SIGIL: getResource(%s) = %d", source, res));
-		return res;
-	}
+    /**
+     * no-args constructor required by Ivy.
+     * 
+     * XXX: It doesn't currently seem to matter that Ivy instantiates this many times,
+     * since SigilParser caches it, and the ProjectRepositoryProvider static cache
+     * prevents it being re-loaded unnecessarily.
+     * 
+     * If this should become a problem, then we will need to delegate to a singleton instance,
+     * as we have done in SigilParser.
+     */
+    public SigilResolver()
+    {
+    }
 
-	private static String encode(String source) {
-		return source.trim().replaceAll(" ", "%20");
-	}
 
-	@SuppressWarnings("unchecked")
-	@Override
-	protected Collection findNames(Map tokenValues, String token) {
-		throw new Error("SigilResolver: findNames not supported.");
-	}
+    public void setConfig( String config )
+    {
+        this.config = config;
+    }
 
-	public void publish(Artifact artifact, File src, boolean overwrite) throws IOException {
-		throw new Error("SigilResolver: publish not supported.");
-	}
 
-	public void beginPublishTransaction(ModuleRevisionId module, boolean overwrite) throws IOException {
-		// stop publish attempts being silently ignored.
-		throw new Error("SigilResolver: publish not supported.");
-	}
+    /**
+     * if true, resolver extracts any jars embedded in Bundle-ClassPath.
+     */
+    public void setExtractBCP( String extract )
+    {
+        this.extractBCP = Boolean.parseBoolean( extract );
+    }
 
-	/*
-	 * Synthesize a virtual ivy file for a Sigil dependency.
-	 */
-	static class SigilIvy implements Resource {
-		private StringBuilder content = new StringBuilder();
-		private String name;
-		private boolean exists = true;
 
-		private SigilIvy() {
-		}
+    private IBldResolver getResolver()
+    {
+        if ( resolver == null )
+        {
+            if ( config == null )
+            {
+                throw new Error( "SigilResolver: not configured. Specify config=\"PATH\" in ivysettings.xml." );
+            }
+            try
+            {
+                URI uri;
+                File file = new File( config );
 
-		public SigilIvy(ISigilBundle bundle, String module, String rev) {
-			this.name = "sigil!" + module + "#" + rev;
+                if ( file.isAbsolute() )
+                {
+                    uri = file.toURI();
+                }
+                else
+                {
+                    URI cwd = new File( "." ).toURI();
+                    uri = cwd.resolve( config );
+                }
 
-			String org = ORG_SIGIL;
-			// FIXME: make status and pub configurable
-			String status = "release";
-			String pub = "20080912162859";
+                Map<String, Properties> repositories = BldFactory.getConfig( uri ).getRepositoryConfig();
+                resolver = new BldResolver( repositories );
+            }
+            catch ( IOException e )
+            {
+                throw new Error( "SigilResolver: failed to configure: " + e );
+            }
+        }
+        return resolver;
+    }
 
-			content.append("<ivy-module version=\"1.0\">\n");
 
-			content.append(format(
-					"<info organisation=\"%s\" module=\"%s\" revision=\"%s\" status=\"%s\" publication=\"%s\"/>\n",
-					org, module, rev, status, pub));
-			
-			String bcp = readBundleClassPath(bundle);
-			if (bcp != null) {
-    			content.append("<publications>\n");
-    			for (String j : bcp.split(",\\s*")) {
-    				if (j.equals(".")) {
-            			content.append("<artifact/>\n");
-        			} else if (j.endsWith(".jar") && bundleContains(bundle, j)) {
-        				j = j.substring(0, j.length() - 4);
-            			content.append(format("<artifact name=\"%s!%s\"/>\n", module, j));
-        			}
-    			}
-    			content.append("</publications>\n");
-			}
+    public IResolution resolveOrFail( IModelElement element, boolean transitive ) throws ResolutionException
+    {
+        return getResolver().resolveOrFail( element, transitive );
+    }
 
-			// TODO: add dependencies?
-			// <dependencies>
-			// <dependency org="org.apache" name="log4j" rev="1.2.12"
-			// revConstraint="[1.2,1.3)"/>
-			// </dependencies>
 
-			content.append("</ivy-module>\n");
-		}
-		
-        private boolean bundleContains(ISigilBundle bundle, String j) {
-        	URI uri = bundle.getBundleInfo().getUpdateLocation();
-            InputStream is = null;
-			try {
-    			URL url =  (uri != null) ? uri.toURL() : bundle.getLocation().toFile().toURL();
-				is = url.openStream();
-            	JarInputStream js = new JarInputStream(is, false);
-            	JarEntry entry;
-            	while ( (entry = js.getNextJarEntry()) != null ) {
-            		if ( j.equals( entry.getName() ) ) {
-            			return true;
-            		}
-            	}
-			} catch (IOException e) {
-			} finally {
-				if (is != null) {
-					try {
-						is.close();
-					} catch (IOException e2) {
-					}
-				}
-			}
-        	return false;
-		}
+    public IResolution resolve( IModelElement element, boolean transitive )
+    {
+        return getResolver().resolve( element, transitive );
+    }
 
-		private String readBundleClassPath(ISigilBundle bundle) {
-        	if (bundle == null)
-        		return null;
-        	
-        	URI uri = bundle.getBundleInfo().getUpdateLocation();
-            InputStream is = null;
-			try {
-    			URL url =  (uri != null) ? uri.toURL() : bundle.getLocation().toFile().toURL();
-				is = url.openStream();
-            	JarInputStream js = new JarInputStream(is, false);
-                Manifest m = js.getManifest();
-                if (m != null)
-                    return (String) m.getMainAttributes().getValue("Bundle-ClassPath");
-			} catch (IOException e) {
-			} finally {
-				if (is != null) {
-					try {
-						is.close();
-					} catch (IOException e2) {
-					}
-				}
-			}
-			
+
+    public String getTypeName()
+    {
+        return "sigil";
+    }
+
+
+    /*
+     * synthesize an ivy descriptor for a Sigil dependency. called after Sigil
+     * resolution, so descriptor already contains resolved version.
+     */
+    public ResolvedResource findIvyFileRef( DependencyDescriptor dd, ResolveData data )
+    {
+        ResolvedResource ref = null;
+
+        ModuleRevisionId id = dd.getDependencyRevisionId();
+
+        if ( !id.getOrganisation().equals( ORG_SIGIL ) )
+        {
             return null;
         }
 
-		public String toString() {
-			return "SigilIvy[" + name + "]";
-		}
+        ISigilBundle bundle = resolve( id );
+        if ( bundle == null )
+        {
+            Log.error( "Failed to find bundle for module " + id );
+            return null;
+        }
 
-		// clone is used to read checksum files
-		// so clone(getName() + ".sha1").exists() should be false
-		public Resource clone(String cloneName) {
-			Log.debug("SigilIvy: clone: " + cloneName);
-			SigilIvy clone = new SigilIvy();
-			clone.name = cloneName;
-			clone.exists = false;
-			return clone;
-		}
+        String symbolicName = id.getName();
+        String version = bundle.getVersion().toString();
 
-		public boolean exists() {
-			return exists;
-		}
+        Resource res = new SigilIvy( extractBCP ? bundle : null, symbolicName, version );
+        ref = new ResolvedResource( res, version );
 
-		public long getContentLength() {
-			return content.length();
-		}
+        Log.debug( format( "findIvyFileRef: dd=%s => ref=%s", dd, ref ) );
+        return ref;
+    }
 
-		public long getLastModified() {
-			// TODO Auto-generated method stub
-			Log.debug("NOT IMPLEMENTED: getLastModified");
-			return 0;
-		}
 
-		public String getName() {
-			return name;
-		}
+    @Override
+    protected ResolvedResource findArtifactRef( Artifact artifact, Date date )
+    {
+        String name = artifact.getName();
+        ModuleRevisionId id = artifact.getModuleRevisionId();
 
-		public boolean isLocal() {
-			return false;
-		}
+        if ( !id.getOrganisation().equals( ORG_SIGIL ) )
+        {
+            return null;
+        }
 
-		@SuppressWarnings("deprecation")
-		public InputStream openStream() throws IOException {
-			return new java.io.StringBufferInputStream(content.toString());
-		}
-	}
+        ISigilBundle bundle = resolve( id );
+        if ( bundle == null )
+        {
+            return null;
+        }
+
+        IBundleModelElement info = bundle.getBundleInfo();
+        URI uri = info.getUpdateLocation();
+        Resource res = null;
+
+        try
+        {
+            URL url = ( uri != null ) ? uri.toURL() : bundle.getLocation().toFile().toURL();
+            if ( name.contains( "!" ) )
+            {
+                String[] split = name.split( "!" );
+                url = new URL( "jar:" + url + "!/" + split[1] + "." + artifact.getExt() );
+            }
+            res = new URLResource( url );
+        }
+        catch ( MalformedURLException e )
+        {
+            System.out.println( "Oops! " + e );
+        }
+
+        String version = bundle.getVersion().toString();
+        ResolvedResource ref = new ResolvedResource( res, version );
+
+        Log.debug( format( "findArtifactRef: artifact=%s, date=%s => ref=%s", artifact, date, ref ) );
+        return ref;
+    }
+
+
+    private ISigilBundle resolve( ModuleRevisionId id )
+    {
+        String revision = id.getRevision();
+        String range = revision;
+
+        if ( revision.indexOf( ',' ) < 0 )
+        {
+            // SigilParser has already resolved the revision from the import
+            // version range.
+            // We now need to locate the same bundle to get its download URL.
+            // We must use an OSGi version range to specify the exact version,
+            // otherwise it will resolve to "specified version or above".
+            range = "[" + revision + "," + revision + "]";
+        }
+
+        RequiredBundle bundle = new RequiredBundle();
+        bundle.setSymbolicName( id.getName() );
+        bundle.setVersions( VersionRange.parseVersionRange( range ) );
+
+        Log.verbose( "searching for " + bundle );
+
+        try
+        {
+            IResolution resolution = resolveOrFail( bundle, false );
+            ISigilBundle[] bundles = resolution.getBundles().toArray( new ISigilBundle[0] );
+            if ( bundles.length == 1 )
+            {
+                return bundles[0];
+            }
+        }
+        catch ( ResolutionException e )
+        {
+            Log.warn( e.getMessage() );
+            return null;
+        }
+        return null;
+    }
+
+
+    /*
+     * Implement BasicResolver abstract methods
+     */
+
+    @Override
+    protected long get( Resource res, File dest ) throws IOException
+    {
+        FileUtil.copy( res.openStream(), dest, null );
+        long len = res.getContentLength();
+        Log.debug( format( "get(%s, %s) = %d", res, dest, len ) );
+        return len;
+    }
+
+
+    @Override
+    public Resource getResource( String source ) throws IOException
+    {
+        source = encode( source );
+        Resource res = resourcesCache.get( source );
+        if ( res == null )
+        {
+            res = new URLResource( new URL( source ) );
+            resourcesCache.put( source, res );
+        }
+        Log.debug( format( "SIGIL: getResource(%s) = %d", source, res ) );
+        return res;
+    }
+
+
+    private static String encode( String source )
+    {
+        return source.trim().replaceAll( " ", "%20" );
+    }
+
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected Collection findNames( Map tokenValues, String token )
+    {
+        throw new Error( "SigilResolver: findNames not supported." );
+    }
+
+
+    public void publish( Artifact artifact, File src, boolean overwrite ) throws IOException
+    {
+        throw new Error( "SigilResolver: publish not supported." );
+    }
+
+
+    public void beginPublishTransaction( ModuleRevisionId module, boolean overwrite ) throws IOException
+    {
+        // stop publish attempts being silently ignored.
+        throw new Error( "SigilResolver: publish not supported." );
+    }
+
+    /*
+     * Synthesize a virtual ivy file for a Sigil dependency.
+     */
+    static class SigilIvy implements Resource
+    {
+        private StringBuilder content = new StringBuilder();
+        private String name;
+        private boolean exists = true;
+
+
+        private SigilIvy()
+        {
+        }
+
+
+        public SigilIvy( ISigilBundle bundle, String module, String rev )
+        {
+            this.name = "sigil!" + module + "#" + rev;
+
+            String org = ORG_SIGIL;
+            // FIXME: make status and pub configurable
+            String status = "release";
+            String pub = "20080912162859";
+
+            content.append( "<ivy-module version=\"1.0\">\n" );
+
+            content.append( format(
+                "<info organisation=\"%s\" module=\"%s\" revision=\"%s\" status=\"%s\" publication=\"%s\"/>\n", org,
+                module, rev, status, pub ) );
+
+            String bcp = readBundleClassPath( bundle );
+            if ( bcp != null )
+            {
+                content.append( "<publications>\n" );
+                for ( String j : bcp.split( ",\\s*" ) )
+                {
+                    if ( j.equals( "." ) )
+                    {
+                        content.append( "<artifact/>\n" );
+                    }
+                    else if ( j.endsWith( ".jar" ) && bundleContains( bundle, j ) )
+                    {
+                        j = j.substring( 0, j.length() - 4 );
+                        content.append( format( "<artifact name=\"%s!%s\"/>\n", module, j ) );
+                    }
+                }
+                content.append( "</publications>\n" );
+            }
+
+            // TODO: add dependencies?
+            // <dependencies>
+            // <dependency org="org.apache" name="log4j" rev="1.2.12"
+            // revConstraint="[1.2,1.3)"/>
+            // </dependencies>
+
+            content.append( "</ivy-module>\n" );
+        }
+
+
+        private boolean bundleContains( ISigilBundle bundle, String j )
+        {
+            URI uri = bundle.getBundleInfo().getUpdateLocation();
+            InputStream is = null;
+            try
+            {
+                URL url = ( uri != null ) ? uri.toURL() : bundle.getLocation().toFile().toURL();
+                is = url.openStream();
+                JarInputStream js = new JarInputStream( is, false );
+                JarEntry entry;
+                while ( ( entry = js.getNextJarEntry() ) != null )
+                {
+                    if ( j.equals( entry.getName() ) )
+                    {
+                        return true;
+                    }
+                }
+            }
+            catch ( IOException e )
+            {
+            }
+            finally
+            {
+                if ( is != null )
+                {
+                    try
+                    {
+                        is.close();
+                    }
+                    catch ( IOException e2 )
+                    {
+                    }
+                }
+            }
+            return false;
+        }
+
+
+        private String readBundleClassPath( ISigilBundle bundle )
+        {
+            if ( bundle == null )
+                return null;
+
+            URI uri = bundle.getBundleInfo().getUpdateLocation();
+            InputStream is = null;
+            try
+            {
+                URL url = ( uri != null ) ? uri.toURL() : bundle.getLocation().toFile().toURL();
+                is = url.openStream();
+                JarInputStream js = new JarInputStream( is, false );
+                Manifest m = js.getManifest();
+                if ( m != null )
+                    return ( String ) m.getMainAttributes().getValue( "Bundle-ClassPath" );
+            }
+            catch ( IOException e )
+            {
+            }
+            finally
+            {
+                if ( is != null )
+                {
+                    try
+                    {
+                        is.close();
+                    }
+                    catch ( IOException e2 )
+                    {
+                    }
+                }
+            }
+
+            return null;
+        }
+
+
+        public String toString()
+        {
+            return "SigilIvy[" + name + "]";
+        }
+
+
+        // clone is used to read checksum files
+        // so clone(getName() + ".sha1").exists() should be false
+        public Resource clone( String cloneName )
+        {
+            Log.debug( "SigilIvy: clone: " + cloneName );
+            SigilIvy clone = new SigilIvy();
+            clone.name = cloneName;
+            clone.exists = false;
+            return clone;
+        }
+
+
+        public boolean exists()
+        {
+            return exists;
+        }
+
+
+        public long getContentLength()
+        {
+            return content.length();
+        }
+
+
+        public long getLastModified()
+        {
+            // TODO Auto-generated method stub
+            Log.debug( "NOT IMPLEMENTED: getLastModified" );
+            return 0;
+        }
+
+
+        public String getName()
+        {
+            return name;
+        }
+
+
+        public boolean isLocal()
+        {
+            return false;
+        }
+
+
+        @SuppressWarnings("deprecation")
+        public InputStream openStream() throws IOException
+        {
+            return new java.io.StringBufferInputStream( content.toString() );
+        }
+    }
 }
diff --git a/sigil/sigil-builder/src/org/apache/felix/sigil/build/Feature.java b/sigil/sigil-builder/src/org/apache/felix/sigil/build/Feature.java
index 66fc79e..bc4e28a 100644
--- a/sigil/sigil-builder/src/org/apache/felix/sigil/build/Feature.java
+++ b/sigil/sigil-builder/src/org/apache/felix/sigil/build/Feature.java
@@ -21,7 +21,9 @@
  */
 package org.apache.felix.sigil.build;
 
-class Feature {
-	String id, version, url;
-	String[] categories;
+
+class Feature
+{
+    String id, version, url;
+    String[] categories;
 }
diff --git a/sigil/sigil-builder/src/org/apache/felix/sigil/build/FindBundlesTask.java b/sigil/sigil-builder/src/org/apache/felix/sigil/build/FindBundlesTask.java
index 059f3e9..e52f37e 100644
--- a/sigil/sigil-builder/src/org/apache/felix/sigil/build/FindBundlesTask.java
+++ b/sigil/sigil-builder/src/org/apache/felix/sigil/build/FindBundlesTask.java
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.sigil.build;
 
+
 import java.io.File;
 import java.io.FilenameFilter;
 
@@ -25,77 +26,98 @@
 import org.apache.tools.ant.Task;
 import org.osgi.framework.Version;
 
-public class FindBundlesTask extends Task {
 
-	private File dir;
-	private String symbolicName;
-	private String property;
+public class FindBundlesTask extends Task
+{
 
-	public File getDir() {
-		return dir;
-	}
+    private File dir;
+    private String symbolicName;
+    private String property;
 
-	public void setDir(File dir) {
-		this.dir = dir;
-	}
 
-	public String getSymbolicName() {
-		return symbolicName;
-	}
+    public File getDir()
+    {
+        return dir;
+    }
 
-	public void setSymbolicName(String symbolicName) {
-		this.symbolicName = symbolicName;
-	}
 
-	public String getProperty() {
-		return property;
-	}
+    public void setDir( File dir )
+    {
+        this.dir = dir;
+    }
 
-	public void setProperty(String property) {
-		this.property = property;
-	}
 
-	@Override
-	public void execute() throws BuildException {
-		System.out.println("Searching " + dir + " for bundle '" + symbolicName + "'");
-		final String prefix = symbolicName + "_";
-		String[] files = dir.list(new FilenameFilter() {
-			public boolean accept(File dir, String name) {
-				return name.startsWith(prefix);
-			}
-		});
-		if (files == null)
-		    files = new String[0];
+    public String getSymbolicName()
+    {
+        return symbolicName;
+    }
 
-		System.out.println("Found " + files.length + " file(s) starting with " + symbolicName);
 
-		Version highest = null;
-		for (String filename : files) {
-			System.out.println("Testing " + filename);
-			// Drop the prefix
-			int startIndex = prefix.length();
+    public void setSymbolicName( String symbolicName )
+    {
+        this.symbolicName = symbolicName;
+    }
 
-			// Drop the ".jar" suffix if present
-			int endIndex = filename.length();
-			if (filename.toLowerCase().endsWith(".jar")) {
-				endIndex -= 4;
-			}
 
-			String versionString = filename.substring(startIndex, endIndex);
-			System.out.println("Version string is '" + versionString + "'");
+    public String getProperty()
+    {
+        return property;
+    }
 
-			Version version = new Version(versionString);
-			if (highest == null || version.compareTo(highest) > 0) {
-				highest = version;
-			}
-		}
 
-		if (highest == null) {
-			throw new BuildException("No matches for symbolic name '"
-					+ symbolicName + "'");
-		}
+    public void setProperty( String property )
+    {
+        this.property = property;
+    }
 
-		getProject().setNewProperty(property, highest.toString());
-	}
+
+    @Override
+    public void execute() throws BuildException
+    {
+        System.out.println( "Searching " + dir + " for bundle '" + symbolicName + "'" );
+        final String prefix = symbolicName + "_";
+        String[] files = dir.list( new FilenameFilter()
+        {
+            public boolean accept( File dir, String name )
+            {
+                return name.startsWith( prefix );
+            }
+        } );
+        if ( files == null )
+            files = new String[0];
+
+        System.out.println( "Found " + files.length + " file(s) starting with " + symbolicName );
+
+        Version highest = null;
+        for ( String filename : files )
+        {
+            System.out.println( "Testing " + filename );
+            // Drop the prefix
+            int startIndex = prefix.length();
+
+            // Drop the ".jar" suffix if present
+            int endIndex = filename.length();
+            if ( filename.toLowerCase().endsWith( ".jar" ) )
+            {
+                endIndex -= 4;
+            }
+
+            String versionString = filename.substring( startIndex, endIndex );
+            System.out.println( "Version string is '" + versionString + "'" );
+
+            Version version = new Version( versionString );
+            if ( highest == null || version.compareTo( highest ) > 0 )
+            {
+                highest = version;
+            }
+        }
+
+        if ( highest == null )
+        {
+            throw new BuildException( "No matches for symbolic name '" + symbolicName + "'" );
+        }
+
+        getProject().setNewProperty( property, highest.toString() );
+    }
 
 }
diff --git a/sigil/sigil-builder/src/org/apache/felix/sigil/build/SiteInsertFeatureContentHandler.java b/sigil/sigil-builder/src/org/apache/felix/sigil/build/SiteInsertFeatureContentHandler.java
index 83e95cb..2f51f0a 100644
--- a/sigil/sigil-builder/src/org/apache/felix/sigil/build/SiteInsertFeatureContentHandler.java
+++ b/sigil/sigil-builder/src/org/apache/felix/sigil/build/SiteInsertFeatureContentHandler.java
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.sigil.build;
 
+
 import java.util.List;
 
 import org.xml.sax.Attributes;
@@ -26,79 +27,106 @@
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.AttributesImpl;
 
-class SiteInsertFeatureContentHandler implements ContentHandler {
-	
-	private final ContentHandler output;
-	private final List<org.apache.felix.sigil.build.Feature> featureList;
 
-	public SiteInsertFeatureContentHandler(ContentHandler output,
-			List<Feature> featureList) {
-		this.output = output;
-		this.featureList = featureList;
-	}
+class SiteInsertFeatureContentHandler implements ContentHandler
+{
 
-	public void characters(char[] ch, int start, int length) throws SAXException {
-		output.characters(ch, start, length);
-	}
+    private final ContentHandler output;
+    private final List<org.apache.felix.sigil.build.Feature> featureList;
 
-	public void endDocument() throws SAXException {
-		output.endDocument();
-	}
 
-	public void endElement(String uri, String localName, String name) throws SAXException {
-		output.endElement(uri, localName, name);
-	}
+    public SiteInsertFeatureContentHandler( ContentHandler output, List<Feature> featureList )
+    {
+        this.output = output;
+        this.featureList = featureList;
+    }
 
-	public void endPrefixMapping(String prefix) throws SAXException {
-		output.endPrefixMapping(prefix);
-	}
 
-	public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
-		//output.ignorableWhitespace(ch, start, length);
-	}
+    public void characters( char[] ch, int start, int length ) throws SAXException
+    {
+        output.characters( ch, start, length );
+    }
 
-	public void processingInstruction(String target, String data) throws SAXException {
-		output.processingInstruction(target, data);
-	}
 
-	public void setDocumentLocator(Locator locator) {
-		output.setDocumentLocator(locator);
-	}
+    public void endDocument() throws SAXException
+    {
+        output.endDocument();
+    }
 
-	public void skippedEntity(String name) throws SAXException {
-		output.skippedEntity(name);
-	}
 
-	public void startDocument() throws SAXException {
-		output.startDocument();
-	}
+    public void endElement( String uri, String localName, String name ) throws SAXException
+    {
+        output.endElement( uri, localName, name );
+    }
 
-	public void startElement(String uri, String localName, String name, Attributes atts)
-			throws SAXException {
-		output.startElement(uri, localName, name, atts);
-		
-		if("site".equals(name)) {
-			for (Feature feature : featureList) {
-				AttributesImpl featureAtts = new AttributesImpl();
-				featureAtts.addAttribute("", "", "url", "CDATA", feature.url);
-				featureAtts.addAttribute("", "", "id", "CDATA", feature.id);
-				featureAtts.addAttribute("", "", "version", "CDATA", feature.version);
-				output.startElement("", "", "feature", featureAtts);
-				
-				for (int i = 0; i < feature.categories.length; i++) {
-					AttributesImpl categoryAtts = new AttributesImpl();
-					categoryAtts.addAttribute("", "", "name", "CDATA", feature.categories[i]);
-					output.startElement("", "", "category", categoryAtts);
-					output.endElement("", "", "category");
-				}
-				
-				output.endElement("", "", "feature");
-			}
-		}
-	}
 
-	public void startPrefixMapping(String prefix, String uri) throws SAXException {
-		output.startPrefixMapping(prefix, uri);
-	}
+    public void endPrefixMapping( String prefix ) throws SAXException
+    {
+        output.endPrefixMapping( prefix );
+    }
+
+
+    public void ignorableWhitespace( char[] ch, int start, int length ) throws SAXException
+    {
+        //output.ignorableWhitespace(ch, start, length);
+    }
+
+
+    public void processingInstruction( String target, String data ) throws SAXException
+    {
+        output.processingInstruction( target, data );
+    }
+
+
+    public void setDocumentLocator( Locator locator )
+    {
+        output.setDocumentLocator( locator );
+    }
+
+
+    public void skippedEntity( String name ) throws SAXException
+    {
+        output.skippedEntity( name );
+    }
+
+
+    public void startDocument() throws SAXException
+    {
+        output.startDocument();
+    }
+
+
+    public void startElement( String uri, String localName, String name, Attributes atts ) throws SAXException
+    {
+        output.startElement( uri, localName, name, atts );
+
+        if ( "site".equals( name ) )
+        {
+            for ( Feature feature : featureList )
+            {
+                AttributesImpl featureAtts = new AttributesImpl();
+                featureAtts.addAttribute( "", "", "url", "CDATA", feature.url );
+                featureAtts.addAttribute( "", "", "id", "CDATA", feature.id );
+                featureAtts.addAttribute( "", "", "version", "CDATA", feature.version );
+                output.startElement( "", "", "feature", featureAtts );
+
+                for ( int i = 0; i < feature.categories.length; i++ )
+                {
+                    AttributesImpl categoryAtts = new AttributesImpl();
+                    categoryAtts.addAttribute( "", "", "name", "CDATA", feature.categories[i] );
+                    output.startElement( "", "", "category", categoryAtts );
+                    output.endElement( "", "", "category" );
+                }
+
+                output.endElement( "", "", "feature" );
+            }
+        }
+    }
+
+
+    public void startPrefixMapping( String prefix, String uri ) throws SAXException
+    {
+        output.startPrefixMapping( prefix, uri );
+    }
 
 }
diff --git a/sigil/sigil-builder/src/org/apache/felix/sigil/build/SiteInsertFeatures.java b/sigil/sigil-builder/src/org/apache/felix/sigil/build/SiteInsertFeatures.java
index 84f92e2..a6cc1ac 100644
--- a/sigil/sigil-builder/src/org/apache/felix/sigil/build/SiteInsertFeatures.java
+++ b/sigil/sigil-builder/src/org/apache/felix/sigil/build/SiteInsertFeatures.java
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.sigil.build;
 
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -42,138 +43,210 @@
 import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;
 
-public class SiteInsertFeatures extends Task {
 
-	private File siteXmlFile;
-	private String features;
-	private String versionPropPrefix;
-	private String categoryPropPrefix;
-	
-	public File getSiteXmlFile() {
-		return siteXmlFile;
-	}
-	public void setSiteXmlFile(File siteXmlFile) {
-		this.siteXmlFile = siteXmlFile;
-	}
-	public String getFeatures() {
-		return features;
-	}
-	public void setFeatures(String features) {
-		this.features = features;
-	}
-	public String getVersionPropPrefix() {
-		return versionPropPrefix;
-	}
-	public void setVersionPropPrefix(String versionPropPrefix) {
-		this.versionPropPrefix = versionPropPrefix;
-	}
-	public String getCategoryPropPrefix() {
-		return categoryPropPrefix;
-	}
-	public void setCategoryPropPrefix(String categoryPropPrefix) {
-		this.categoryPropPrefix = categoryPropPrefix;
-	}
-	
-	@Override
-	public void execute() throws BuildException {
-		Project project = getProject();
-		
-		List<Feature> featureList = new ArrayList<Feature>(); 
-		StringTokenizer tokenizer = new StringTokenizer(features, ",");
-		while(tokenizer.hasMoreTokens()) {
-			Feature feature = new Feature();
-			feature.id = tokenizer.nextToken().trim();
-			
-			// Find the version property
-			String versionProp;
-			if(versionPropPrefix == null) {
-				versionProp = feature.id;
-			} else {
-				versionProp = versionPropPrefix + "." + feature.id;
-			}
-			feature.version = project.getProperty(versionProp);
-			
-			// Find the categories for this feature
-			feature.categories = new String[0];
-			if(categoryPropPrefix != null) {
-				String categoriesStr = project.getProperty(categoryPropPrefix + "." + feature.id);
-				if(categoriesStr != null) {
-					StringTokenizer categoriesTokenizer = new StringTokenizer(categoriesStr, ",");
-					feature.categories = new String[categoriesTokenizer.countTokens()];
-					for(int i=0; i<feature.categories.length; i++) {
-						feature.categories[i] = categoriesTokenizer.nextToken();
-					}
-				}
-			}
+public class SiteInsertFeatures extends Task
+{
 
-			if(feature.version != null) {
-				feature.url = "features/" + feature.id + "_" + feature.version + ".jar";
-				featureList.add(feature);
-			} else {
-				System.out.println("Skipping feature " + feature.id);
-			}
-		}
-		
-		if(!siteXmlFile.isFile()) {
-			throw new BuildException(siteXmlFile + " does not exist or is not a normal file");
-		}
-		try {
-			// Generate new XML into a temporary file
-			File tempFile = File.createTempFile("tmp", ".xml", siteXmlFile.getParentFile());
-			tempFile.deleteOnExit();
+    private File siteXmlFile;
+    private String features;
+    private String versionPropPrefix;
+    private String categoryPropPrefix;
 
-			SAXTransformerFactory transformerFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
-			TransformerHandler transformerHandler = transformerFactory.newTransformerHandler();
-			transformerHandler.setResult(new StreamResult(tempFile));
-			
-			SAXParserFactory parserFactory = SAXParserFactory.newInstance();
-			SAXParser parser = parserFactory.newSAXParser();
-			
-			SiteInsertFeatureContentHandler contentHandler = new SiteInsertFeatureContentHandler(transformerHandler, featureList);
-			
-			XMLReader reader = parser.getXMLReader();
-			reader.setContentHandler(contentHandler);
-			reader.parse(new InputSource(new FileInputStream(siteXmlFile)));
-			
-			// Backup original file
-			File backup = new File(siteXmlFile.getParentFile(), siteXmlFile.getName() + ".bak");
-			copyFile(siteXmlFile, backup);
-			
-			// Replace original file
-			copyFile(tempFile, siteXmlFile);
-			
-		} catch (IOException e) {
-			throw new BuildException(e);
-		} catch (TransformerConfigurationException e) {
-			throw new BuildException(e);
-		} catch (IllegalArgumentException e) {
-			throw new BuildException(e);
-		} catch (TransformerFactoryConfigurationError e) {
-			throw new BuildException(e);
-		} catch (ParserConfigurationException e) {
-			throw new BuildException(e);
-		} catch (SAXException e) {
-			throw new BuildException(e);
-		}
-	}
-	
-	private void copyFile(File source, File dest) throws IOException {
-		FileInputStream in = null;
-		FileOutputStream out = null;
-		try {
-			in = new FileInputStream(source);
-			out = new FileOutputStream(dest);
-			
-			byte[] buffer = new byte[1024];
-			
-			int read;
-			while((read = in.read(buffer, 0, 1024)) > -1) {
-				out.write(buffer, 0, read);
-			}
-		} finally {
-			try { if(in != null) in.close(); } catch(IOException e) {}
-			try { if(out != null) out.close(); } catch(IOException e) {}
-		}
-		
-	}
+
+    public File getSiteXmlFile()
+    {
+        return siteXmlFile;
+    }
+
+
+    public void setSiteXmlFile( File siteXmlFile )
+    {
+        this.siteXmlFile = siteXmlFile;
+    }
+
+
+    public String getFeatures()
+    {
+        return features;
+    }
+
+
+    public void setFeatures( String features )
+    {
+        this.features = features;
+    }
+
+
+    public String getVersionPropPrefix()
+    {
+        return versionPropPrefix;
+    }
+
+
+    public void setVersionPropPrefix( String versionPropPrefix )
+    {
+        this.versionPropPrefix = versionPropPrefix;
+    }
+
+
+    public String getCategoryPropPrefix()
+    {
+        return categoryPropPrefix;
+    }
+
+
+    public void setCategoryPropPrefix( String categoryPropPrefix )
+    {
+        this.categoryPropPrefix = categoryPropPrefix;
+    }
+
+
+    @Override
+    public void execute() throws BuildException
+    {
+        Project project = getProject();
+
+        List<Feature> featureList = new ArrayList<Feature>();
+        StringTokenizer tokenizer = new StringTokenizer( features, "," );
+        while ( tokenizer.hasMoreTokens() )
+        {
+            Feature feature = new Feature();
+            feature.id = tokenizer.nextToken().trim();
+
+            // Find the version property
+            String versionProp;
+            if ( versionPropPrefix == null )
+            {
+                versionProp = feature.id;
+            }
+            else
+            {
+                versionProp = versionPropPrefix + "." + feature.id;
+            }
+            feature.version = project.getProperty( versionProp );
+
+            // Find the categories for this feature
+            feature.categories = new String[0];
+            if ( categoryPropPrefix != null )
+            {
+                String categoriesStr = project.getProperty( categoryPropPrefix + "." + feature.id );
+                if ( categoriesStr != null )
+                {
+                    StringTokenizer categoriesTokenizer = new StringTokenizer( categoriesStr, "," );
+                    feature.categories = new String[categoriesTokenizer.countTokens()];
+                    for ( int i = 0; i < feature.categories.length; i++ )
+                    {
+                        feature.categories[i] = categoriesTokenizer.nextToken();
+                    }
+                }
+            }
+
+            if ( feature.version != null )
+            {
+                feature.url = "features/" + feature.id + "_" + feature.version + ".jar";
+                featureList.add( feature );
+            }
+            else
+            {
+                System.out.println( "Skipping feature " + feature.id );
+            }
+        }
+
+        if ( !siteXmlFile.isFile() )
+        {
+            throw new BuildException( siteXmlFile + " does not exist or is not a normal file" );
+        }
+        try
+        {
+            // Generate new XML into a temporary file
+            File tempFile = File.createTempFile( "tmp", ".xml", siteXmlFile.getParentFile() );
+            tempFile.deleteOnExit();
+
+            SAXTransformerFactory transformerFactory = ( SAXTransformerFactory ) SAXTransformerFactory.newInstance();
+            TransformerHandler transformerHandler = transformerFactory.newTransformerHandler();
+            transformerHandler.setResult( new StreamResult( tempFile ) );
+
+            SAXParserFactory parserFactory = SAXParserFactory.newInstance();
+            SAXParser parser = parserFactory.newSAXParser();
+
+            SiteInsertFeatureContentHandler contentHandler = new SiteInsertFeatureContentHandler( transformerHandler,
+                featureList );
+
+            XMLReader reader = parser.getXMLReader();
+            reader.setContentHandler( contentHandler );
+            reader.parse( new InputSource( new FileInputStream( siteXmlFile ) ) );
+
+            // Backup original file
+            File backup = new File( siteXmlFile.getParentFile(), siteXmlFile.getName() + ".bak" );
+            copyFile( siteXmlFile, backup );
+
+            // Replace original file
+            copyFile( tempFile, siteXmlFile );
+
+        }
+        catch ( IOException e )
+        {
+            throw new BuildException( e );
+        }
+        catch ( TransformerConfigurationException e )
+        {
+            throw new BuildException( e );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            throw new BuildException( e );
+        }
+        catch ( TransformerFactoryConfigurationError e )
+        {
+            throw new BuildException( e );
+        }
+        catch ( ParserConfigurationException e )
+        {
+            throw new BuildException( e );
+        }
+        catch ( SAXException e )
+        {
+            throw new BuildException( e );
+        }
+    }
+
+
+    private void copyFile( File source, File dest ) throws IOException
+    {
+        FileInputStream in = null;
+        FileOutputStream out = null;
+        try
+        {
+            in = new FileInputStream( source );
+            out = new FileOutputStream( dest );
+
+            byte[] buffer = new byte[1024];
+
+            int read;
+            while ( ( read = in.read( buffer, 0, 1024 ) ) > -1 )
+            {
+                out.write( buffer, 0, read );
+            }
+        }
+        finally
+        {
+            try
+            {
+                if ( in != null )
+                    in.close();
+            }
+            catch ( IOException e )
+            {
+            }
+            try
+            {
+                if ( out != null )
+                    out.close();
+            }
+            catch ( IOException e )
+            {
+            }
+        }
+
+    }
 }