[felix-framework] 01/01: Imported Upstream version 4.4.0

Emmanuel Bourg ebourg-guest at moszumanska.debian.org
Wed Apr 9 17:50:30 UTC 2014


This is an automated email from the git hooks/post-receive script.

ebourg-guest pushed a commit to annotated tag upstream/4.4.0
in repository felix-framework.

commit 1ef17d10ce41afc4256026d8ed91b971f4c6639d
Author: Emmanuel Bourg <ebourg at apache.org>
Date:   Wed Apr 9 16:34:35 2014 +0200

    Imported Upstream version 4.4.0
---
 DEPENDENCIES                                       |    6 +-
 NOTICE                                             |    4 +-
 doc/changelog.txt                                  |  124 ++
 pom.xml                                            |   12 +-
 src/main/appended-resources/META-INF/DEPENDENCIES  |    6 +-
 src/main/appended-resources/META-INF/NOTICE        |    2 +-
 .../apache/felix/framework/BundleContextImpl.java  |    2 +-
 .../org/apache/felix/framework/BundleImpl.java     |  196 +-
 .../felix/framework/BundleProtectionDomain.java    |   19 +-
 .../framework/BundleRevisionDependencies.java      |   27 +-
 .../apache/felix/framework/BundleRevisionImpl.java |   39 +-
 .../apache/felix/framework/BundleWiringImpl.java   |  639 ++++---
 .../apache/felix/framework/ExtensionManager.java   |   68 +-
 .../java/org/apache/felix/framework/Felix.java     |  456 +++--
 .../org/apache/felix/framework/FilterImpl.java     |    4 +-
 .../felix/framework/FrameworkStartLevelImpl.java   |   45 +-
 .../felix/framework/FrameworkWiringImpl.java       |   16 +-
 .../apache/felix/framework/PackageAdminImpl.java   |    5 +-
 .../apache/felix/framework/ResolveContextImpl.java |  110 ++
 .../felix/framework/ServiceRegistrationImpl.java   |   43 +-
 .../apache/felix/framework/ServiceRegistry.java    |   68 +-
 .../apache/felix/framework/StatefulResolver.java   | 1334 +++++++------
 .../org/apache/felix/framework/URLHandlers.java    |  231 ++-
 .../framework/URLHandlersBundleStreamHandler.java  |    7 +-
 .../framework/URLHandlersContentHandlerProxy.java  |   22 +-
 .../framework/URLHandlersStreamHandlerProxy.java   |  162 +-
 .../org/apache/felix/framework/WovenClassImpl.java |   10 +-
 .../apache/felix/framework/cache/BundleCache.java  |    7 +-
 .../felix/framework/cache/DirectoryRevision.java   |    2 +-
 .../apache/felix/framework/cache/JarRevision.java  |    2 +-
 .../framework/capabilityset/CapabilitySet.java     |   75 +-
 .../framework/capabilityset/SimpleFilter.java      |   35 +-
 .../felix/framework/resolver/Candidates.java       |  220 ++-
 .../felix/framework/resolver/HostedCapability.java |  126 +-
 .../felix/framework/resolver/ResolveContext.java   |   52 +
 .../apache/felix/framework/resolver/Resolver.java  |   18 +-
 .../felix/framework/resolver/ResolverImpl.java     |  278 +--
 .../felix/framework/resolver/ShadowList.java       |  157 ++
 .../{Resolver.java => SimpleHostedCapability.java} |   57 +-
 ...ostedCapability.java => WrappedCapability.java} |   40 +-
 ...tedRequirement.java => WrappedRequirement.java} |    6 +-
 ...ostBundleRevision.java => WrappedRevision.java} |   41 +-
 .../felix/framework/util/EventDispatcher.java      |   27 +-
 .../felix/framework/util/FelixConstants.java       |    3 +-
 .../apache/felix/framework/util/ImmutableList.java |  146 ++
 .../apache/felix/framework/util/ImmutableMap.java  |  129 ++
 .../apache/felix/framework/util/SecureAction.java  |   52 +-
 .../org/apache/felix/framework/util/StringMap.java |  173 +-
 .../java/org/apache/felix/framework/util/Util.java |   44 +-
 .../util/manifestparser/ManifestParser.java        |  358 +++-
 .../framework/util/manifestparser/R4Library.java   |    4 +
 .../util/manifestparser/R4LibraryClause.java       |   34 +-
 .../framework/wiring/BundleCapabilityImpl.java     |   18 +-
 .../framework/wiring/BundleRequirementImpl.java    |   16 +-
 .../java/org/osgi/framework/AdaptPermission.java   |   68 +-
 .../java/org/osgi/framework/AdminPermission.java   |  364 ++--
 .../org/osgi/framework/AllServiceListener.java     |   55 +-
 src/main/java/org/osgi/framework/Bundle.java       |  149 +-
 .../java/org/osgi/framework/BundleActivator.java   |   55 +-
 .../java/org/osgi/framework/BundleContext.java     |   96 +-
 src/main/java/org/osgi/framework/BundleEvent.java  |   49 +-
 .../java/org/osgi/framework/BundleException.java   |   39 +-
 .../java/org/osgi/framework/BundleListener.java    |   24 +-
 .../java/org/osgi/framework/BundlePermission.java  |  139 +-
 .../org/osgi/framework/CapabilityPermission.java   |  100 +-
 src/main/java/org/osgi/framework/Configurable.java |    9 +-
 src/main/java/org/osgi/framework/Constants.java    |   61 +-
 src/main/java/org/osgi/framework/Filter.java       |   23 +-
 .../java/org/osgi/framework/FrameworkEvent.java    |   16 +-
 .../java/org/osgi/framework/FrameworkListener.java |   23 +-
 .../java/org/osgi/framework/FrameworkUtil.java     | 1976 +++++++++++++++++---
 .../org/osgi/framework/InvalidSyntaxException.java |   43 +-
 .../java/org/osgi/framework/PackagePermission.java |  183 +-
 src/main/java/org/osgi/framework/ServiceEvent.java |   65 +-
 .../java/org/osgi/framework/ServiceException.java  |   30 +-
 .../java/org/osgi/framework/ServiceFactory.java    |   13 +-
 .../java/org/osgi/framework/ServiceListener.java   |   42 +-
 .../java/org/osgi/framework/ServicePermission.java |  234 +--
 .../java/org/osgi/framework/ServiceReference.java  |  104 +-
 .../org/osgi/framework/ServiceRegistration.java    |   65 +-
 .../java/org/osgi/framework/SignerProperty.java    |   16 +-
 .../osgi/framework/SynchronousBundleListener.java  |   39 +-
 .../osgi/framework/UnfilteredServiceListener.java  |   73 +
 src/main/java/org/osgi/framework/Version.java      |  120 +-
 src/main/java/org/osgi/framework/VersionRange.java |  509 +++++
 .../osgi/framework/hooks/bundle/CollisionHook.java |   85 +
 .../org/osgi/framework/hooks/bundle/EventHook.java |   33 +-
 .../org/osgi/framework/hooks/bundle/FindHook.java  |   29 +-
 .../framework/hooks/resolver/ResolverHook.java     |  149 +-
 .../hooks/resolver/ResolverHookFactory.java        |  112 +-
 .../osgi/framework/hooks/service/EventHook.java    |   11 +-
 .../framework/hooks/service/EventListenerHook.java |    8 +-
 .../org/osgi/framework/hooks/service/FindHook.java |   26 +-
 .../osgi/framework/hooks/service/ListenerHook.java |   44 +-
 .../osgi/framework/hooks/weaving/WovenClass.java   |   18 +-
 .../java/org/osgi/framework/launch/Framework.java  |   61 +-
 .../osgi/framework/launch/FrameworkFactory.java    |   25 +-
 .../namespace/AbstractWiringNamespace.java         |   56 +
 .../osgi/framework/namespace/BundleNamespace.java  |  153 ++
 .../namespace/ExecutionEnvironmentNamespace.java   |   55 +
 .../osgi/framework/namespace/HostNamespace.java    |  174 ++
 .../framework/namespace/IdentityNamespace.java     |  162 ++
 .../osgi/framework/namespace/PackageNamespace.java |  112 ++
 .../framework/startlevel/FrameworkStartLevel.java  |    6 +-
 .../osgi/framework/wiring/BundleCapability.java    |   37 +-
 .../osgi/framework/wiring/BundleRequirement.java   |   63 +-
 .../org/osgi/framework/wiring/BundleRevision.java  |  129 +-
 .../org/osgi/framework/wiring/BundleRevisions.java |    5 +-
 .../java/org/osgi/framework/wiring/BundleWire.java |   48 +-
 .../org/osgi/framework/wiring/BundleWiring.java    |  226 ++-
 .../org/osgi/framework/wiring/FrameworkWiring.java |    8 +-
 src/main/java/org/osgi/resource/Capability.java    |   86 +
 src/main/java/org/osgi/resource/Namespace.java     |  154 ++
 src/main/java/org/osgi/resource/Requirement.java   |   90 +
 src/main/java/org/osgi/resource/Resource.java      |   82 +
 src/main/java/org/osgi/resource/Wire.java          |   87 +
 src/main/java/org/osgi/resource/Wiring.java        |  144 ++
 .../osgi/service/packageadmin/ExportedPackage.java |   10 +-
 .../org/osgi/service/startlevel/StartLevel.java    |    6 +-
 .../url/AbstractURLStreamHandlerService.java       |   46 +-
 .../java/org/osgi/service/url/URLConstants.java    |   12 +-
 .../osgi/service/url/URLStreamHandlerService.java  |   31 +-
 .../osgi/service/url/URLStreamHandlerSetter.java   |   22 +-
 .../org/osgi/util/tracker/AbstractTracked.java     |   57 +-
 .../java/org/osgi/util/tracker/BundleTracker.java  |  145 +-
 .../osgi/util/tracker/BundleTrackerCustomizer.java |   65 +-
 .../java/org/osgi/util/tracker/ServiceTracker.java |  338 ++--
 .../util/tracker/ServiceTrackerCustomizer.java     |   39 +-
 src/main/resources/default.properties              |  174 +-
 .../org/osgi/framework/hooks/bundle/packageinfo    |    2 +-
 .../org/osgi/framework/launch/packageinfo          |    2 +-
 .../{hooks/bundle => namespace}/packageinfo        |    0
 src/main/resources/org/osgi/framework/packageinfo  |    2 +-
 .../org/osgi/framework/wiring/packageinfo          |    2 +-
 .../hooks/bundle => resource}/packageinfo          |    0
 .../resources/org/osgi/util/tracker/packageinfo    |    2 +-
 .../apache/felix/framework/CollisionHookTest.java  |  297 +++
 .../framework/RequirementsCapabilitiesTest.java    |  267 +++
 .../felix/framework/ServiceRegistryTest.java       |   56 +-
 .../felix/framework/StartStopBundleTest.java       |  105 +-
 .../apache/felix/framework/URLHandlersTest.java    |  385 ++++
 .../framework/capabilityset/SimpleFilterTest.java  |    9 +
 .../felix/framework/util/EventDispatcherTest.java  |   16 +-
 .../util/manifestparser/ManifestParserTest.java    |   88 +
 144 files changed, 10930 insertions(+), 4285 deletions(-)

diff --git a/DEPENDENCIES b/DEPENDENCIES
index 911ea71..03546b3 100644
--- a/DEPENDENCIES
+++ b/DEPENDENCIES
@@ -9,7 +9,7 @@ Apache Felix Framework
 
 
 
-Copyright 2011 The Apache Software Foundation
+Copyright 2013 The Apache Software Foundation
 
 This software was developed at the Apache Software Foundation
 (http://www.apache.org) and may have dependencies on other
@@ -19,14 +19,14 @@ I. Included Third-Party Software
 
 This product includes software developed at
 The OSGi Alliance (http://www.osgi.org/).
-Copyright (c) OSGi Alliance (2000, 2009).
+Copyright (c) OSGi Alliance (2000, 2012).
 Licensed under the Apache License 2.0.
 
 II. Used Third-Party Software
 
 This product uses software developed at
 The OSGi Alliance (http://www.osgi.org/).
-Copyright (c) OSGi Alliance (2000, 2009).
+Copyright (c) OSGi Alliance (2000, 2012).
 Licensed under the Apache License 2.0.
 
 III. License Summary
diff --git a/NOTICE b/NOTICE
index fd89c60..61635c3 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,6 +1,6 @@
 
 Apache Felix Framework
-Copyright 2006-2011 The Apache Software Foundation
+Copyright 2006-2014 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
@@ -8,5 +8,5 @@ The Apache Software Foundation (http://www.apache.org/).
 
 This product includes software developed at
 The OSGi Alliance (http://www.osgi.org/).
-Copyright (c) OSGi Alliance (2000, 2009).
+Copyright (c) OSGi Alliance (2000, 2012).
 Licensed under the Apache License 2.0.
diff --git a/doc/changelog.txt b/doc/changelog.txt
index 79e58db..72f9425 100644
--- a/doc/changelog.txt
+++ b/doc/changelog.txt
@@ -1,3 +1,127 @@
+Changes from 4.2.1 to 4.4.0
+---------------------------
+** Bug
+    * [FELIX-1131] - ServiceReference.isAssignableTo fails when using a factory that can not see the exported class and the bundle exporting the service does not have a direct wire to this class
+    * [FELIX-3992] - Classloader access outside of a privileged block
+    * [FELIX-4190] - The framework should not hold any lock while calling ServiceFactory#unget
+    * [FELIX-4283] - actually throw exception if method not found
+    * [FELIX-4331] - [Core R5] Support BundleContext and Framework adaptations
+    * [FELIX-4353] - [Core R5] BundleWiringTests OSGi CT test failures
+    * [FELIX-4354] - [Core R5] ResolverHookTests OSGi CT test failures
+    * [FELIX-4355] - [Core R5] org.osgi.test.cases.framework.launch OSGi CT test failure
+    * [FELIX-4365] - Input stream not properly closed on org.apache.felix.framework.Felix.getFrameworkVersion
+    * [FELIX-4388] - Initial start level not considered when bundle.start() is called
+    * [FELIX-4462] - Classloader deadlock in Java6 between two bundles
+
+** Improvement
+    * [FELIX-4128] - [Core R5] Provide an OSGi R5 compliant framework implementation
+    * [FELIX-4284] - remove dead allocation
+
+** Task
+    * [FELIX-4080] - [Core R5] Add support for org.osgi.framework.UnfilteredServiceListener
+    * [FELIX-4082] - [Core R5] Update org.osgi.framework.bsnversion framework property
+    * [FELIX-4083] - [Core R5] Support for valueOf when evaluating a Filter
+    * [FELIX-4084] - [Core R5] Enhance Bundle.adapt() to provider AccessControlContext.
+    * [FELIX-4085] - [Core R5] Implement updates to the Bundle Hook Specification
+    * [FELIX-4324] - [Core R5] Implement osgi.identity namespace for fragments
+
+** Wish
+    * [FELIX-3868] - Adding osgi.identity namespace to bundles (resources)
+
+Changes from 4.2.0 to 4.2.1
+---------------------------
+** Bug
+    * [FELIX-3411] - The implementation of org.osgi.service.startlevel.StartLevel#setStartLevel(int) does not follow the spec
+    * [FELIX-3893] - Bundle in cache doesn't pass security check anymore.
+    * [FELIX-3907] - NullPointerException in BundleWiringImpl when m_disposed is true.
+    * [FELIX-3939] - IllegalArgumentException from ClassLoader.definePackage
+    * [FELIX-3950] - Permission check being done even when security manager is absent
+    * [FELIX-3957] - Error events can be thrown when refreshing fragment bundles
+
+** Improvement
+    * [FELIX-3961] - Add a fallback to the default java security policy if no security provider is present
+
+Changes from 4.0.3 to 4.2.0
+---------------------------
+** Bug
+    * [FELIX-2780] - Extension bundle implementation relies on urlhandlers  service to start extension bundles
+    * [FELIX-3160] - NPE in BundleRevisionImpl.close() when uninstalling a bundle
+    * [FELIX-3242] - Concurrent modification problem in StatefulResolver$ResolverStateImpl.getCandidates
+    * [FELIX-3273] - Possible exception when accessing headers
+    * [FELIX-3306] - Lazy activation of bundles is not always working as expected
+    * [FELIX-3343] - Installing an fragment bundle without Bundle-ManifestVersion: 2 causes NPE in resolver
+    * [FELIX-3348] - StartLevel thread may terminate on uncaught exception
+    * [FELIX-3353] - The implementation of org.osgi.service.packageadmin.PackageAdmin#getExportedPackages(Bundle), does not follow the spec.
+    * [FELIX-3367] - getClassloader permission
+    * [FELIX-3397] - NPE when trying to resolve invalid fragments
+    * [FELIX-3411] - The implementation of org.osgi.service.startlevel.StartLevel#setStartLevel(int) does not follow the spec
+    * [FELIX-3413] - NPE and thread blocked in org.osgi.service.packageadmin.PackageAdmin#refreshPackages(Bundle[])
+    * [FELIX-3455] - Framework JARs for JDK 7
+    * [FELIX-3465] - Multi root resolve operations may cause duplicate blame chains to be created
+    * [FELIX-3618] - [Framework] Should not allow bundles to use generic cap/req headers for osgi.wiring.* namespaces
+    * [FELIX-3626] - Issue of felix on android 4.1
+    * [FELIX-3632] - [Framework] Parsing of delimited strings in manifest parser collapses all consecutive escapes
+    * [FELIX-3670] - PackageAdmin.isBundleType throws NPE for uninstalled bundle
+    * [FELIX-3713] - Bundle.start() returns without starting the bundle
+    * [FELIX-3743] - Potential endless loop setting the active framework startlevel
+    * [FELIX-3753] - Felix crashes when embedded within Felix
+    * [FELIX-3761] - When a bundle registers a service, the bundle lock is obtained without any real purpose
+    * [FELIX-3766] - Slightly invalid logic for pre-checking dynamic imports which cause the framework the grab the lock with no real need
+    * [FELIX-3803] - Bundle#getResource always try to resolve the bundle
+    * [FELIX-3824] - Possible InvalidStateException thrown while unregistering bundle services
+    * [FELIX-3840] - problem with URLHandlers when running 2 frameworks in one jvm in separate class loaders
+    * [FELIX-3844] - Native bundles cannot be installed on Windows 8 and Windows Server 2012
+    * [FELIX-3852] - InstallBundle throws ClassCastException: java.util.jar.Attributes$Name cannot be cast to java.lang.String
+    * [FELIX-3887] - ClassCastException during resolution of Require-Bundle: system.bundle
+
+** Improvement
+    * [FELIX-3344] - [Framework] Filter parsing treats ** as invalid syntax
+    * [FELIX-3372] - Add the ability to handle a blank on the property "org.osgi.framework.system.packages.extra"
+    * [FELIX-3394] - [Framework] Refactor internal resolver APIs to better align with upcoming OSGi resolver spec
+    * [FELIX-3447] - Optimize read only collections by using a specific class and not a wrapper which is slower
+    * [FELIX-3553] - Use of parallel class loading capability of JDK7
+    * [FELIX-3609] - Small optimizations
+    * [FELIX-3611] - Bundle certificates are not added to the CodeSource when building the BundleProtectionDomain
+    * [FELIX-3807] - Refreshing bundles should first grab all the bundle locks to avoid concurrent modifications of those bundles
+
+** New Feature
+    * [FELIX-3504] - [Framework] Move to OSGi R5 packages
+
+** Task
+    * [FELIX-3786] - Create system package definintions for Java 8
+
+
+Changes from 4.0.2 to 4.0.3
+---------------------------
+
+** Bug
+    * [FELIX-3003] - NPE in ResolverImpl.permutateIfNeeded
+    * [FELIX-3296] - URLHandlers caches null as values for common protocols
+    * [FELIX-3302] - Adapt the URLHandlers for the 4.0 refactoring
+    * [FELIX-3363] - Native bundles cannot be installed on Windows Server 2008 r2 with the tag win32
+    * [FELIX-3393] - Possible deadlock with reentrant calls
+    * [FELIX-3572] - [Framework] Resolver is not checking package space consistency for dynamic imports
+
+** Improvement
+    * [FELIX-3262] - Startup delay due to URLHandlersBundleStreamHandler
+
+Changes from 4.0.1 to 4.0.2
+---------------------------
+
+** Bug
+    * [FELIX-3178] - NPE in ResolverImpl
+    * [FELIX-3194] - [Framework] Manifest parser is not correctly handling escapes
+    * [FELIX-3205] - Error resolving system.bundle dependencies
+    * [FELIX-3207] - Improper handling of nulls and substring matching at CapabilitySet/SimpleFilter
+    * [FELIX-3211] - org.apache.felix.framework.cache.BundleCache.deleteDirectoryTreeRecursive throws NPE
+    * [FELIX-3220] - Multiple ClassCastException(s) when invoking OSGi Service-Hooks (EventHook, FindHook)
+
+** Improvement
+    * [FELIX-3166] - Make Felix compile within Eclipse
+
+** New Feature
+    * [FELIX-3156] - Implement Bundle::getDataFile and Bundle::compareTo
+
 Changes from 4.0.0 to 4.0.1
 ---------------------------
 
diff --git a/pom.xml b/pom.xml
index 09fba3e..1432244 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,16 +27,16 @@
   <packaging>bundle</packaging>
   <name>Apache Felix Framework</name>
   <artifactId>org.apache.felix.framework</artifactId>
-  <version>4.0.1</version>
+  <version>4.4.0</version>
   <dependencies>
   </dependencies>
   <properties>
     <dollar>$</dollar>
   </properties>
     <scm>
-      <connection>scm:svn:http://svn.apache.org/repos/asf/felix/releases/org.apache.felix.framework-4.0.1</connection>
-      <developerConnection>scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.framework-4.0.1</developerConnection>
-      <url>scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.framework-4.0.1</url>
+      <connection>scm:svn:http://svn.apache.org/repos/asf/felix/releases/org.apache.felix.framework-4.4.0</connection>
+      <developerConnection>scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.framework-4.4.0</developerConnection>
+      <url>scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.framework-4.4.0</url>
     </scm>
   <build>
     <plugins>
@@ -44,7 +44,7 @@
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
         <configuration>
-          <target>jsr14</target>
+          <target>1.5</target>
           <source>1.5</source>
         </configuration>
       </plugin>
@@ -60,7 +60,7 @@
             <Bundle-Name>Apache Felix Framework</Bundle-Name>
             <Bundle-Description>OSGi R4 framework implementation.</Bundle-Description>
             <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
-            <Export-Package>org.osgi.framework.*;-split-package:=merge-first,org.osgi.service.packageadmin,org.osgi.service.url,org.osgi.service.startlevel,org.osgi.util.tracker</Export-Package>
+            <Export-Package>org.osgi.framework.*;-split-package:=merge-first,org.osgi.resource,org.osgi.service.*,org.osgi.util.tracker</Export-Package>
             <Private-Package>org.apache.felix.framework.*</Private-Package>
             <Import-Package>!*</Import-Package>
           </instructions>
diff --git a/src/main/appended-resources/META-INF/DEPENDENCIES b/src/main/appended-resources/META-INF/DEPENDENCIES
index 1e5d957..310180d 100644
--- a/src/main/appended-resources/META-INF/DEPENDENCIES
+++ b/src/main/appended-resources/META-INF/DEPENDENCIES
@@ -1,4 +1,4 @@
-Copyright 2011 The Apache Software Foundation
+Copyright 2013 The Apache Software Foundation
 
 This software was developed at the Apache Software Foundation
 (http://www.apache.org) and may have dependencies on other
@@ -8,14 +8,14 @@ I. Included Third-Party Software
 
 This product includes software developed at
 The OSGi Alliance (http://www.osgi.org/).
-Copyright (c) OSGi Alliance (2000, 2009).
+Copyright (c) OSGi Alliance (2000, 2012).
 Licensed under the Apache License 2.0.
 
 II. Used Third-Party Software
 
 This product uses software developed at
 The OSGi Alliance (http://www.osgi.org/).
-Copyright (c) OSGi Alliance (2000, 2009).
+Copyright (c) OSGi Alliance (2000, 2012).
 Licensed under the Apache License 2.0.
 
 III. License Summary
diff --git a/src/main/appended-resources/META-INF/NOTICE b/src/main/appended-resources/META-INF/NOTICE
index 3db2e43..8b4b009 100644
--- a/src/main/appended-resources/META-INF/NOTICE
+++ b/src/main/appended-resources/META-INF/NOTICE
@@ -1,4 +1,4 @@
 This product includes software developed at
 The OSGi Alliance (http://www.osgi.org/).
-Copyright (c) OSGi Alliance (2000, 2009).
+Copyright (c) OSGi Alliance (2000, 2012).
 Licensed under the Apache License 2.0.
diff --git a/src/main/java/org/apache/felix/framework/BundleContextImpl.java b/src/main/java/org/apache/felix/framework/BundleContextImpl.java
index d7bbfa0..bbdd980 100644
--- a/src/main/java/org/apache/felix/framework/BundleContextImpl.java
+++ b/src/main/java/org/apache/felix/framework/BundleContextImpl.java
@@ -343,7 +343,7 @@ class BundleContextImpl implements FelixBundleContext
             }
         }
 
-        return m_felix.registerService(m_bundle, clazzes, svcObj, dict);
+        return m_felix.registerService(this, clazzes, svcObj, dict);
     }
 
     public <S> ServiceRegistration<S> registerService(
diff --git a/src/main/java/org/apache/felix/framework/BundleImpl.java b/src/main/java/org/apache/felix/framework/BundleImpl.java
index e89f727..f04bac7 100644
--- a/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -22,12 +22,24 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.security.AccessControlContext;
 import java.security.ProtectionDomain;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
 
 import org.apache.felix.framework.cache.BundleArchive;
-import org.apache.felix.framework.ext.SecurityProvider;
 import org.apache.felix.framework.util.SecurityManagerEx;
+import org.apache.felix.framework.util.ShrinkableCollection;
 import org.apache.felix.framework.util.StringMap;
 import org.apache.felix.framework.util.Util;
 import org.osgi.framework.AdaptPermission;
@@ -40,6 +52,7 @@ import org.osgi.framework.Constants;
 import org.osgi.framework.ServicePermission;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.Version;
+import org.osgi.framework.hooks.bundle.CollisionHook;
 import org.osgi.framework.startlevel.BundleStartLevel;
 import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.framework.wiring.BundleRevisions;
@@ -58,7 +71,9 @@ class BundleImpl implements Bundle, BundleRevisions
     private BundleActivator m_activator = null;
     private volatile BundleContext m_context = null;
     private final Map m_cachedHeaders = new HashMap();
+    private Map m_uninstalledHeaders = null;
     private long m_cachedHeadersTimestamp;
+    private final Bundle m_installingBundle;
 
     // Indicates whether the bundle is stale, meaning that it has
     // been refreshed and completely removed from the framework.
@@ -80,9 +95,10 @@ class BundleImpl implements Bundle, BundleRevisions
         m_stale = false;
         m_activator = null;
         m_context = null;
+        m_installingBundle = null;
     }
 
-    BundleImpl(Felix felix, BundleArchive archive) throws Exception
+    BundleImpl(Felix felix, Bundle installingBundle, BundleArchive archive) throws Exception
     {
         __m_felix = felix;
         m_archive = archive;
@@ -91,8 +107,9 @@ class BundleImpl implements Bundle, BundleRevisions
         m_stale = false;
         m_activator = null;
         m_context = null;
+        m_installingBundle = installingBundle;
 
-        BundleRevision revision = createRevision();
+        BundleRevision revision = createRevision(false);
         addRevision(revision);
     }
 
@@ -132,12 +149,15 @@ class BundleImpl implements Bundle, BundleRevisions
 // for last case.
     synchronized void closeAndDelete() throws Exception
     {
-        // Mark the bundle as stale, since it is being deleted.
-        m_stale = true;
-        // Close all revisions.
-        closeRevisions();
-        // Delete bundle archive, which will close revisions.
-        m_archive.closeAndDelete();
+        if (!m_stale)
+        {
+            // Mark the bundle as stale, since it is being deleted.
+            m_stale = true;
+            // Close all revisions.
+            closeRevisions();
+            // Delete bundle archive, which will close revisions.
+            m_archive.closeAndDelete();
+        }
     }
 
 // Called from BundleImpl.close(), BundleImpl.closeAndDelete(), and BundleImpl.refresh()
@@ -166,7 +186,7 @@ class BundleImpl implements Bundle, BundleRevisions
         else
         {
             // Get current revision, since we can reuse it.
-            BundleRevisionImpl current = (BundleRevisionImpl) adapt(BundleRevisionImpl.class);
+            BundleRevisionImpl current = adapt(BundleRevisionImpl.class);
             // Close all existing revisions.
             closeRevisions();
             // Clear all revisions.
@@ -183,8 +203,12 @@ class BundleImpl implements Bundle, BundleRevisions
             // Reset the bundle state.
             m_state = Bundle.INSTALLED;
             m_stale = false;
-            m_cachedHeaders.clear();
-            m_cachedHeadersTimestamp = 0;
+
+            synchronized (m_cachedHeaders)
+            {
+                m_cachedHeaders.clear();
+                m_cachedHeadersTimestamp = 0;
+            }
         }
     }
 
@@ -301,7 +325,7 @@ class BundleImpl implements Bundle, BundleRevisions
         }
 
         return getFramework().findBundleEntries(
-            adapt(BundleRevisionImpl.class), path, filePattern, recurse);
+                this, path, filePattern, recurse);
     }
 
     public Dictionary getHeaders()
@@ -334,7 +358,7 @@ class BundleImpl implements Bundle, BundleRevisions
         // Spec says empty local returns raw headers.
         if (locale.length() == 0)
         {
-            result = new StringMap(adapt(BundleRevisionImpl.class).getHeaders(), false);
+            result = new StringMap(adapt(BundleRevisionImpl.class).getHeaders());
         }
 
         // If we have no result, try to get it from the cached headers.
@@ -342,12 +366,12 @@ class BundleImpl implements Bundle, BundleRevisions
         {
             synchronized (m_cachedHeaders)
             {
-                // If the bundle is uninstalled, then the cached headers should
-                // only contain the localized headers for the default locale at
-                // the time of uninstall, so just return that.
-                if (getState() == Bundle.UNINSTALLED)
+                // If the bundle is uninstalled, then we should always return
+                // the uninstalled headers, which are the default locale as per
+                // the spec.
+                if (m_uninstalledHeaders != null)
                 {
-                    result = (Map) m_cachedHeaders.values().iterator().next();
+                    result = m_uninstalledHeaders;
                 }
                 // If the bundle has been updated, clear the cached headers.
                 else if (getLastModified() > m_cachedHeadersTimestamp)
@@ -370,7 +394,7 @@ class BundleImpl implements Bundle, BundleRevisions
         if (result == null)
         {
             // Get a modifiable copy of the raw headers.
-            Map headers = new StringMap(adapt(BundleRevisionImpl.class).getHeaders(), false);
+            Map headers = new StringMap(adapt(BundleRevisionImpl.class).getHeaders());
             // Assume for now that this will be the result.
             result = headers;
 
@@ -471,8 +495,11 @@ class BundleImpl implements Bundle, BundleRevisions
     {
         synchronized (m_cachedHeaders)
         {
-            m_cachedHeaders.put(locale, localizedHeaders);
-            m_cachedHeadersTimestamp = System.currentTimeMillis();
+            if (m_uninstalledHeaders == null)
+            {
+                m_cachedHeaders.put(locale, localizedHeaders);
+                m_cachedHeadersTimestamp = System.currentTimeMillis();
+            }
         }
     }
 
@@ -834,7 +861,12 @@ class BundleImpl implements Bundle, BundleRevisions
     {
         try
         {
-            return m_archive.getStartLevel();
+            int level = m_archive.getStartLevel();
+            if ( level == -1 )
+            {
+                level = defaultLevel;
+            }
+            return level;
         }
         catch (Exception ex)
         {
@@ -1000,17 +1032,17 @@ class BundleImpl implements Bundle, BundleRevisions
         // only the default locale will be left in the header cache.
         synchronized (m_cachedHeaders)
         {
-            if ((m_cachedHeaders.size() > 1)
-                || !m_cachedHeaders.containsKey(Locale.getDefault().toString()))
+            if (m_uninstalledHeaders == null)
             {
+                m_uninstalledHeaders = getCurrentLocalizedHeader(Locale.getDefault().toString());
                 m_cachedHeaders.clear();
-                Map map = getCurrentLocalizedHeader(Locale.getDefault().toString());
             }
         }
 
         // Uninstall the bundle.
         getFramework().uninstallBundle(this);
     }
+
     private static final SecurityManagerEx m_smEx = new SecurityManagerEx();
     private static final ClassLoader m_classloader = Felix.class.getClassLoader();
 
@@ -1032,7 +1064,11 @@ class BundleImpl implements Bundle, BundleRevisions
     public synchronized <A> A adapt(Class<A> type)
     {
         checkAdapt(type);
-        if (type == BundleStartLevel.class)
+        if (type == BundleContext.class)
+        {
+            return (A) m_context;
+        }
+        else if (type == BundleStartLevel.class)
         {
             return (A) getFramework().adapt(FrameworkStartLevelImpl.class)
                 .createBundleStartLevel(this);
@@ -1064,19 +1100,36 @@ class BundleImpl implements Bundle, BundleRevisions
             }
             return (A) m_revisions.get(0).getWiring();
         }
+        else if ( type == AccessControlContext.class)
+        {
+            if (m_state == Bundle.UNINSTALLED)
+            {
+                return null;
+            }
+            final ProtectionDomain pd = this.getProtectionDomain();
+            if (pd == null)
+            {
+                return null;
+            }
+            return (A) new AccessControlContext(new ProtectionDomain[] {pd});
+
+        }
         return null;
     }
 
     public File getDataFile(String filename)
     {
-        throw new UnsupportedOperationException("Not supported yet.");
+        return getFramework().getDataFile(this, filename);
     }
 
     public int compareTo(Bundle t)
     {
-        throw new UnsupportedOperationException("Not supported yet.");
+        long thisBundleId = this.getBundleId();
+        long thatBundleId = t.getBundleId();
+        return (thisBundleId < thatBundleId ? -1 : (thisBundleId == thatBundleId ? 0 : 1));
     }
 
+    @Override
     public String toString()
     {
         String sym = getSymbolicName();
@@ -1124,7 +1177,7 @@ class BundleImpl implements Bundle, BundleRevisions
         m_archive.revise(location, is);
         try
         {
-            BundleRevision revision = createRevision();
+            BundleRevision revision = createRevision(true);
             addRevision(revision);
         }
         catch (Exception ex)
@@ -1155,23 +1208,14 @@ class BundleImpl implements Bundle, BundleRevisions
     {
         m_revisions.add(0, revision);
 
-        // Set protection domain after adding the revision to the bundle,
-        // since this requires that the bundle has a revision.
-        ((BundleRevisionImpl) revision).setProtectionDomain(
-            new BundleProtectionDomain(getFramework(), this));
-
-        SecurityProvider sp = getFramework().getSecurityProvider();
-        if ((sp != null) && (System.getSecurityManager() != null))
+        try
         {
-            try
-            {
-                sp.checkBundle(this);
-            }
-            catch (Exception ex)
-            {
-                m_revisions.remove(0);
-                throw ex;
-            }
+            getFramework().setBundleProtectionDomain(this, (BundleRevisionImpl) revision);
+        }
+        catch (Exception ex)
+        {
+            m_revisions.remove(0);
+            throw ex;
         }
 
         // TODO: REFACTOR - consider nulling capabilities for extension bundles
@@ -1184,7 +1228,7 @@ class BundleImpl implements Bundle, BundleRevisions
         }
     }
 
-    private BundleRevision createRevision() throws Exception
+    private BundleRevision createRevision(boolean isUpdate) throws Exception
     {
         // Get and parse the manifest from the most recent revision and
         // create an associated revision object for it.
@@ -1203,7 +1247,7 @@ class BundleImpl implements Bundle, BundleRevisions
         String allowMultiple =
             (String) getFramework().getConfig().get(Constants.FRAMEWORK_BSNVERSION);
         allowMultiple = (allowMultiple == null)
-            ? Constants.FRAMEWORK_BSNVERSION_SINGLE
+            ? Constants.FRAMEWORK_BSNVERSION_MANAGED
             : allowMultiple;
         if (revision.getManifestVersion().equals("2")
             && !allowMultiple.equals(Constants.FRAMEWORK_BSNVERSION_MULTIPLE))
@@ -1212,25 +1256,56 @@ class BundleImpl implements Bundle, BundleRevisions
             bundleVersion = (bundleVersion == null) ? Version.emptyVersion : bundleVersion;
             String symName = revision.getSymbolicName();
 
+            List<Bundle> collisionCanditates = new ArrayList<Bundle>();
             Bundle[] bundles = getFramework().getBundles();
             for (int i = 0; (bundles != null) && (i < bundles.length); i++)
             {
                 long id = ((BundleImpl) bundles[i]).getBundleId();
                 if (id != getBundleId())
                 {
-                    String sym = bundles[i].getSymbolicName();
-                    Version ver = bundles[i].getVersion();
-                    if ((symName != null)
-                        && (sym != null)
-                        && symName.equals(sym)
-                        && bundleVersion.equals(ver))
+                    if (symName.equals(bundles[i].getSymbolicName())
+                        && bundleVersion.equals(bundles[i].getVersion()))
+                    {
+                        collisionCanditates.add(bundles[i]);
+                    }
+                }
+            }
+            if (!collisionCanditates.isEmpty() && allowMultiple.equals(Constants.FRAMEWORK_BSNVERSION_MANAGED))
+            {
+                Set<ServiceReference<CollisionHook>> hooks = getFramework().getHooks(CollisionHook.class);
+                if (!hooks.isEmpty())
+                {
+                    Collection<Bundle> shrinkableCollisionCandidates = new ShrinkableCollection<Bundle>(collisionCanditates);
+                    for (ServiceReference<CollisionHook> hook : hooks)
                     {
-                        throw new BundleException(
-                            "Bundle symbolic name and version are not unique: "
-                            + sym + ':' + ver, BundleException.DUPLICATE_BUNDLE_ERROR);
+                        CollisionHook ch = getFramework().getService(getFramework(), hook);
+                        if (ch != null)
+                        {
+                            int operationType;
+                            Bundle target;
+                            if (isUpdate)
+                            {
+                                operationType = CollisionHook.UPDATING;
+                                target = this;
+                            }
+                            else
+                            {
+                                operationType = CollisionHook.INSTALLING;
+                                target = m_installingBundle == null ? this : m_installingBundle;
+                            }
+
+                            Felix.m_secureAction.invokeBundleCollisionHook(ch, operationType, target,
+                                    shrinkableCollisionCandidates);
+                        }
                     }
                 }
             }
+            if (!collisionCanditates.isEmpty())
+            {
+                throw new BundleException(
+                    "Bundle symbolic name and version are not unique: "
+                    + symName + ':' + bundleVersion, BundleException.DUPLICATE_BUNDLE_ERROR);
+            }
         }
 
         return revision;
@@ -1242,8 +1317,7 @@ class BundleImpl implements Bundle, BundleRevisions
 
         for (int i = m_revisions.size() - 1; (i >= 0) && (pd == null); i--)
         {
-            pd = (ProtectionDomain)
-                ((BundleRevisionImpl) m_revisions.get(i)).getProtectionDomain();
+            pd = ((BundleRevisionImpl) m_revisions.get(i)).getProtectionDomain();
         }
 
         return pd;
@@ -1294,4 +1368,4 @@ class BundleImpl implements Bundle, BundleRevisions
     {
         return m_context;
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/felix/framework/BundleProtectionDomain.java b/src/main/java/org/apache/felix/framework/BundleProtectionDomain.java
index eda9f21..061105c 100644
--- a/src/main/java/org/apache/felix/framework/BundleProtectionDomain.java
+++ b/src/main/java/org/apache/felix/framework/BundleProtectionDomain.java
@@ -36,21 +36,23 @@ public class BundleProtectionDomain extends ProtectionDomain
     private final WeakReference m_revision;
 
     // TODO: SECURITY - This should probably take a revision, not a bundle.
-    BundleProtectionDomain(Felix felix, BundleImpl bundle)
+    BundleProtectionDomain(Felix felix, BundleImpl bundle, Object certificates)
         throws MalformedURLException
     {
         super(
             new CodeSource(
                 Felix.m_secureAction.createURL(
                     Felix.m_secureAction.createURL(null, "location:", new FakeURLStreamHandler()),
-                    bundle._getLocation(),
+                    bundle._getLocation().startsWith("reference:") ? 
+                        bundle._getLocation().substring("reference:".length()) : 
+                        bundle._getLocation(),
                     new FakeURLStreamHandler()
                     ),
-                (Certificate[]) null),
-            null);
+                (Certificate[]) certificates),
+            null, null, null);
         m_felix = new WeakReference(felix);
         m_bundle = new WeakReference(bundle);
-        m_revision = new WeakReference(bundle.adapt(BundleRevision.class));
+        m_revision = new WeakReference(bundle.adapt(BundleRevisionImpl.class));
         m_hashCode = bundle.hashCode();
         m_toString = "[" + bundle + "]";
     }
@@ -67,6 +69,11 @@ public class BundleProtectionDomain extends ProtectionDomain
             felix.impliesBundlePermission(this, permission, false) : false;
     }
 
+    boolean superImplies(Permission permission)
+    {
+        return super.implies(permission);
+    }
+
     public boolean impliesDirect(Permission permission)
     {
         Felix felix = (Felix) m_felix.get();
@@ -101,4 +108,4 @@ public class BundleProtectionDomain extends ProtectionDomain
     {
         return m_toString;
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/felix/framework/BundleRevisionDependencies.java b/src/main/java/org/apache/felix/framework/BundleRevisionDependencies.java
index 1e3a8fe..9cdb9d8 100644
--- a/src/main/java/org/apache/felix/framework/BundleRevisionDependencies.java
+++ b/src/main/java/org/apache/felix/framework/BundleRevisionDependencies.java
@@ -41,9 +41,7 @@ class BundleRevisionDependencies
 
     public synchronized void addDependent(BundleWire bw)
     {
-// TODO: OSGi R4.4 - Eventually we won't need to use the impl type here,
-//       since the plan is to standardize on this method for the OBR spec.
-        BundleRevision provider = ((BundleWireImpl) bw).getProvider();
+        BundleRevision provider = bw.getProvider();
         Map<BundleCapability, Set<BundleWire>> caps =
             m_dependentsMap.get(provider);
         if (caps == null)
@@ -186,10 +184,7 @@ class BundleRevisionDependencies
                     {
                         for (BundleWire dependentWire : entry.getValue())
                         {
-// TODO: OSGi R4.4 - Eventually we won't need to use the impl type here,
-//       since the plan is to standardize on this method for the OBR spec.
-                            result.add(((BundleWireImpl) dependentWire)
-                                .getRequirer().getBundle());
+                            result.add(dependentWire.getRequirer().getBundle());
                         }
                     }
                 }
@@ -227,10 +222,7 @@ class BundleRevisionDependencies
                     {
                         for (BundleWire dependentWire : entry.getValue())
                         {
-// TODO: OSGi R4.4 - Eventually we won't need to use the impl type here,
-//       since the plan is to standardize on this method for the OBR spec.
-                            result.add(((BundleWireImpl) dependentWire)
-                                .getRequirer().getBundle());
+                            result.add(dependentWire.getRequirer().getBundle());
                         }
                     }
                 }
@@ -260,10 +252,7 @@ class BundleRevisionDependencies
                     {
                         for (BundleWire dependentWire : entry.getValue())
                         {
-// TODO: OSGi R4.4 - Eventually we won't need to use the impl type here,
-//       since the plan is to standardize on this method for the OBR spec.
-                            result.add(((BundleWireImpl) dependentWire)
-                                .getRequirer().getBundle());
+                            result.add(dependentWire.getRequirer().getBundle());
                         }
                     }
                 }
@@ -284,10 +273,8 @@ class BundleRevisionDependencies
             {
                 for (BundleWire bw : wiring.getRequiredWires(null))
                 {
-// TODO: OSGi R4.4 - Eventually we won't need to use the impl type here,
-//       since the plan is to standardize on this method for the OBR spec.
                     Map<BundleCapability, Set<BundleWire>> caps =
-                        m_dependentsMap.get(((BundleWireImpl) bw).getProvider());
+                        m_dependentsMap.get(bw.getProvider());
                     if (caps != null)
                     {
                         List<BundleCapability> gc = new ArrayList<BundleCapability>();
@@ -306,9 +293,7 @@ class BundleRevisionDependencies
                         }
                         if (caps.isEmpty())
                         {
-// TODO: OSGi R4.4 - Eventually we won't need to use the impl type here,
-//       since the plan is to standardize on this method for the OBR spec.
-                            m_dependentsMap.remove(((BundleWireImpl) bw).getProvider());
+                            m_dependentsMap.remove(bw.getProvider());
                         }
                     }
                 }
diff --git a/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java b/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
index 7e184cc..bc8de71 100644
--- a/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
+++ b/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
@@ -22,7 +22,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.net.URLStreamHandler;
 import java.security.ProtectionDomain;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -43,8 +42,11 @@ import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
 
-public class BundleRevisionImpl implements BundleRevision
+public class BundleRevisionImpl implements BundleRevision, Resource
 {
     public final static int EAGER_ACTIVATION = 0;
     public final static int LAZY_ACTIVATION = 1;
@@ -54,6 +56,7 @@ public class BundleRevisionImpl implements BundleRevision
 
     private final String m_manifestVersion;
     private final boolean m_isExtension;
+    private final boolean m_isFragment;
     private final String m_symbolicName;
     private final Version m_version;
 
@@ -90,9 +93,10 @@ public class BundleRevisionImpl implements BundleRevision
         m_id = id;
         m_headerMap = null;
         m_content = null;
-        m_manifestVersion = null;
+        m_manifestVersion = "";
         m_symbolicName = null;
         m_isExtension = false;
+        m_isFragment = false;
         m_version = null;
         m_declaredCaps = Collections.EMPTY_LIST;
         m_declaredReqs = Collections.EMPTY_LIST;
@@ -134,6 +138,7 @@ public class BundleRevisionImpl implements BundleRevision
             : ManifestParser.parseDelimitedString(mp.getActivationIncludeDirective(), ",");
         m_symbolicName = mp.getSymbolicName();
         m_isExtension = mp.isExtension();
+        m_isFragment = m_headerMap.containsKey(Constants.FRAGMENT_HOST);
     }
 
     static SecureAction getSecureAction()
@@ -189,6 +194,16 @@ public class BundleRevisionImpl implements BundleRevision
         return m_version;
     }
 
+    public List<Capability> getCapabilities(String namespace)
+    {
+        return asCapabilityList(getDeclaredCapabilities(namespace));
+    }
+
+    static List<Capability> asCapabilityList(List reqs)
+    {
+        return (List<Capability>) reqs;
+    }
+
     public List<BundleCapability> getDeclaredCapabilities(String namespace)
     {
         List<BundleCapability> result = m_declaredCaps;
@@ -206,6 +221,16 @@ public class BundleRevisionImpl implements BundleRevision
         return result;
     }
 
+    public List<Requirement> getRequirements(String namespace)
+    {
+        return asRequirementList(getDeclaredRequirements(namespace));
+    }
+
+    static List<Requirement> asRequirementList(List reqs)
+    {
+        return (List<Requirement>) reqs;
+    }
+
     public List<BundleRequirement> getDeclaredRequirements(String namespace)
     {
         List<BundleRequirement> result = m_declaredReqs;
@@ -225,11 +250,7 @@ public class BundleRevisionImpl implements BundleRevision
 
     public int getTypes()
     {
-        if (getHeaders().containsKey(Constants.FRAGMENT_HOST))
-        {
-            return BundleRevision.TYPE_FRAGMENT;
-        }
-        return 0;
+        return (getManifestVersion().equals("2") && m_isFragment) ? BundleRevision.TYPE_FRAGMENT : 0;
     }
 
     public BundleWiring getWiring()
@@ -650,4 +671,4 @@ public class BundleRevisionImpl implements BundleRevision
     {
         return m_id;
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/felix/framework/BundleWiringImpl.java b/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
index af7cea8..beecd41 100644
--- a/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
+++ b/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
@@ -48,6 +48,7 @@ import org.apache.felix.framework.resolver.ResolveException;
 import org.apache.felix.framework.resolver.ResourceNotFoundException;
 import org.apache.felix.framework.util.CompoundEnumeration;
 import org.apache.felix.framework.util.FelixConstants;
+import org.apache.felix.framework.util.ImmutableList;
 import org.apache.felix.framework.util.SecurityManagerEx;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.manifestparser.ManifestParser;
@@ -63,11 +64,15 @@ import org.osgi.framework.PackagePermission;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.hooks.weaving.WeavingException;
 import org.osgi.framework.hooks.weaving.WeavingHook;
+import org.osgi.framework.namespace.IdentityNamespace;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.framework.wiring.BundleWire;
 import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Wire;
 
 public class BundleWiringImpl implements BundleWiring
 {
@@ -161,7 +166,7 @@ public class BundleWiringImpl implements BundleWiring
         m_revision = revision;
         m_importedPkgs = importedPkgs;
         m_requiredPkgs = requiredPkgs;
-        m_wires = Collections.unmodifiableList(wires);
+        m_wires = ImmutableList.newInstance(wires);
 
         // We need to sort the fragments and add ourself as a dependent of each one.
         // We also need to create an array of fragment contents to attach to our
@@ -246,24 +251,37 @@ public class BundleWiringImpl implements BundleWiring
                 }
             }
         }
-        m_resolvedReqs = Collections.unmodifiableList(reqList);
+        m_resolvedReqs = ImmutableList.newInstance(reqList);
 
         // Calculate resolved list of capabilities, which includes:
         // 1. All capabilities from host and any fragments except for exported
         //    packages that we have an import (i.e., the export was substituted).
-        // And nothing else at this time. Fragments currently have no capabilities.
+        // 2. For fragments the identity capability only.
+        // And nothing else at this time.
         boolean isFragment = Util.isFragment(revision);
-        List<BundleCapability> capList = (isFragment)
-            ? Collections.EMPTY_LIST
-            : new ArrayList<BundleCapability>();
+        List<BundleCapability> capList = new ArrayList<BundleCapability>();
         // Also keep track of whether any resolved package capabilities are filtered.
         Map<String, List<List<String>>> includedPkgFilters =
             new HashMap<String, List<List<String>>>();
         Map<String, List<List<String>>> excludedPkgFilters =
             new HashMap<String, List<List<String>>>();
-// TODO: OSGi R4.4 - Fragments currently have no capabilities, but they may
-//       have an identity capability in the future.
-        if (!isFragment)
+
+        if (isFragment)
+        {
+            // This is a fragment, add its identity capability
+            for (BundleCapability cap : m_revision.getDeclaredCapabilities(null))
+            {
+                if (IdentityNamespace.IDENTITY_NAMESPACE.equals(cap.getNamespace()))
+                {
+                    String effective = cap.getDirectives().get(Constants.EFFECTIVE_DIRECTIVE);
+                    if ((effective == null) || (effective.equals(Constants.EFFECTIVE_RESOLVE)))
+                    {
+                        capList.add(cap);
+                    }
+                }
+            }
+        }
+        else
         {
             for (BundleCapability cap : m_revision.getDeclaredCapabilities(null))
             {
@@ -305,8 +323,11 @@ public class BundleWiringImpl implements BundleWiring
                 {
                     for (BundleCapability cap : fragment.getDeclaredCapabilities(null))
                     {
-// TODO: OSGi R4.4 - OSGi R4.4 may introduce an identity capability, if so
-//       that will need to be excluded from here.
+                        if (IdentityNamespace.IDENTITY_NAMESPACE.equals(cap.getNamespace())) {
+                            // The identity capability is not transferred from the fragment to the bundle
+                            continue;
+                        }
+
                         if (!cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
                             || (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
                                 && !imports.contains(cap.getAttributes()
@@ -372,7 +393,7 @@ public class BundleWiringImpl implements BundleWiring
             }
         }
 
-        m_resolvedCaps = Collections.unmodifiableList(capList);
+        m_resolvedCaps = ImmutableList.newInstance(capList);
         m_includedPkgFilters = (includedPkgFilters.isEmpty())
             ? Collections.EMPTY_MAP : includedPkgFilters;
         m_excludedPkgFilters = (excludedPkgFilters.isEmpty())
@@ -400,7 +421,7 @@ public class BundleWiringImpl implements BundleWiring
         // could not be found when resolving the bundle.
         m_resolvedNativeLibs = (libList.isEmpty())
             ? null
-            : Collections.unmodifiableList(libList);
+            : ImmutableList.newInstance(libList);
 
         ClassLoader bootLoader = m_defBootClassLoader;
         if (revision.getBundle().getBundleId() != 0)
@@ -447,6 +468,12 @@ public class BundleWiringImpl implements BundleWiring
         return filters;
     }
 
+    @Override
+    public String toString()
+    {
+        return m_revision.getBundle().toString();
+    }
+
     public synchronized void dispose()
     {
         if (m_fragmentContents != null)
@@ -490,6 +517,11 @@ public class BundleWiringImpl implements BundleWiring
         return !m_isDisposed;
     }
 
+    public List<Capability> getResourceCapabilities(String namespace)
+    {
+        return BundleRevisionImpl.asCapabilityList(getCapabilities(namespace));
+    }
+
     public List<BundleCapability> getCapabilities(String namespace)
     {
         if (isInUse())
@@ -511,6 +543,11 @@ public class BundleWiringImpl implements BundleWiring
         return null;
     }
 
+    public List<Requirement> getResourceRequirements(String namespace)
+    {
+        return BundleRevisionImpl.asRequirementList(getRequirements(namespace));
+    }
+
     public List<BundleRequirement> getRequirements(String namespace)
     {
         if (isInUse())
@@ -547,6 +584,16 @@ public class BundleWiringImpl implements BundleWiring
         return m_resolvedNativeLibs;
     }
 
+    private static List<Wire> asWireList(List wires)
+    {
+        return (List<Wire>) wires;
+    }
+
+    public List<Wire> getProvidedResourceWires(String namespace)
+    {
+        return asWireList(getProvidedWires(namespace));
+    }
+
     public List<BundleWire> getProvidedWires(String namespace)
     {
         if (isInUse())
@@ -557,6 +604,11 @@ public class BundleWiringImpl implements BundleWiring
         return null;
     }
 
+    public List<Wire> getRequiredResourceWires(String namespace)
+    {
+        return asWireList(getRequiredWires(namespace));
+    }
+
     public List<BundleWire> getRequiredWires(String namespace)
     {
         if (isInUse())
@@ -593,22 +645,34 @@ public class BundleWiringImpl implements BundleWiring
         // Technically, there is a window here where readers won't see
         // both values updates at the same time, but it seems unlikely
         // to cause any issues.
-        m_wires = Collections.unmodifiableList(wires);
+        m_wires = ImmutableList.newInstance(wires);
         m_importedPkgs = importedPkgs;
     }
 
+    public BundleRevision getResource()
+    {
+        return m_revision;
+    }
+
     public BundleRevision getRevision()
     {
         return m_revision;
     }
 
-    public synchronized ClassLoader getClassLoader()
+    public ClassLoader getClassLoader()
     {
         if (m_isDisposed)
         {
             return null;
         }
-        if (m_classLoader == null)
+        return getClassLoaderInternal();
+    }
+
+    private synchronized ClassLoader getClassLoaderInternal()
+    {
+        // Only try to create the class loader if the bundle
+        // is not disposed.
+        if (!m_isDisposed && (m_classLoader == null))
         {
             // Determine which class loader to use based on which
             // Java platform we are running on.
@@ -667,7 +731,7 @@ public class BundleWiringImpl implements BundleWiring
                 {
                     entries.add(e.nextElement());
                 }
-                return Collections.unmodifiableList(entries);
+                return ImmutableList.newInstance(entries);
             }
             return Collections.EMPTY_LIST;
         }
@@ -1248,7 +1312,8 @@ public class BundleWiringImpl implements BundleWiring
     {
         // Get the appropriate class loader for delegation.
         ClassLoader parent = (m_classLoader == null)
-            ? determineParentClassLoader() : m_classLoader.getParent();
+            ? determineParentClassLoader() :
+            BundleRevisionImpl.getSecureAction().getParentClassLoader(m_classLoader);
         return (parent == null) ? m_bootClassLoader : parent;
     }
 
@@ -1314,7 +1379,17 @@ public class BundleWiringImpl implements BundleWiring
             throw new ClassNotFoundException(name);
         }
 
-        return getClassLoader().loadClass(name);
+        ClassLoader cl = getClassLoaderInternal();
+        if (cl == null)
+        {
+            throw new ClassNotFoundException(
+                "Unable to load class '"
+                + name
+                + "' because the bundle wiring for "
+                + m_revision.getSymbolicName()
+                + " is no longer valid.");
+        }
+        return cl.loadClass(name);
     }
 
     private boolean isFiltered(String name)
@@ -1429,9 +1504,24 @@ public class BundleWiringImpl implements BundleWiring
                 // If not found, try the revision's own class path.
                 if (result == null)
                 {
-                    result = (isClass)
-                        ? (Object) ((BundleClassLoader) getClassLoader()).findClass(name)
-                        : (Object) m_revision.getResourceLocal(name);
+                    if (isClass)
+                    {
+                        ClassLoader cl = getClassLoaderInternal();
+                        if (cl == null)
+                        {
+                            throw new ClassNotFoundException(
+                                "Unable to load class '"
+                                + name
+                                + "' because the bundle wiring for "
+                                + m_revision.getSymbolicName()
+                                + " is no longer valid.");
+                        }
+                        result = (Object) ((BundleClassLoader) cl).findClass(name);
+                    }
+                    else
+                    {
+                        result = (Object) m_revision.getResourceLocal(name);
+                    }
 
                     // If still not found, then try the revision's dynamic imports.
                     if (result == null)
@@ -1765,18 +1855,47 @@ public class BundleWiringImpl implements BundleWiring
         }
     }
 
-    public class BundleClassLoaderJava5 extends BundleClassLoader
+    public static class BundleClassLoaderJava5 extends BundleClassLoader
     {
-        public BundleClassLoaderJava5(ClassLoader parent)
+        static final boolean m_isParallel;
+        static
         {
-            super(parent);
+            boolean registered = false;
+            try
+            {
+                Method method = BundleRevisionImpl.getSecureAction()
+                    .getDeclaredMethod(ClassLoader.class, "registerAsParallelCapable", null);
+
+                BundleRevisionImpl.getSecureAction().setAccesssible(method);
+
+                registered = ((Boolean) method.invoke(null)).booleanValue();
+            }
+            catch (Throwable th)
+            {
+                // This is OK on older java versions
+            }
+
+            m_isParallel = registered;
+        }
+
+        protected boolean isParallel()
+        {
+            return m_isParallel;
+        }
+
+        private final BundleWiringImpl m_wiring;
+
+        public BundleClassLoaderJava5(BundleWiringImpl wiring, ClassLoader parent)
+        {
+            super(wiring, parent);
+            m_wiring = wiring;
         }
 
         @Override
         public Enumeration getResources(String name)
         {
-            Enumeration urls = BundleWiringImpl.this.getResourcesByDelegation(name);
-            if (m_useLocalURLs)
+            Enumeration urls = m_wiring.getResourcesByDelegation(name);
+            if (m_wiring.m_useLocalURLs)
             {
                 urls = new ToLocalUrlEnumeration(urls);
             }
@@ -1786,12 +1905,29 @@ public class BundleWiringImpl implements BundleWiring
         @Override
         protected Enumeration findResources(String name)
         {
-            return m_revision.getResourcesLocal(name);
+            return m_wiring.m_revision.getResourcesLocal(name);
         }
     }
 
-    public class BundleClassLoader extends SecureClassLoader implements BundleReference
+    public static class BundleClassLoader extends SecureClassLoader implements BundleReference
     {
+         static
+         {
+             try
+             {
+                 Method method = BundleRevisionImpl.getSecureAction()
+                    .getDeclaredMethod(ClassLoader.class, "registerAsParallelCapable", null);
+
+                 BundleRevisionImpl.getSecureAction().setAccesssible(method);
+
+                 method.invoke(null);
+             }
+             catch (Throwable th)
+             {
+                 // This is OK on older java versions
+             }
+         }
+
         // Flag used to determine if a class has been loaded from this class
         // loader or not.
         private volatile boolean m_isActivationTriggered = false;
@@ -1800,8 +1936,10 @@ public class BundleWiringImpl implements BundleWiring
         private Object[][] m_cachedLibs = new Object[0][];
         private static final int LIBNAME_IDX = 0;
         private static final int LIBPATH_IDX = 1;
+        private final Map<String, Thread> m_classLocks = new HashMap<String, Thread>();
+        private final BundleWiringImpl m_wiring;
 
-        public BundleClassLoader(ClassLoader parent)
+        public BundleClassLoader(BundleWiringImpl wiring, ClassLoader parent)
         {
             super(parent);
             if (m_dexFileClassLoadClass != null)
@@ -1812,6 +1950,12 @@ public class BundleWiringImpl implements BundleWiring
             {
                 m_jarContentToDexFile = null;
             }
+            m_wiring = wiring;
+        }
+
+        protected boolean isParallel()
+        {
+            return false;
         }
 
         public boolean isActivationTriggered()
@@ -1821,17 +1965,18 @@ public class BundleWiringImpl implements BundleWiring
 
         public Bundle getBundle()
         {
-            return BundleWiringImpl.this.getBundle();
+            return m_wiring.getBundle();
         }
 
         @Override
         protected Class loadClass(String name, boolean resolve)
             throws ClassNotFoundException
         {
-            Class clazz = null;
+            Class clazz;
 
             // Make sure the class was not already loaded.
-            synchronized (this)
+            Object lock = (isParallel()) ? m_classLocks : this;
+            synchronized (lock)
             {
                 clazz = findLoadedClass(name);
             }
@@ -1840,7 +1985,7 @@ public class BundleWiringImpl implements BundleWiring
             {
                 try
                 {
-                    clazz = (Class) findClassOrResourceByDelegation(name, true);
+                    clazz = (Class) m_wiring.findClassOrResourceByDelegation(name, true);
                 }
                 catch (ResourceNotFoundException ex)
                 {
@@ -1850,10 +1995,9 @@ public class BundleWiringImpl implements BundleWiring
                 catch (ClassNotFoundException cnfe)
                 {
                     ClassNotFoundException ex = cnfe;
-                    String msg = name;
-                    if (m_logger.getLogLevel() >= Logger.LOG_DEBUG)
+                    if (m_wiring.m_logger.getLogLevel() >= Logger.LOG_DEBUG)
                     {
-                        msg = diagnoseClassLoadError(m_resolver, m_revision, name);
+                        String msg = diagnoseClassLoadError(m_wiring.m_resolver, m_wiring.m_revision, name);
                         ex = (msg != null)
                             ? new ClassNotFoundException(msg, cnfe)
                             : ex;
@@ -1875,6 +2019,21 @@ public class BundleWiringImpl implements BundleWiring
         {
             Class clazz = null;
 
+            // Do a quick check to try to avoid searching for classes on a
+            // disposed class loader, which will avoid some odd exception.
+            // This won't prevent all weird exception, since the wiring could
+            // still get disposed of after this check, but it will prevent
+            // some, perhaps.
+            if (m_wiring.m_isDisposed)
+            {
+                throw new ClassNotFoundException(
+                    "Unable to load class '"
+                    + name
+                    + "' because the bundle wiring for "
+                    + m_wiring.m_revision.getSymbolicName()
+                    + " is no longer valid.");
+            }
+
             // Search for class in bundle revision.
             if (clazz == null)
             {
@@ -1883,7 +2042,7 @@ public class BundleWiringImpl implements BundleWiring
                 byte[] bytes = null;
 
                 // Check the bundle class path.
-                List<Content> contentPath = m_revision.getContentPath();
+                List<Content> contentPath = m_wiring.m_revision.getContentPath();
                 Content content = null;
                 for (int i = 0;
                     (bytes == null) &&
@@ -1905,14 +2064,14 @@ public class BundleWiringImpl implements BundleWiring
                     // or removal, we just get a snapshot and leave any changes
                     // as a race condition, doing any necessary clean up in
                     // the error handling.
-                    Felix felix = ((BundleImpl) m_revision.getBundle()).getFramework();
+                    Felix felix = ((BundleImpl) m_wiring.m_revision.getBundle()).getFramework();
                     Set<ServiceReference<WeavingHook>> hooks =
                         felix.getHooks(WeavingHook.class);
                     WovenClassImpl wci = null;
                     if (!hooks.isEmpty())
                     {
                         // Create woven class to be used for hooks.
-                        wci = new WovenClassImpl(name, BundleWiringImpl.this, bytes);
+                        wci = new WovenClassImpl(name, m_wiring, bytes);
                         // Loop through hooks in service ranking order.
                         for (ServiceReference<WeavingHook> sr : hooks)
                         {
@@ -1928,7 +2087,7 @@ public class BundleWiringImpl implements BundleWiring
                                 {
                                     try
                                     {
-                                        m_revision.getSecureAction()
+                                        BundleRevisionImpl.getSecureAction()
                                             .invokeWeavingHook(wh, wci);
                                     }
                                     catch (Throwable th)
@@ -1961,201 +2120,232 @@ public class BundleWiringImpl implements BundleWiring
                     // Before we actually attempt to define the class, grab
                     // the lock for this class loader and make sure than no
                     // other thread has defined this class in the meantime.
-                    synchronized (this)
+                    Object lock = (isParallel()) ? m_classLocks : this;
+                    synchronized (lock)
                     {
-                        byte[] wovenBytes = null;
-                        Class wovenClass = null;
-                        List<String> wovenImports = null;
-                        try
+                        Thread me = Thread.currentThread();
+                        while (m_classLocks.containsKey(name) && (m_classLocks.get(name) != me))
                         {
-                            clazz = findLoadedClass(name);
-                            if (clazz == null)
+                            try
+                            {
+                                lock.wait();
+                            }
+                            catch (InterruptedException e)
+                            {
+                                // TODO: WHAT TO DO HERE?
+                                throw new RuntimeException(e);
+                            }
+                        }
+                        // Lock released, try loading class.
+                        clazz = findLoadedClass(name);
+                        if (clazz == null)
+                        {
+                            // Not found, we should try load it.
+                            m_classLocks.put(name, me);
+                        }
+                    }
+
+                    byte[] wovenBytes = null;
+                    Class wovenClass = null;
+                    List<String> wovenImports = null;
+                    try
+                    {
+                        if (clazz == null)
+                        {
+                            // If we have a woven class then get the class bytes from
+                            // it since they may have changed.
+                            // NOTE: We are taking a snapshot of these values and
+                            // are not preventing a malbehaving weaving hook from
+                            // modifying them after the fact. The price of preventing
+                            // this isn't worth it, since they can already wreck
+                            // havoc via weaving anyway. However, we do pass the
+                            // snapshot values into the woven class when we mark it
+                            // as complete so that it will refect the actual values
+                            // we used to define the class.
+                            if (wci != null)
                             {
-                                // If we have a woven class then get the class bytes from
-                                // it since they may have changed.
-                                // NOTE: We are taking a snapshot of these values and
-                                // are not preventing a malbehaving weaving hook from
-                                // modifying them after the fact. The price of preventing
-                                // this isn't worth it, since they can already wreck
-                                // havoc via weaving anyway. However, we do pass the
-                                // snapshot values into the woven class when we mark it
-                                // as complete so that it will refect the actual values
-                                // we used to define the class.
-                                if (wci != null)
+                                bytes = wovenBytes = wci._getBytes();
+                                wovenImports = wci.getDynamicImportsInternal();
+
+                                // Try to add any woven dynamic imports, since they
+                                // could potentially be needed when defining the class.
+                                List<BundleRequirement> allWovenReqs =
+                                    new ArrayList<BundleRequirement>();
+                                for (String s : wovenImports)
                                 {
-                                    bytes = wovenBytes = wci._getBytes();
-                                    wovenImports = wci.getDynamicImportsInternal();
-
-                                    // Try to add any woven dynamic imports, since they
-                                    // could potentially be needed when defining the class.
-                                    List<BundleRequirement> allWovenReqs =
-                                        new ArrayList<BundleRequirement>();
-                                    for (String s : wovenImports)
+                                    try
                                     {
-                                        try
-                                        {
-                                            List<BundleRequirement> wovenReqs =
-                                                ManifestParser.parseDynamicImportHeader(
-                                                    m_logger, m_revision, s);
-                                            allWovenReqs.addAll(wovenReqs);
-                                        }
-                                        catch (BundleException ex)
+                                        List<BundleRequirement> wovenReqs =
+                                            ManifestParser.parseDynamicImportHeader(
+                                                m_wiring.m_logger, m_wiring.m_revision, s);
+                                        allWovenReqs.addAll(wovenReqs);
+                                    }
+                                    catch (BundleException ex)
+                                    {
+                                        // There should be no exception here
+                                        // since we checked syntax before adding
+                                        // dynamic import strings to list.
+                                    }
+                                }
+                                // Add the dynamic requirements.
+                                if (!allWovenReqs.isEmpty())
+                                {
+                                    // Check for duplicate woven imports.
+                                    // First grab existing woven imports, if any.
+                                    Set<String> filters = new HashSet<String>();
+                                    if (m_wiring.m_wovenReqs != null)
+                                    {
+                                        for (BundleRequirement req : m_wiring.m_wovenReqs)
                                         {
-                                            // There should be no exception here
-                                            // since we checked syntax before adding
-                                            // dynamic import strings to list.
+                                            filters.add(
+                                                ((BundleRequirementImpl) req)
+                                                    .getFilter().toString());
                                         }
-                                     }
-                                    // Add the dynamic requirements.
-                                    if (!allWovenReqs.isEmpty())
+                                    }
+                                    // Then check new woven imports for duplicates
+                                    // against existing and self.
+                                    int idx = allWovenReqs.size();
+                                    while (idx < allWovenReqs.size())
                                     {
-                                        // Check for duplicate woven imports.
-                                        // First grab existing woven imports, if any.
-                                        Set<String> filters = new HashSet<String>();
-                                        if (m_wovenReqs != null)
+                                        BundleRequirement wovenReq = allWovenReqs.get(idx);
+                                        String filter = ((BundleRequirementImpl)
+                                            wovenReq).getFilter().toString();
+                                        if (!filters.contains(filter))
                                         {
-                                            for (BundleRequirement req : m_wovenReqs)
-                                            {
-                                                filters.add(
-                                                    ((BundleRequirementImpl) req)
-                                                        .getFilter().toString());
-                                            }
+                                            filters.add(filter);
+                                            idx++;
                                         }
-                                        // Then check new woven imports for duplicates
-                                        // against existing and self.
-                                        int idx = allWovenReqs.size();
-                                        while (idx < allWovenReqs.size())
+                                        else
                                         {
-                                            BundleRequirement wovenReq = allWovenReqs.get(idx);
-                                            String filter = ((BundleRequirementImpl)
-                                                wovenReq).getFilter().toString();
-                                            if (!filters.contains(filter))
-                                            {
-                                                filters.add(filter);
-                                                idx++;
-                                            }
-                                            else
-                                            {
-                                                allWovenReqs.remove(idx);
-                                            }
+                                            allWovenReqs.remove(idx);
                                         }
-                                        // Merge existing with new imports, if any.
-                                        if (!allWovenReqs.isEmpty())
+                                    }
+                                    // Merge existing with new imports, if any.
+                                    if (!allWovenReqs.isEmpty())
+                                    {
+                                        if (m_wiring.m_wovenReqs != null)
                                         {
-                                            if (m_wovenReqs != null)
-                                            {
-                                                allWovenReqs.addAll(0, m_wovenReqs);
-                                            }
-                                            m_wovenReqs = allWovenReqs;
+                                            allWovenReqs.addAll(0, m_wiring.m_wovenReqs);
                                         }
+                                        m_wiring.m_wovenReqs = allWovenReqs;
                                     }
                                 }
+                            }
 
-                                int activationPolicy =
-                                    ((BundleImpl) getBundle()).isDeclaredActivationPolicyUsed()
+                            int activationPolicy =
+                                ((BundleImpl) getBundle()).isDeclaredActivationPolicyUsed()
                                     ? ((BundleRevisionImpl) getBundle()
                                         .adapt(BundleRevision.class)).getDeclaredActivationPolicy()
                                     : EAGER_ACTIVATION;
 
-                                // If the revision is using deferred activation, then if
-                                // we load this class from this revision we need to activate
-                                // the bundle before returning the class. We will short
-                                // circuit the trigger matching if the trigger is already
-                                // tripped.
-                                boolean isTriggerClass = m_isActivationTriggered
-                                    ? false : m_revision.isActivationTrigger(pkgName);
-                                if (!m_isActivationTriggered
-                                    && isTriggerClass
-                                    && (activationPolicy == BundleRevisionImpl.LAZY_ACTIVATION)
-                                    && (getBundle().getState() == Bundle.STARTING))
+                            // If the revision is using deferred activation, then if
+                            // we load this class from this revision we need to activate
+                            // the bundle before returning the class. We will short
+                            // circuit the trigger matching if the trigger is already
+                            // tripped.
+                            boolean isTriggerClass = m_isActivationTriggered
+                                ? false : m_wiring.m_revision.isActivationTrigger(pkgName);
+                            if (!m_isActivationTriggered
+                                && isTriggerClass
+                                && (activationPolicy == BundleRevisionImpl.LAZY_ACTIVATION)
+                                && (getBundle().getState() == Bundle.STARTING))
+                            {
+                                List deferredList = (List) m_deferredActivation.get();
+                                if (deferredList == null)
                                 {
-                                    List deferredList = (List) m_deferredActivation.get();
-                                    if (deferredList == null)
-                                    {
-                                        deferredList = new ArrayList();
-                                        m_deferredActivation.set(deferredList);
-                                    }
-                                    deferredList.add(new Object[] { name, getBundle() });
+                                    deferredList = new ArrayList();
+                                    m_deferredActivation.set(deferredList);
                                 }
-                                // We need to try to define a Package object for the class
-                                // before we call defineClass() if we haven't already
-                                // created it.
-                                if (pkgName.length() > 0)
+                                deferredList.add(new Object[] { name, getBundle() });
+                            }
+                            // We need to try to define a Package object for the class
+                            // before we call defineClass() if we haven't already
+                            // created it.
+                            if (pkgName.length() > 0)
+                            {
+                                if (getPackage(pkgName) == null)
                                 {
-                                    if (getPackage(pkgName) == null)
-                                    {
-                                        Object[] params = definePackage(pkgName);
-                                        if (params != null)
-                                        {
-                                            definePackage(
-                                                pkgName,
-                                                (String) params[0],
-                                                (String) params[1],
-                                                (String) params[2],
-                                                (String) params[3],
-                                                (String) params[4],
-                                                (String) params[5],
-                                                null);
-                                        }
-                                        else
-                                        {
-                                            definePackage(pkgName, null, null,
-                                                null, null, null, null, null);
-                                        }
-                                    }
-                                }
+                                    Object[] params = definePackage(pkgName);
 
-                                // If we can load the class from a dex file do so
-                                if (content instanceof JarContent)
-                                {
+                                    // This is a harmless check-then-act situation,
+                                    // where threads might be racing to create different
+                                    // classes in the same package, so catch and ignore
+                                    // any IAEs that may occur.
                                     try
                                     {
-                                        clazz = getDexFileClass((JarContent) content, name, this);
+                                        definePackage(
+                                            pkgName,
+                                            (String) params[0],
+                                            (String) params[1],
+                                            (String) params[2],
+                                            (String) params[3],
+                                            (String) params[4],
+                                            (String) params[5],
+                                            null);
                                     }
-                                    catch (Exception ex)
+                                    catch (IllegalArgumentException ex)
                                     {
-                                        // Looks like we can't
+                                        // Ignore.
                                     }
                                 }
+                            }
 
-                                if (clazz == null)
+                            // If we can load the class from a dex file do so
+                            if (content instanceof JarContent)
+                            {
+                                try
                                 {
-                                    // If we have a security context, then use it to
-                                    // define the class with it for security purposes,
-                                    // otherwise define the class without a protection domain.
-                                    if (m_revision.getProtectionDomain() != null)
-                                    {
-                                        clazz = defineClass(name, bytes, 0, bytes.length,
-                                            m_revision.getProtectionDomain());
-                                    }
-                                    else
-                                    {
-                                        clazz = defineClass(name, bytes, 0, bytes.length);
-                                    }
-
-                                    wovenClass = clazz;
+                                    clazz = getDexFileClass((JarContent) content, name, this);
+                                }
+                                catch (Exception ex)
+                                {
+                                    // Looks like we can't
                                 }
+                            }
 
-                                // At this point if we have a trigger class, then the deferred
-                                // activation trigger has tripped.
-                                if (!m_isActivationTriggered && isTriggerClass && (clazz != null))
+                            if (clazz == null)
+                            {
+                                // If we have a security context, then use it to
+                                // define the class with it for security purposes,
+                                // otherwise define the class without a protection domain.
+                                if (m_wiring.m_revision.getProtectionDomain() != null)
+                                {
+                                    clazz = defineClass(name, bytes, 0, bytes.length,
+                                        m_wiring.m_revision.getProtectionDomain());
+                                }
+                                else
                                 {
-                                    m_isActivationTriggered = true;
+                                    clazz = defineClass(name, bytes, 0, bytes.length);
                                 }
+
+                                wovenClass = clazz;
                             }
-                        }
-                        finally
-                        {
-                            // If we have a woven class, mark it as complete.
-                            // Not exactly clear how we should deal with the
-                            // case where the weaving didn't happen because
-                            // someone else beat us in defining the class.
-                            if (wci != null)
+
+                            // At this point if we have a trigger class, then the deferred
+                            // activation trigger has tripped.
+                            if (!m_isActivationTriggered && isTriggerClass && (clazz != null))
                             {
-                                wci.complete(wovenClass, wovenBytes, wovenImports);
+                                m_isActivationTriggered = true;
                             }
                         }
                     }
+                    finally
+                    {
+                        // If we have a woven class, mark it as complete.
+                        // Not exactly clear how we should deal with the
+                        // case where the weaving didn't happen because
+                        // someone else beat us in defining the class.
+                        if (wci != null)
+                        {
+                            wci.complete(wovenClass, wovenBytes, wovenImports);
+                        }
+
+                        synchronized (lock)
+                        {
+                            m_classLocks.remove(name);
+                            lock.notifyAll();
+                        }
+                    }
 
                     // Perform deferred activation without holding the class loader lock,
                     // if the class we are returning is the instigating class.
@@ -2164,19 +2354,26 @@ public class BundleWiringImpl implements BundleWiring
                         && (deferredList.size() > 0)
                         && ((Object[]) deferredList.get(0))[0].equals(name))
                     {
-                        for (int i = deferredList.size() - 1; i >= 0; i--)
+                        // Null the deferred list.
+                        m_deferredActivation.set(null);
+                        while (!deferredList.isEmpty())
                         {
+                            // Lazy bundles should be activated in the reverse order
+                            // of when they were added to the deferred list, so grab
+                            // them from the end of the deferred list.
+                            Object[] lazy = (Object[]) deferredList.remove(deferredList.size() - 1);
                             try
                             {
-                                felix.getFramework().activateBundle(
-                                    (BundleImpl) ((Object[]) deferredList.get(i))[1], true);
+                                felix.getFramework().activateBundle((BundleImpl) (lazy)[1], true);
                             }
-                            catch (BundleException ex)
+                            catch (Throwable ex)
                             {
-                                ex.printStackTrace();
+                                m_wiring.m_logger.log((BundleImpl) (lazy)[1],
+                                    Logger.LOG_WARNING,
+                                    "Unable to lazily start bundle.",
+                                    ex);
                             }
                         }
-                        deferredList.clear();
                     }
                 }
             }
@@ -2186,12 +2383,12 @@ public class BundleWiringImpl implements BundleWiring
 
         private Object[] definePackage(String pkgName)
         {
-            String spectitle = (String) m_revision.getHeaders().get("Specification-Title");
-            String specversion = (String) m_revision.getHeaders().get("Specification-Version");
-            String specvendor = (String) m_revision.getHeaders().get("Specification-Vendor");
-            String impltitle = (String) m_revision.getHeaders().get("Implementation-Title");
-            String implversion = (String) m_revision.getHeaders().get("Implementation-Version");
-            String implvendor = (String) m_revision.getHeaders().get("Implementation-Vendor");
+            String spectitle = (String) m_wiring.m_revision.getHeaders().get("Specification-Title");
+            String specversion = (String) m_wiring.m_revision.getHeaders().get("Specification-Version");
+            String specvendor = (String) m_wiring.m_revision.getHeaders().get("Specification-Vendor");
+            String impltitle = (String) m_wiring.m_revision.getHeaders().get("Implementation-Title");
+            String implversion = (String) m_wiring.m_revision.getHeaders().get("Implementation-Version");
+            String implvendor = (String) m_wiring.m_revision.getHeaders().get("Implementation-Vendor");
             if ((spectitle != null)
                 || (specversion != null)
                 || (specvendor != null)
@@ -2203,7 +2400,7 @@ public class BundleWiringImpl implements BundleWiring
                     spectitle, specversion, specvendor, impltitle, implversion, implvendor
                 };
             }
-            return null;
+            return new Object[] {null, null, null, null, null, null};
         }
 
         private Class getDexFileClass(JarContent content, String name, ClassLoader loader)
@@ -2253,8 +2450,8 @@ public class BundleWiringImpl implements BundleWiring
         @Override
         public URL getResource(String name)
         {
-            URL url = BundleWiringImpl.this.getResourceByDelegation(name);
-            if (m_useLocalURLs)
+            URL url = m_wiring.getResourceByDelegation(name);
+            if (m_wiring.m_useLocalURLs)
             {
                 url = convertToLocalUrl(url);
             }
@@ -2264,7 +2461,7 @@ public class BundleWiringImpl implements BundleWiring
         @Override
         protected URL findResource(String name)
         {
-            return m_revision.getResourceLocal(name);
+            return m_wiring.m_revision.getResourceLocal(name);
         }
 
         // The findResources() method should only look at the revision itself, but
@@ -2275,8 +2472,8 @@ public class BundleWiringImpl implements BundleWiring
         @Override
         protected Enumeration findResources(String name)
         {
-            Enumeration urls = BundleWiringImpl.this.getResourcesByDelegation(name);
-            if (m_useLocalURLs)
+            Enumeration urls = m_wiring.getResourcesByDelegation(name);
+            if (m_wiring.m_useLocalURLs)
             {
                 urls = new ToLocalUrlEnumeration(urls);
             }
@@ -2311,21 +2508,21 @@ public class BundleWiringImpl implements BundleWiring
                 // native library.
                 if (result == null)
                 {
-                    List<R4Library> libs = getNativeLibraries();
+                    List<R4Library> libs = m_wiring.getNativeLibraries();
                     for (int libIdx = 0; (libs != null) && (libIdx < libs.size()); libIdx++)
                     {
-                        if (libs.get(libIdx).match(m_configMap, name))
+                        if (libs.get(libIdx).match(m_wiring.m_configMap, name))
                         {
                             // Search bundle content first for native library.
-                            result = m_revision.getContent().getEntryAsNativeLibrary(
+                            result = m_wiring.m_revision.getContent().getEntryAsNativeLibrary(
                                 libs.get(libIdx).getEntryName());
                             // If not found, then search fragments in order.
                             for (int i = 0;
-                                (result == null) && (m_fragmentContents != null)
-                                    && (i < m_fragmentContents.size());
+                                (result == null) && (m_wiring.m_fragmentContents != null)
+                                    && (i < m_wiring.m_fragmentContents.size());
                                 i++)
                             {
-                                result = m_fragmentContents.get(i).getEntryAsNativeLibrary(
+                                result = m_wiring.m_fragmentContents.get(i).getEntryAsNativeLibrary(
                                     libs.get(libIdx).getEntryName());
                             }
                         }
@@ -2348,7 +2545,7 @@ public class BundleWiringImpl implements BundleWiring
         @Override
         public String toString()
         {
-            return BundleWiringImpl.this.toString();
+            return m_wiring.toString();
         }
     }
 
@@ -2527,7 +2724,7 @@ public class BundleWiringImpl implements BundleWiring
                 BundleRevision.PACKAGE_NAMESPACE, (Object) pkgName);
             BundleRequirementImpl req = new BundleRequirementImpl(
                 revision, BundleRevision.PACKAGE_NAMESPACE, dirs, attrs);
-            Set<BundleCapability> exporters = resolver.getCandidates(req, false);
+            List<BundleCapability> exporters = resolver.findProviders(req, false);
 
             BundleRevision provider = null;
             try
@@ -2566,7 +2763,7 @@ public class BundleWiringImpl implements BundleWiring
             BundleRevision.PACKAGE_NAMESPACE, (Object) pkgName);
         BundleRequirementImpl req = new BundleRequirementImpl(
             revision, BundleRevision.PACKAGE_NAMESPACE, dirs, attrs);
-        Set<BundleCapability> exports = resolver.getCandidates(req, false);
+        List<BundleCapability> exports = resolver.findProviders(req, false);
         if (exports.size() > 0)
         {
             boolean classpath = false;
diff --git a/src/main/java/org/apache/felix/framework/ExtensionManager.java b/src/main/java/org/apache/felix/framework/ExtensionManager.java
index 1b3e2e6..002cea3 100644
--- a/src/main/java/org/apache/felix/framework/ExtensionManager.java
+++ b/src/main/java/org/apache/felix/framework/ExtensionManager.java
@@ -24,7 +24,6 @@ import java.io.InputStream;
 import java.net.URL;
 import java.net.URLConnection;
 import java.net.URLStreamHandler;
-import java.security.AccessControlException;
 import java.security.AllPermission;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -37,8 +36,8 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.NoSuchElementException;
 import java.util.Set;
-
 import org.apache.felix.framework.util.FelixConstants;
+import org.apache.felix.framework.util.ImmutableList;
 import org.apache.felix.framework.util.StringMap;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.manifestparser.ManifestParser;
@@ -121,7 +120,7 @@ class ExtensionManager extends URLStreamHandler implements Content
 
     private final Logger m_logger;
     private final Map m_configMap;
-    private final Map m_headerMap = new StringMap(false);
+    private final Map m_headerMap = new StringMap();
     private final BundleRevision m_systemBundleRevision;
     private volatile List<BundleCapability> m_capabilities = Collections.EMPTY_LIST;
     private volatile Set<String> m_exportNames = Collections.EMPTY_SET;
@@ -194,7 +193,8 @@ class ExtensionManager extends URLStreamHandler implements Content
         // If any extra packages are specified, then append them.
         String pkgextra =
             (String) m_configMap.get(FelixConstants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
-        syspkgs = (pkgextra == null) ? syspkgs : syspkgs + "," + pkgextra;
+        syspkgs = ((pkgextra == null) || (pkgextra.trim().length() == 0))
+            ? syspkgs : syspkgs + "," + pkgextra;
         m_headerMap.put(FelixConstants.BUNDLE_MANIFESTVERSION, "2");
         m_headerMap.put(FelixConstants.EXPORT_PACKAGE, syspkgs);
 
@@ -213,7 +213,8 @@ class ExtensionManager extends URLStreamHandler implements Content
         // If any extra capabilities are specified, then append them.
         String capextra =
             (String) m_configMap.get(FelixConstants.FRAMEWORK_SYSTEMCAPABILITIES_EXTRA);
-        syscaps = (capextra == null) ? syscaps : syscaps + "," + capextra;
+        syscaps = ((capextra == null) || (capextra.trim().length() == 0))
+            ? syscaps : syscaps + "," + capextra;
         m_headerMap.put(FelixConstants.PROVIDE_CAPABILITY, syscaps);
         try
         {
@@ -241,10 +242,34 @@ class ExtensionManager extends URLStreamHandler implements Content
 
         List<BundleCapability> aliasCaps = new ArrayList<BundleCapability>(caps);
 
+        String[] aliases = {
+            FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME,
+            Constants.SYSTEM_BUNDLE_SYMBOLICNAME };
+
         for (int capIdx = 0; capIdx < aliasCaps.size(); capIdx++)
         {
-            // Get the attributes and search for bundle symbolic name.
-            for (Entry<String, Object> entry : aliasCaps.get(capIdx).getAttributes().entrySet())
+            BundleCapability cap = aliasCaps.get(capIdx);
+
+            // Need to alias bundle and host capabilities.
+            if (cap.getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE)
+                || cap.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
+            {
+                // Make a copy of the attribute array.
+                Map<String, Object> aliasAttrs =
+                    new HashMap<String, Object>(cap.getAttributes());
+                // Add the aliased value.
+                aliasAttrs.put(cap.getNamespace(), aliases);
+                // Create the aliased capability to replace the old capability.
+                cap = new BundleCapabilityImpl(
+                    cap.getRevision(),
+                    cap.getNamespace(),
+                    cap.getDirectives(),
+                    aliasAttrs);
+                aliasCaps.set(capIdx, cap);
+            }
+
+            // Further, search attributes for bundle symbolic name and alias it too.
+            for (Entry<String, Object> entry : cap.getAttributes().entrySet())
             {
                 // If there is a bundle symbolic name attribute, add the
                 // standard alias as a value.
@@ -252,18 +277,14 @@ class ExtensionManager extends URLStreamHandler implements Content
                 {
                     // Make a copy of the attribute array.
                     Map<String, Object> aliasAttrs =
-                        new HashMap<String, Object>(aliasCaps.get(capIdx).getAttributes());
+                        new HashMap<String, Object>(cap.getAttributes());
                     // Add the aliased value.
-                    aliasAttrs.put(
-                        Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE,
-                        new String[] {
-                            (String) entry.getValue(),
-                            Constants.SYSTEM_BUNDLE_SYMBOLICNAME});
+                    aliasAttrs.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, aliases);
                     // Create the aliased capability to replace the old capability.
                     aliasCaps.set(capIdx, new BundleCapabilityImpl(
-                        caps.get(capIdx).getRevision(),
-                        caps.get(capIdx).getNamespace(),
-                        caps.get(capIdx).getDirectives(),
+                        cap.getRevision(),
+                        cap.getNamespace(),
+                        cap.getDirectives(),
                         aliasAttrs));
                     // Continue with the next capability.
                     break;
@@ -309,13 +330,13 @@ class ExtensionManager extends URLStreamHandler implements Content
         Object sm = System.getSecurityManager();
         if (sm != null)
         {
-                ((SecurityManager) sm).checkPermission(
-                    new AdminPermission(bundle, AdminPermission.EXTENSIONLIFECYCLE));
-        }
+            ((SecurityManager) sm).checkPermission(
+                new AdminPermission(bundle, AdminPermission.EXTENSIONLIFECYCLE));
 
-        if (!((BundleProtectionDomain) bundle.getProtectionDomain()).impliesDirect(new AllPermission()))
-        {
-            throw new SecurityException("Extension Bundles must have AllPermission");
+            if (!((BundleProtectionDomain) bundle.getProtectionDomain()).impliesDirect(new AllPermission()))
+            {
+                throw new SecurityException("Extension Bundles must have AllPermission");
+            }
         }
 
         String directive = ManifestParser.parseExtensionBundleHeader((String)
@@ -474,7 +495,7 @@ class ExtensionManager extends URLStreamHandler implements Content
             new ArrayList<BundleCapability>(m_capabilities.size() + caps.size());
         newCaps.addAll(m_capabilities);
         newCaps.addAll(caps);
-        m_capabilities = Collections.unmodifiableList(newCaps);
+        m_capabilities = ImmutableList.newInstance(newCaps);
         m_headerMap.put(Constants.EXPORT_PACKAGE, convertCapabilitiesToHeaders(m_headerMap));
     }
 
@@ -578,6 +599,7 @@ class ExtensionManager extends URLStreamHandler implements Content
             };
     }
 
+    @Override
     protected InetAddress getHostAddress(URL u)
     {
         // the extension URLs do not address real hosts
diff --git a/src/main/java/org/apache/felix/framework/Felix.java b/src/main/java/org/apache/felix/framework/Felix.java
index 3847b51..d670d78 100644
--- a/src/main/java/org/apache/felix/framework/Felix.java
+++ b/src/main/java/org/apache/felix/framework/Felix.java
@@ -18,11 +18,11 @@
  */
 package org.apache.felix.framework;
 
-import org.osgi.framework.launch.Framework;
 import java.io.*;
 import java.net.*;
 import java.security.*;
 import java.util.*;
+
 import org.apache.felix.framework.BundleWiringImpl.BundleClassLoader;
 import org.apache.felix.framework.ServiceRegistry.ServiceRegistryCallbacks;
 import org.apache.felix.framework.cache.BundleArchive;
@@ -63,6 +63,7 @@ import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServicePermission;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.launch.Framework;
 import org.osgi.framework.startlevel.FrameworkStartLevel;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRevision;
@@ -170,6 +171,9 @@ public class Felix extends BundleImpl implements Framework
     // Security Manager created by the framework
     private SecurityManager m_securityManager = null;
 
+    // Do we need to consult the default java security policy if no security provider is present?
+    private volatile boolean m_securityDefaultPolicy;
+
     /**
      * <p>
      * This constructor creates a framework instance with a specified <tt>Map</tt>
@@ -283,6 +287,11 @@ public class Felix extends BundleImpl implements Framework
      *       unsupported fragment bundles throws an exception or logs a warning.
      *       Possible values are "<tt>exception</tt>" or "<tt>warning</tt>". The
      *       default value is "<tt>exception</tt>".
+     *   </li>
+     *   <li><tt>felix.security.defaultpolicy</tt> - Flag to indicate whether
+     *       to consult the default java securtiy policy if no security extension
+     *       is present. The default value is "<tt>false</tt>".
+     *   </li>
      * </ul>
      * <p>
      * The <a href="Main.html"><tt>Main</tt></a> class implements some
@@ -305,7 +314,7 @@ public class Felix extends BundleImpl implements Framework
     {
         super();
         // Copy the configuration properties; convert keys to strings.
-        m_configMutableMap = new StringMap(false);
+        m_configMutableMap = new StringMap();
         if (configMap != null)
         {
             for (Iterator i = configMap.entrySet().iterator(); i.hasNext(); )
@@ -363,6 +372,9 @@ public class Felix extends BundleImpl implements Framework
             m_bootPkgs[i] = s;
         }
 
+        // Read the security default policy property
+        m_securityDefaultPolicy = "true".equals(getProperty(FelixConstants.SECURITY_DEFAULT_POLICY));
+
         // Create default bundle stream handler.
         m_bundleStreamHandler = new URLHandlersBundleStreamHandler(this);
 
@@ -473,7 +485,12 @@ public class Felix extends BundleImpl implements Framework
     public <A> A adapt(Class<A> type)
     {
         checkAdapt(type);
-        if ((type == FrameworkWiring.class)
+        if ((type == Framework.class)
+            || (type == Felix.class))
+        {
+            return (A) this;
+        }
+        else if ((type == FrameworkWiring.class)
             || (type == FrameworkWiringImpl.class))
         {
             return (A) m_fwkWiring;
@@ -699,6 +716,10 @@ public class Felix extends BundleImpl implements Framework
                     archives = null;
                 }
 
+                // Create system bundle activator and bundle context so we can activate it.
+                setActivator(new SystemBundleActivator());
+                setBundleContext(new BundleContextImpl(m_logger, this, this));
+
                 // Now load all cached bundles.
                 for (int i = 0; (archives != null) && (i < archives.length); i++)
                 {
@@ -759,9 +780,10 @@ public class Felix extends BundleImpl implements Framework
                 // so create a gate for that purpose.
                 m_shutdownGate = new ThreadGate();
 
-                // Create system bundle activator and bundle context so we can activate it.
-                setActivator(new SystemBundleActivator());
-                setBundleContext(new BundleContextImpl(m_logger, this, this));
+                // Start services
+                m_fwkWiring.start();
+                m_fwkStartLevel.start();
+
                 try
                 {
                     Felix.m_secureAction.startActivator(
@@ -778,6 +800,53 @@ public class Felix extends BundleImpl implements Framework
                 // its bundle context to the logger so that it can track log services.
                 m_logger.setSystemBundleContext(_getBundleContext());
 
+                // We have to check with the security provider (if there is one).
+                // This is to avoid having bundles in the cache that have been tampered with
+                SecurityProvider sp = getFramework().getSecurityProvider();
+                if ((sp != null) && (System.getSecurityManager() != null))
+                {
+                    boolean locked = acquireGlobalLock();
+                    if (!locked)
+                    {
+                        throw new BundleException(
+                            "Unable to acquire the global lock to check the bundle.");
+                    }
+                    try
+                    {
+                        for (Object bundle : m_installedBundles[IDENTIFIER_MAP_IDX].values())
+                        {
+                            try
+                            {
+                                if (bundle != this)
+                                {
+                                    setBundleProtectionDomain((BundleImpl) bundle, (BundleRevisionImpl) ((BundleImpl) bundle).adapt(BundleRevisionImpl.class));
+                                }
+                            }
+                            catch (Exception ex)
+                            {
+                                ((BundleImpl) bundle).close();
+                                maps = new Map[] {
+                                    new HashMap<String, BundleImpl>(m_installedBundles[LOCATION_MAP_IDX]),
+                                    new TreeMap<Long, BundleImpl>(m_installedBundles[IDENTIFIER_MAP_IDX])
+                                };
+                                maps[LOCATION_MAP_IDX].remove(((BundleImpl) bundle)._getLocation());
+                                maps[IDENTIFIER_MAP_IDX].remove(new Long(((BundleImpl) bundle).getBundleId()));
+                                m_installedBundles = maps;
+
+                                m_logger.log(
+                                    Logger.LOG_ERROR,
+                                    "Bundle in cache doesn't pass security check anymore.",
+                                    ex);
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        // Always release the global lock.
+                        releaseGlobalLock();
+                    }
+                }
+
                 // Clear the cache of classes coming from the system bundle.
                 // This is only used for Felix.getBundle(Class clazz) to speed
                 // up class lookup for the system bundle.
@@ -793,6 +862,20 @@ public class Felix extends BundleImpl implements Framework
         }
     }
 
+    void setBundleProtectionDomain(BundleImpl bundleImpl, BundleRevisionImpl revisionImpl) throws Exception
+    {
+        Object certificates = null;
+        SecurityProvider sp = getFramework().getSecurityProvider();
+        if ((sp != null) && (System.getSecurityManager() != null))
+        {
+            sp.checkBundle(bundleImpl);
+            Map signers = (Map) sp.getSignerMatcher(bundleImpl, Bundle.SIGNERS_TRUSTED);
+            certificates = signers.keySet().toArray(new java.security.cert.Certificate[0]);
+        }
+        revisionImpl.setProtectionDomain(
+            new BundleProtectionDomain(this, bundleImpl, certificates));
+    }
+
     /**
      * This method starts the framework instance, which will transition the
      * framework from start level 0 to its active start level as specified in
@@ -1056,7 +1139,7 @@ public class Felix extends BundleImpl implements Framework
     **/
     void setActiveStartLevel(int requestedLevel, FrameworkListener[] listeners)
     {
-        Bundle[] bundles = null;
+        Bundle[] bundles;
 
         // Record the target start level immediately and use this for
         // comparisons for starting/stopping bundles to avoid race
@@ -1078,17 +1161,13 @@ public class Felix extends BundleImpl implements Framework
             // This approach does mean that it is possible for a for individual
             // bundle states to change during this operation. If a bundle's start
             // level changes, then it is possible for it to be processed out of
-            // order. Uninstalled bundles are just logged andignored.
+            // order. Uninstalled bundles are just logged and ignored.
             //
             // Calls to this method are only made by the start level thread, which
             // serializes framework start level changes. Thus, it is not possible
             // for two requests to change the framework's start level to interfere
             // with each other.
 
-            // Determine if we are lowering or raising the
-            // active start level.
-            boolean lowering = (m_targetStartLevel < m_activeStartLevel);
-
             // Acquire global lock.
             boolean locked = acquireGlobalLock();
             if (!locked)
@@ -1127,13 +1206,27 @@ public class Felix extends BundleImpl implements Framework
                 releaseGlobalLock();
             }
 
+            // Determine if we are lowering or raising the
+            // active start level.
+            boolean isLowering = (m_targetStartLevel < m_activeStartLevel);
+            // Determine the range of start levels to process.
+            int low = (isLowering) ? m_targetStartLevel + 1 : m_activeStartLevel + 1;
+            int high = (isLowering) ? m_activeStartLevel : m_targetStartLevel;
+            m_activeStartLevel = (isLowering) ? high : low;
+
             // Process bundles and stop or start them accordingly.
             while (bundlesRemaining)
             {
                 StartLevelTuple tuple;
+
+                // Remove our tuple to be processed while holding the queue lock
+                // and update the active start level accordingly, which allows
+                // us to determine in startBundle() if concurrent requests to
+                // start a bundle should be handled synchronously or just added
+                // to the queue and handled asynchronously.
                 synchronized (m_startLevelBundles)
                 {
-                    if (lowering)
+                    if (isLowering)
                     {
                         tuple = m_startLevelBundles.last();
                     }
@@ -1141,6 +1234,11 @@ public class Felix extends BundleImpl implements Framework
                     {
                         tuple = m_startLevelBundles.first();
                     }
+
+                    if ((tuple.m_level >= low) && (tuple.m_level <= high))
+                    {
+                        m_activeStartLevel = tuple.m_level;
+                    }
                 }
 
                 // Ignore the system bundle, since its start() and
@@ -1165,22 +1263,30 @@ public class Felix extends BundleImpl implements Framework
                                 Logger.LOG_ERROR,
                                 "Error locking " + tuple.m_bundle._getLocation(), ex);
                         }
+                        else
+                        {
+                            synchronized (m_startLevelBundles)
+                            {
+                                m_startLevelBundles.remove(tuple);
+                                bundlesRemaining = !m_startLevelBundles.isEmpty();
+                            }
+                        }
                         continue;
                     }
 
                     try
                     {
                         // Start the bundle if necessary.
-                        if (((tuple.m_bundle.getPersistentState() == Bundle.ACTIVE)
-                            || (tuple.m_bundle.getPersistentState() == Bundle.STARTING))
-                            && (tuple.m_level <= m_targetStartLevel))
+                        // Note that we only attempt to start the bundle if
+                        // its start level is equal to the active start level,
+                        // which means we assume lower bundles are in the state
+                        // they should be in (i.e., we won't attempt to restart
+                        // them if they previously failed to start).
+                        if (!isLowering
+                            && (((tuple.m_bundle.getPersistentState() == Bundle.ACTIVE)
+                                || (tuple.m_bundle.getPersistentState() == Bundle.STARTING))
+                                && (tuple.m_level == m_activeStartLevel)))
                         {
-                            // Count up the active start level.
-                            if (m_activeStartLevel != tuple.m_level)
-                            {
-                                m_activeStartLevel = tuple.m_level;
-                            }
-
                             try
                             {
 // TODO: LAZY - Not sure if this is the best way...
@@ -1199,16 +1305,11 @@ public class Felix extends BundleImpl implements Framework
                             }
                         }
                         // Stop the bundle if necessary.
-                        else if (((tuple.m_bundle.getState() == Bundle.ACTIVE)
-                            || (tuple.m_bundle.getState() == Bundle.STARTING))
-                            && (tuple.m_level > m_targetStartLevel))
+                        else if (isLowering
+                            && (((tuple.m_bundle.getState() == Bundle.ACTIVE)
+                                || (tuple.m_bundle.getState() == Bundle.STARTING))
+                                && (tuple.m_level == m_activeStartLevel)))
                         {
-                            // Count down the active start level.
-                            if (m_activeStartLevel != tuple.m_level)
-                            {
-                                m_activeStartLevel = tuple.m_level;
-                            }
-
                             try
                             {
                                 stopBundle(tuple.m_bundle, false);
@@ -1493,13 +1594,16 @@ public class Felix extends BundleImpl implements Framework
         {
             return null;
         }
-        try
-        {
-            resolveBundleRevision(bundle.adapt(BundleRevision.class));
-        }
-        catch (Exception ex)
+        else if (bundle.getState() == Bundle.INSTALLED)
         {
-            // Ignore.
+            try
+            {
+                resolveBundleRevision(bundle.adapt(BundleRevision.class));
+            }
+            catch (Exception ex)
+            {
+                // Ignore.
+            }
         }
 
         // If the bundle revision isn't resolved, then just search
@@ -1529,13 +1633,16 @@ public class Felix extends BundleImpl implements Framework
         {
             return null;
         }
-        try
-        {
-            resolveBundleRevision(bundle.adapt(BundleRevision.class));
-        }
-        catch (Exception ex)
+        else if (bundle.getState() == Bundle.INSTALLED)
         {
-            // Ignore.
+            try
+            {
+                resolveBundleRevision(bundle.adapt(BundleRevision.class));
+            }
+            catch (Exception ex)
+            {
+                // Ignore.
+            }
         }
 
         if (bundle.adapt(BundleRevision.class).getWiring() == null)
@@ -1614,13 +1721,33 @@ public class Felix extends BundleImpl implements Framework
      * Implementation for Bundle.findEntries().
     **/
     Enumeration findBundleEntries(
-        BundleRevision revision, String path, String filePattern, boolean recurse)
+            BundleImpl bundle, String path, String filePattern, boolean recurse)
     {
-        // Try to resolve the bundle per the spec.
-        List<Bundle> list = new ArrayList<Bundle>(1);
-        list.add(revision.getBundle());
-        resolveBundles(list);
+        if (bundle.getState() == Bundle.UNINSTALLED)
+        {
+            throw new IllegalStateException("The bundle is uninstalled.");
+        }
+        else if (!Util.isFragment(bundle.adapt(BundleRevision.class)) && bundle.getState() == Bundle.INSTALLED)
+        {
+            try
+            {
+                resolveBundleRevision(bundle.adapt(BundleRevision.class));
+            }
+            catch (Exception ex)
+            {
+                // Ignore.
+            }
+        }
+        return findBundleEntries(
+                bundle.adapt(BundleRevision.class), path, filePattern, recurse);
+    }
 
+    /**
+     * Implementation for BundleWiring.findEntries().
+     **/
+    Enumeration findBundleEntries(
+        BundleRevision revision, String path, String filePattern, boolean recurse)
+    {
         // Get the entry enumeration from the revision content and
         // create a wrapper enumeration to filter it.
         Enumeration enumeration =
@@ -1737,6 +1864,7 @@ public class Felix extends BundleImpl implements Framework
         // bundles can be installed or uninstalled during the resolve.
 
         int eventType;
+        boolean isTransient = (options & Bundle.START_TRANSIENT) != 0;
 
         // Acquire bundle lock.
         try
@@ -1784,7 +1912,7 @@ public class Felix extends BundleImpl implements Framework
 
             // Set and save the bundle's persistent state to active
             // if we are supposed to record state change.
-            if ((options & Bundle.START_TRANSIENT) == 0)
+            if (!isTransient)
             {
                 if ((options & Bundle.START_ACTIVATION_POLICY) != 0)
                 {
@@ -1797,31 +1925,64 @@ public class Felix extends BundleImpl implements Framework
             }
 
             // Check to see if the bundle's start level is greater than the
-            // the framework's active start level.
+            // the framework's target start level and if so just return. For
+            // transient starts we compare their start level to the current
+            // active start level, since we never process transient starts
+            // asynchronously (i.e., they are either satisfied and process
+            // synchronously here or they throw an exception).
             int bundleLevel = bundle.getStartLevel(getInitialBundleStartLevel());
-            if (bundleLevel > m_targetStartLevel)
+            if (isTransient && (bundleLevel > m_activeStartLevel))
             {
                 // Throw an exception for transient starts.
-                if ((options & Bundle.START_TRANSIENT) != 0)
-                {
-                    throw new BundleException(
-                        "Cannot start bundle " + bundle + " because its start level is "
-                        + bundleLevel
-                        + ", which is greater than the framework's start level of "
-                        + m_targetStartLevel + ".");
-                }
-                // Ignore persistent starts.
+                throw new BundleException(
+                    "Cannot start bundle " + bundle + " because its start level is "
+                    + bundleLevel
+                    + ", which is greater than the framework's start level of "
+                    + m_activeStartLevel + ".");
+            }
+            else if (bundleLevel > m_targetStartLevel)
+            {
+                // Ignore persistent starts that are not satisfied.
                 return;
             }
 
-            // Check to see if there is a start level change in progress and if so
-            // add this bundle to the bundles being processed by the start level
-            // thread and return.
+            // Check to see if there is a start level change in progress and if
+            // so queue this bundle to the start level bundle queue for the start
+            // level thread and return, except for transient starts which are
+            // queued but processed synchronously.
+            // Note: Don't queue starts from the start level thread, otherwise
+            // we'd never get anything started.
             if (!Thread.currentThread().getName().equals(FrameworkStartLevelImpl.THREAD_NAME))
             {
                 synchronized (m_startLevelBundles)
                 {
-                    if (!m_startLevelBundles.isEmpty())
+                    // Since we have the start level queue lock, we know the
+                    // active start level cannot change. For transient starts
+                    // we now need to double check and make sure we can still
+                    // start them since technically the active start level could
+                    // have changed.
+                    if (isTransient && (bundleLevel > m_activeStartLevel))
+                    {
+                        throw new BundleException(
+                            "Cannot start bundle " + bundle + " because its start level is "
+                            + bundleLevel
+                            + ", which is greater than the framework's start level of "
+                            + m_activeStartLevel + ".");
+                    }
+
+                    // If the start level bundle queue is not empty, then we know
+                    // there is a start level operation ongoing. We know that the
+                    // bundle being started is satisfied by the target start level
+                    // otherwise we wouldn't be here. In most cases we simply want
+                    // to queue the bundle; however, if the bundle level is lower
+                    // than the current active start level, then we want to handle
+                    // it synchronously. This is because the start level thread
+                    // ignores bundles that it should have already processed.
+                    // So queue the bundle if its bundle start level is greater
+                    // or equal to the active start level and then simply return
+                    // since it will be processed asynchronously.
+                    if (!m_startLevelBundles.isEmpty()
+                        && (bundleLevel >= m_activeStartLevel))
                     {
                         // Only add the bundle to the start level bundles
                         // being process if it is not already there.
@@ -1833,15 +1994,29 @@ public class Felix extends BundleImpl implements Framework
                                 found = true;
                             }
                         }
+
                         if (!found)
                         {
-// TODO: STARTLEVEL - Technically, if a bundle is installed and started during a
-//       start level operation, then it will end up being queued for the start level
-//       thread even if its start level is met, when it potentially could have been
-//       started immediately.
                             m_startLevelBundles.add(new StartLevelTuple(bundle, bundleLevel));
                         }
-                        return;
+
+                        // Note that although we queued the transiently started
+                        // bundle, we don't return here because we handle all
+                        // transient bundles synchronously. The reason why we
+                        // queue it anyway is for the case where the start level
+                        // is lowering, since the transiently started bundle may
+                        // have already been processed by the start level thread
+                        // and we will start it briefly here synchronously, but
+                        // we want the start level thread to process it again
+                        // so it gets another chance to stop it. This is not an
+                        // issue when the start level is raising because the
+                        // start level thread ignores non-persistently started
+                        // bundles or if it is also persistently started it will
+                        // be a no-op.
+                        if (!isTransient)
+                        {
+                            return;
+                        }
                     }
                 }
             }
@@ -1933,7 +2108,7 @@ public class Felix extends BundleImpl implements Framework
     {
         // CONCURRENCY NOTE:
         // We will first acquire the bundle lock for the specific bundle
-        // as long as the bundle is STARTING or ACTIVE, shich is necessary
+        // as long as the bundle is STARTING or ACTIVE, which is necessary
         // because we may change the bundle state.
 
         // Acquire bundle lock.
@@ -2488,13 +2663,11 @@ public class Felix extends BundleImpl implements Framework
                     new TreeMap<Long, BundleImpl>(m_installedBundles[IDENTIFIER_MAP_IDX])
                 };
                 target = (BundleImpl) maps[LOCATION_MAP_IDX].remove(bundle._getLocation());
-                maps[IDENTIFIER_MAP_IDX].remove(new Long(target.getBundleId()));
-                m_installedBundles = maps;
-
-                // Put the uninstalled bundle into the uninstalled
-                // list for subsequent refreshing.
                 if (target != null)
                 {
+                    maps[IDENTIFIER_MAP_IDX].remove(new Long(target.getBundleId()));
+                    m_installedBundles = maps;
+
                     // Set the bundle's persistent state to uninstalled.
                     bundle.setPersistentStateUninstalled();
 
@@ -2617,7 +2790,7 @@ public class Felix extends BundleImpl implements Framework
             }
             try
             {
-                bundle = new BundleImpl(this, ba);
+                bundle = new BundleImpl(this, null, ba);
 
                 // Extensions are handled as a special case.
                 if (bundle.isExtension())
@@ -2729,7 +2902,7 @@ public class Felix extends BundleImpl implements Framework
                     }
                     try
                     {
-                        bundle = new BundleImpl(this, ba);
+                        bundle = new BundleImpl(this, origin, ba);
                     }
                     finally
                     {
@@ -3188,7 +3361,7 @@ public class Felix extends BundleImpl implements Framework
      * @return A <code>ServiceRegistration</code> object or null.
     **/
     ServiceRegistration registerService(
-        BundleImpl bundle, String[] classNames, Object svcObj, Dictionary dict)
+        BundleContextImpl context, String[] classNames, Object svcObj, Dictionary dict)
     {
         if (classNames == null)
         {
@@ -3199,51 +3372,32 @@ public class Felix extends BundleImpl implements Framework
             throw new IllegalArgumentException("Service object cannot be null.");
         }
 
-        // Acquire bundle lock.
-        try
-        {
-            acquireBundleLock(bundle, Bundle.STARTING | Bundle.ACTIVE | Bundle.STOPPING);
-        }
-        catch (IllegalStateException ex)
-        {
-            throw new IllegalStateException(
-                "Can only register services while bundle is active or activating.");
-        }
-
         ServiceRegistration reg = null;
 
-        try
+        // Check to make sure that the service object is
+        // an instance of all service classes; ignore if
+        // service object is a service factory.
+        if (!(svcObj instanceof ServiceFactory))
         {
-            // Check to make sure that the service object is
-            // an instance of all service classes; ignore if
-            // service object is a service factory.
-            if (!(svcObj instanceof ServiceFactory))
+            for (int i = 0; i < classNames.length; i++)
             {
-                for (int i = 0; i < classNames.length; i++)
+                Class clazz = Util.loadClassUsingClass(svcObj.getClass(), classNames[i], m_secureAction);
+                if (clazz == null)
                 {
-                    Class clazz = Util.loadClassUsingClass(svcObj.getClass(), classNames[i], m_secureAction);
-                    if (clazz == null)
-                    {
-                        throw new IllegalArgumentException(
-                            "Cannot cast service: " + classNames[i]);
-                    }
-                    else if (!clazz.isAssignableFrom(svcObj.getClass()))
-                    {
-                        throw new IllegalArgumentException(
-                            "Service object is not an instance of \""
-                            + classNames[i] + "\".");
-                    }
+                    throw new IllegalArgumentException(
+                        "Cannot cast service: " + classNames[i]);
+                }
+                else if (!clazz.isAssignableFrom(svcObj.getClass()))
+                {
+                    throw new IllegalArgumentException(
+                        "Service object is not an instance of \""
+                        + classNames[i] + "\".");
                 }
             }
-
-            reg = m_registry.registerService(bundle, classNames, svcObj, dict);
-        }
-        finally
-        {
-            // Always release bundle lock.
-            releaseBundleLock(bundle);
         }
 
+        reg = m_registry.registerService(context, classNames, svcObj, dict);
+
         // Check to see if this a listener hook; if so, then we need
         // to invoke the callback with all existing service listeners.
         if (ServiceRegistry.isHook(
@@ -3434,6 +3588,14 @@ public class Felix extends BundleImpl implements Framework
 
     File getDataFile(BundleImpl bundle, String s)
     {
+        if (bundle.getState() == Bundle.UNINSTALLED)
+        {
+            throw new IllegalStateException("Bundle has been uninstalled");
+        }
+        else if (Util.isFragment(adapt(BundleRevision.class)))
+        {
+            return null;
+        }
         try
         {
             if (bundle == this)
@@ -3556,7 +3718,7 @@ public class Felix extends BundleImpl implements Framework
             BundleRevision.PACKAGE_NAMESPACE,
             Collections.EMPTY_MAP,
             attrs);
-        Set<BundleCapability> exports = m_resolver.getCandidates(req, false);
+        List<BundleCapability> exports = m_resolver.findProviders(req, false);
 
         // We only want resolved capabilities.
         for (Iterator<BundleCapability> it = exports.iterator(); it.hasNext(); )
@@ -3883,11 +4045,16 @@ public class Felix extends BundleImpl implements Framework
             bundles = new HashSet<Bundle>();
             for (Bundle target : newTargets)
             {
-                // Add the current target bundle to the map of
-                // bundles to be refreshed.
-                bundles.add(target);
-                // Add all importing bundles to map.
-                populateDependentGraph((BundleImpl) target, bundles);
+                // If anyone passes in a null bundle, then just
+                // ignore it.
+                if (target != null)
+                {
+                    // Add the current target bundle to the map of
+                    // bundles to be refreshed.
+                    bundles.add(target);
+                    // Add all importing bundles to map.
+                    populateDependentGraph((BundleImpl) target, bundles);
+                }
             }
         }
 
@@ -4138,7 +4305,13 @@ public class Felix extends BundleImpl implements Framework
         {
             return m_securityProvider.hasBundlePermission(bundleProtectionDomain, permission, direct);
         }
-        return true;
+        else
+        {
+            Bundle source = bundleProtectionDomain.getBundle();
+
+            return (m_securityDefaultPolicy && (source == null || source.getBundleId() != 0)) ?
+                bundleProtectionDomain.superImplies(permission) : true;
+        }
     }
 
     private BundleActivator createBundleActivator(Bundle impl)
@@ -4325,6 +4498,17 @@ public class Felix extends BundleImpl implements Framework
             {
                 ex.printStackTrace();
             }
+            finally
+            {
+                try
+                {
+                    in.close();
+                }
+                catch (IOException ex)
+                {
+                    // Not much we can do.
+                }
+            }
         }
 
         // Maven uses a '-' to separate the version qualifier,
@@ -4612,19 +4796,28 @@ public class Felix extends BundleImpl implements Framework
 
         public void stop()
         {
-// TODO: LOCKING - This is not really correct.
-            if (m_bundle.getState() == Bundle.ACTIVE)
+            acquireBundleLock(m_bundle,
+                    Bundle.INSTALLED | Bundle.RESOLVED | Bundle.STARTING |
+                    Bundle.ACTIVE | Bundle.STOPPING | Bundle.UNINSTALLED);
+            try
             {
-                m_oldState = Bundle.ACTIVE;
-                try
-                {
-                    stopBundle(m_bundle, false);
-                }
-                catch (Throwable ex)
+                m_oldState = m_bundle.getState();
+                if (m_oldState != Bundle.UNINSTALLED)
                 {
-                    fireFrameworkEvent(FrameworkEvent.ERROR, m_bundle, ex);
+                    if (!Util.isFragment(m_bundle.adapt(BundleRevision.class)))
+                    {
+                        stopBundle(m_bundle, false);
+                    }
                 }
             }
+            catch (Throwable ex)
+            {
+                fireFrameworkEvent(FrameworkEvent.ERROR, m_bundle, ex);
+            }
+            finally
+            {
+                releaseBundleLock(m_bundle);
+            }
         }
 
         public void refreshOrRemove()
@@ -4839,7 +5032,8 @@ public class Felix extends BundleImpl implements Framework
             // holds the global lock or the bundle lock already.
             while (!bundle.isLockable() ||
                 ((m_globalLockThread != null)
-                    && (m_globalLockThread != Thread.currentThread())))
+                    && (m_globalLockThread != Thread.currentThread())
+                    && (bundle.getLockingThread() != Thread.currentThread())))
             {
                 // Check to make sure the bundle is in a desired state.
                 // If so, keep waiting. If not, throw an exception.
diff --git a/src/main/java/org/apache/felix/framework/FilterImpl.java b/src/main/java/org/apache/felix/framework/FilterImpl.java
index 3f1cc2d..666533f 100644
--- a/src/main/java/org/apache/felix/framework/FilterImpl.java
+++ b/src/main/java/org/apache/felix/framework/FilterImpl.java
@@ -113,7 +113,7 @@ public class FilterImpl implements Filter
         public WrapperCapability(ServiceReference sr)
         {
             super(null, null, Collections.EMPTY_MAP, Collections.EMPTY_MAP);
-            m_map = new StringMap(false);
+            m_map = new StringMap();
             for (String key : sr.getPropertyKeys())
             {
                 m_map.put(key, sr.getProperty(key));
@@ -161,7 +161,7 @@ public class FilterImpl implements Filter
             if (!caseSensitive)
             {
                 m_dict = null;
-                m_map = new StringMap(false);
+                m_map = new StringMap();
                 if (dict != null)
                 {
                     Enumeration keys = dict.keys();
diff --git a/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java b/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java
index dcb5fcc..e6509ce 100644
--- a/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java
+++ b/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java
@@ -37,19 +37,25 @@ class FrameworkStartLevelImpl implements FrameworkStartLevel, Runnable
     private static final int STARTLEVEL_IDX = 1;
 
     private final Felix m_felix;
+    private final ServiceRegistry m_registry;
     private final List m_requests = new ArrayList();
     private final List<FrameworkListener[]> m_requestListeners
         = new ArrayList<FrameworkListener[]>();
-    private final ServiceRegistration<StartLevel> m_slReg;
+    private ServiceRegistration<StartLevel> m_slReg;
     private Thread m_thread = null;
 
     FrameworkStartLevelImpl(Felix felix, ServiceRegistry registry)
     {
         m_felix = felix;
-        m_slReg = registry.registerService(felix,
-            new String[] { StartLevel.class.getName() },
-            new StartLevelImpl(felix),
-            null);
+        m_registry = registry;
+    }
+
+    void start()
+    {
+        m_slReg = m_registry.registerService(m_felix._getBundleContext(),
+                new String[] { StartLevel.class.getName() },
+                new StartLevelImpl(m_felix),
+                null);
     }
 
     // Should only be called hold requestList lock.
@@ -252,6 +258,7 @@ class FrameworkStartLevelImpl implements FrameworkStartLevel, Runnable
     {
         // This thread loops forever, thus it should
         // be a daemon thread.
+        Object previousRequest = null;
         while (true)
         {
             Object request = null;
@@ -292,7 +299,33 @@ class FrameworkStartLevelImpl implements FrameworkStartLevel, Runnable
             if (request instanceof Integer)
             {
                 // Set the new framework start level.
-                m_felix.setActiveStartLevel(((Integer) request).intValue(), listeners);
+                try
+                {
+                    m_felix.setActiveStartLevel(((Integer) request).intValue(), listeners);
+                }
+                catch (IllegalStateException ise)
+                {
+                    // Thrown if global lock cannot be acquired, in which case
+                    // just retry (unless we already did)
+                    if (previousRequest == request)
+                    {
+                        m_felix.getLogger().log(Logger.LOG_ERROR,
+                            "Unexpected problem setting active start level to " + request, ise);
+                    }
+                    else
+                    {
+                        synchronized (m_requests)
+                        {
+                            m_requests.add(0, request);
+                            previousRequest = request;
+                        }
+                    }
+                }
+                catch (Exception ex)
+                {
+                    m_felix.getLogger().log(Logger.LOG_ERROR,
+                        "Unexpected problem setting active start level to " + request, ex);
+                }
             }
             else
             {
diff --git a/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java b/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java
index da7bfee..8ad803c 100644
--- a/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java
+++ b/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java
@@ -31,20 +31,26 @@ import org.osgi.service.packageadmin.PackageAdmin;
 class FrameworkWiringImpl implements FrameworkWiring, Runnable
 {
     private final Felix m_felix;
+    private final ServiceRegistry m_registry;
     private final List<Collection<Bundle>> m_requests = new ArrayList();
     private final List<FrameworkListener[]> m_requestListeners
         = new ArrayList<FrameworkListener[]>();
-    private final ServiceRegistration<PackageAdmin> m_paReg;
+    private ServiceRegistration<PackageAdmin> m_paReg;
     private Thread m_thread = null;
 
 
     public FrameworkWiringImpl(Felix felix, ServiceRegistry registry)
     {
         m_felix = felix;
-        m_paReg = registry.registerService(felix,
-            new String[] { PackageAdmin.class.getName() },
-            new PackageAdminImpl(felix),
-            null);
+        m_registry = registry;
+    }
+
+    void start()
+    {
+        m_paReg = m_registry.registerService(m_felix._getBundleContext(),
+                new String[] { PackageAdmin.class.getName() },
+                new PackageAdminImpl(m_felix),
+                null);
     }
 
     /**
diff --git a/src/main/java/org/apache/felix/framework/PackageAdminImpl.java b/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
index 513f1e8..3a5b915 100644
--- a/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
+++ b/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
@@ -110,7 +110,7 @@ public class PackageAdminImpl implements PackageAdmin
     public int getBundleType(Bundle bundle)
     {
         Map headerMap = ((BundleRevisionImpl)
-            bundle.adapt(BundleRevision.class)).getHeaders();
+            bundle.adapt(BundleRevisionImpl.class)).getHeaders();
         if (headerMap.containsKey(Constants.FRAGMENT_HOST))
         {
             return PackageAdmin.BUNDLE_TYPE_FRAGMENT;
@@ -156,7 +156,8 @@ public class PackageAdminImpl implements PackageAdmin
     **/
     public ExportedPackage[] getExportedPackages(Bundle bundle)
     {
-        return m_felix.getExportedPackages(bundle);
+        ExportedPackage[] pkgs = m_felix.getExportedPackages(bundle);
+        return ((pkgs == null) || pkgs.length == 0) ? null : pkgs;
     }
 
     public Bundle[] getFragments(Bundle bundle)
diff --git a/src/main/java/org/apache/felix/framework/ResolveContextImpl.java b/src/main/java/org/apache/felix/framework/ResolveContextImpl.java
new file mode 100644
index 0000000..393dabf
--- /dev/null
+++ b/src/main/java/org/apache/felix/framework/ResolveContextImpl.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.framework.StatefulResolver.ResolverHookRecord;
+import org.apache.felix.framework.resolver.CandidateComparator;
+import org.apache.felix.framework.resolver.HostedCapability;
+import org.apache.felix.framework.resolver.ResolveContext;
+import org.apache.felix.framework.resolver.ResolveException;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWiring;
+
+/**
+ *
+ * @author rickhall
+ */
+public class ResolveContextImpl extends ResolveContext
+{
+    private final StatefulResolver m_state;
+    private final Map<BundleRevision, BundleWiring> m_wirings;
+    private final ResolverHookRecord m_resolverHookrecord;
+    private final Collection<BundleRevision> m_mandatory;
+    private final Collection<BundleRevision> m_optional;
+    private final Collection<BundleRevision> m_ondemand;
+
+    ResolveContextImpl(
+        StatefulResolver state, Map<BundleRevision, BundleWiring> wirings,
+        ResolverHookRecord resolverHookRecord, Collection<BundleRevision> mandatory,
+        Collection<BundleRevision> optional, Collection<BundleRevision> ondemand)
+    {
+        m_state = state;
+        m_wirings = wirings;
+        m_resolverHookrecord = resolverHookRecord;
+        m_mandatory = mandatory;
+        m_optional = optional;
+        m_ondemand = ondemand;
+    }
+
+    @Override
+    public Collection<BundleRevision> getMandatoryRevisions()
+    {
+        return new ArrayList<BundleRevision>(m_mandatory);
+    }
+
+    @Override
+    public Collection<BundleRevision> getOptionalRevisions()
+    {
+        return new ArrayList<BundleRevision>(m_optional);
+    }
+
+    public Collection<BundleRevision> getOndemandRevisions()
+    {
+        return new ArrayList<BundleRevision>(m_ondemand);
+    }
+
+    public List<BundleCapability> findProviders(BundleRequirement br, boolean obeyMandatory)
+    {
+        return m_state.findProvidersInternal(m_resolverHookrecord, br, obeyMandatory);
+    }
+
+    public int insertHostedCapability(List<BundleCapability> caps, HostedCapability hc)
+    {
+        int idx = Collections.binarySearch(caps, hc, new CandidateComparator());
+        if (idx < 0)
+        {
+            idx = Math.abs(idx + 1);
+        }
+        caps.add(idx, hc);
+        return idx;
+    }
+
+    public boolean isEffective(BundleRequirement br)
+    {
+        return m_state.isEffective(br);
+    }
+
+    public Map<BundleRevision, BundleWiring> getWirings()
+    {
+        return m_wirings;
+    }
+
+    public void checkNativeLibraries(BundleRevision rev) throws ResolveException
+    {
+        m_state.checkNativeLibraries(rev);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java b/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
index be6fb4b..ce35e18 100644
--- a/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
+++ b/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
@@ -29,6 +29,7 @@ import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.osgi.framework.*;
 import org.osgi.framework.BundleReference;
+import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.framework.wiring.BundleWire;
 
@@ -47,7 +48,7 @@ class ServiceRegistrationImpl implements ServiceRegistration
     // Service factory interface.
     private volatile ServiceFactory m_factory;
     // Associated property dictionary.
-    private volatile Map m_propMap = new StringMap(false);
+    private volatile Map m_propMap = new StringMap();
     // Re-usable service reference.
     private final ServiceReferenceImpl m_ref;
     // Flag indicating that we are unregistering.
@@ -161,10 +162,21 @@ class ServiceRegistrationImpl implements ServiceRegistration
 
         // Case 2.
         if ((m_factory != null)
-            && (m_factory.getClass().getClassLoader() instanceof BundleReference)
-            && !((BundleReference) m_factory.getClass()
-                .getClassLoader()).getBundle().equals(m_bundle))
+            && (Felix.m_secureAction.getClassLoader(m_factory.getClass()) instanceof BundleReference)
+            && !((BundleReference) Felix.m_secureAction.getClassLoader(m_factory.getClass())).getBundle().equals(m_bundle))
         {
+            try
+            {
+                Class providedClazz = m_bundle.loadClass(clazz.getName());
+                if (providedClazz != null)
+                {
+                    return providedClazz == clazz;
+                }
+            }
+            catch (ClassNotFoundException ex)
+            {
+                // Ignore and try interface class loaders.
+            }
             return true;
         }
 
@@ -272,7 +284,7 @@ class ServiceRegistrationImpl implements ServiceRegistration
     private void initializeProperties(Dictionary dict)
     {
         // Create a case-insensitive map for the properties.
-        Map props = new StringMap(false);
+        Map props = new StringMap();
 
         if (dict != null)
         {
@@ -485,12 +497,14 @@ class ServiceRegistrationImpl implements ServiceRegistration
             // Get the package.
             String pkgName =
                 Util.getClassPackage(className);
-            BundleRevision requesterRevision = requester.adapt(BundleRevision.class);
             // Get package wiring from service requester.
+            BundleRevision requesterRevision = requester.adapt(BundleRevision.class);
             BundleWire requesterWire = Util.getWire(requesterRevision, pkgName);
+            BundleCapability requesterCap = Util.getPackageCapability(requesterRevision, pkgName);
             // Get package wiring from service provider.
             BundleRevision providerRevision = m_bundle.adapt(BundleRevision.class);
             BundleWire providerWire = Util.getWire(providerRevision, pkgName);
+            BundleCapability providerCap = Util.getPackageCapability(providerRevision, pkgName);
 
             // There are four situations that may occur here:
             //   1. Neither the requester, nor provider have wires for the package.
@@ -533,10 +547,11 @@ class ServiceRegistrationImpl implements ServiceRegistration
             // Case 2: Requester has no wire, but provider does.
             else if ((requesterWire == null) && (providerWire != null))
             {
-                // Allow if the requester is the exporter of the provider's wire.
-                if (providerWire.getProviderWiring().getRevision().equals(requesterRevision))
+                // If the requester exports the package, then the provider must
+                // be wired to it.
+                if (requesterCap != null)
                 {
-                    allow = true;
+                    allow = providerWire.getProviderWiring().getRevision().equals(requesterRevision);
                 }
                 // Otherwise, check if the requester has access to the class and,
                 // if so, if it is the same class as the provider.
@@ -571,13 +586,11 @@ class ServiceRegistrationImpl implements ServiceRegistration
             // Case 3: Requester has a wire, but provider does not.
             else if ((requesterWire != null) && (providerWire == null))
             {
-                // If the provider is the exporter of the requester's package, then check
-                // if the requester is wired to the latest version of the provider, if so
-                // then allow else don't (the provider has been updated but not refreshed).
-                if (((BundleImpl) m_bundle).hasRevision(
-                    requesterWire.getProviderWiring().getRevision()))
+                // If the provider exports the package, then the requester must
+                // be wired to it.
+                if (providerCap != null)
                 {
-                    allow = providerRevision.equals(requesterWire.getProviderWiring().getRevision());
+                    allow = requesterWire.getProviderWiring().getRevision().equals(providerRevision);
                 }
                 // If the provider is not the exporter of the requester's package,
                 // then try to use the service registration to see if the requester's
diff --git a/src/main/java/org/apache/felix/framework/ServiceRegistry.java b/src/main/java/org/apache/felix/framework/ServiceRegistry.java
index c21ba5b..46c880b 100644
--- a/src/main/java/org/apache/felix/framework/ServiceRegistry.java
+++ b/src/main/java/org/apache/felix/framework/ServiceRegistry.java
@@ -19,10 +19,12 @@
 package org.apache.felix.framework;
 
 import java.util.*;
+
 import org.apache.felix.framework.capabilityset.CapabilitySet;
 import org.apache.felix.framework.capabilityset.SimpleFilter;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceEvent;
 import org.osgi.framework.ServiceException;
@@ -53,6 +55,7 @@ public class ServiceRegistry
         new WeakHashMap<ServiceReference, ServiceReference>();
 
     private final static Class<?>[] m_hookClasses = {
+        org.osgi.framework.hooks.bundle.CollisionHook.class,
         org.osgi.framework.hooks.bundle.FindHook.class,
         org.osgi.framework.hooks.bundle.EventHook.class,
         org.osgi.framework.hooks.service.EventHook.class,
@@ -101,12 +104,14 @@ public class ServiceRegistry
 
     // Caller is expected to fire REGISTERED event.
     public ServiceRegistration registerService(
-        Bundle bundle, String[] classNames, Object svcObj, Dictionary dict)
+        BundleContext context, String[] classNames, Object svcObj, Dictionary dict)
     {
         ServiceRegistrationImpl reg = null;
 
         synchronized (this)
         {
+            Bundle bundle = context.getBundle();
+
             // Create the service registration.
             reg = new ServiceRegistrationImpl(
                 this, bundle, classNames, new Long(m_currentServiceId++), svcObj, dict);
@@ -150,15 +155,20 @@ public class ServiceRegistry
         }
 
         // Now forcibly unget the service object for all stubborn clients.
-        synchronized (this)
+        ServiceReference ref = reg.getReference();
+        Bundle[] clients = getUsingBundles(ref);
+        for (int i = 0; (clients != null) && (i < clients.length); i++)
         {
-            Bundle[] clients = getUsingBundles(reg.getReference());
-            for (int i = 0; (clients != null) && (i < clients.length); i++)
-            {
-                while (ungetService(clients[i], reg.getReference()))
-                    ; // Keep removing until it is no longer possible
-            }
-            ((ServiceRegistrationImpl) reg).invalidate();
+            while (ungetService(clients[i], reg.getReference()))
+                ; // Keep removing until it is no longer possible
+        }
+        // Invalidate registration
+        ((ServiceRegistrationImpl) reg).invalidate();
+        // Bundles are allowed to get a reference while unregistering
+        for (int i = 0; (clients != null) && (i < clients.length); i++)
+        {
+            while (ungetService(clients[i], ref))
+                ; // Keep removing until it is no longer possible
         }
     }
 
@@ -188,7 +198,14 @@ public class ServiceRegistry
         {
             if (((ServiceRegistrationImpl) regs[i]).isValid())
             {
-                regs[i].unregister();
+                try
+                {
+                    regs[i].unregister();
+                }
+                catch (IllegalStateException e)
+                {
+                    // Ignore exception if the service has already been unregistered
+                }
             }
         }
 
@@ -488,6 +505,7 @@ public class ServiceRegistry
 
     void servicePropertiesModified(ServiceRegistration reg, Dictionary oldProps)
     {
+        updateHook(reg.getReference());
         if (m_callbacks != null)
         {
             m_callbacks.serviceChanged(
@@ -704,7 +722,7 @@ public class ServiceRegistry
                     Set<ServiceReference<?>> hooks = m_allHooks.get(hookClass);
                     if (hooks == null)
                     {
-                        hooks = new HashSet<ServiceReference<?>>();
+                        hooks = new TreeSet<ServiceReference<?>>(Collections.reverseOrder());
                         m_allHooks.put(hookClass, hooks);
                     }
                     hooks.add(ref);
@@ -713,6 +731,32 @@ public class ServiceRegistry
         }
     }
 
+    private void updateHook(ServiceReference ref)
+    {
+        // We maintain the hooks sorted, so if ranking has changed for example,
+        // we need to ensure the order remains correct by resorting the hooks.
+        Object svcObj = ((ServiceRegistrationImpl.ServiceReferenceImpl) ref)
+                .getRegistration().getService();
+        String [] classNames = (String[]) ref.getProperty(Constants.OBJECTCLASS);
+
+        for (Class<?> hookClass : m_hookClasses)
+        {
+            if (isHook(classNames, hookClass, svcObj))
+            {
+                synchronized (m_allHooks)
+                {
+                    Set<ServiceReference<?>> hooks = m_allHooks.get(hookClass);
+                    if (hooks != null)
+                    {
+                        List<ServiceReference<?>> refs = new ArrayList<ServiceReference<?>>(hooks);
+                        hooks.clear();
+                        hooks.addAll(refs);
+                    }
+                }
+            }
+        }
+    }
+
     private void removeHook(ServiceReference ref)
     {
         Object svcObj = ((ServiceRegistrationImpl.ServiceReferenceImpl) ref)
@@ -771,4 +815,4 @@ public class ServiceRegistry
     {
         void serviceChanged(ServiceEvent event, Dictionary oldProps);
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/felix/framework/StatefulResolver.java b/src/main/java/org/apache/felix/framework/StatefulResolver.java
index c099f15..6c6e75f 100644
--- a/src/main/java/org/apache/felix/framework/StatefulResolver.java
+++ b/src/main/java/org/apache/felix/framework/StatefulResolver.java
@@ -24,13 +24,13 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.NoSuchElementException;
 import java.util.Set;
-import java.util.SortedSet;
 import java.util.StringTokenizer;
-import java.util.TreeSet;
 import org.apache.felix.framework.capabilityset.CapabilitySet;
 import org.apache.felix.framework.capabilityset.SimpleFilter;
 import org.apache.felix.framework.resolver.CandidateComparator;
@@ -41,6 +41,7 @@ import org.apache.felix.framework.resolver.ResolverWire;
 import org.apache.felix.framework.util.ShrinkableCollection;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.apache.felix.framework.wiring.BundleWireImpl;
 import org.osgi.framework.Bundle;
@@ -64,33 +65,270 @@ class StatefulResolver
     private final Logger m_logger;
     private final Felix m_felix;
     private final Resolver m_resolver;
-    private final ResolverStateImpl m_resolverState;
-    private final List<ResolverHook> m_hooks = new ArrayList<ResolverHook>();
     private boolean m_isResolving = false;
-    private Collection<BundleRevision> m_whitelist = null;
+
+    // Set of all revisions.
+    private final Set<BundleRevision> m_revisions;
+    // Set of all fragments.
+    private final Set<BundleRevision> m_fragments;
+    // Capability sets.
+    private final Map<String, CapabilitySet> m_capSets;
+    // Maps singleton symbolic names to list of bundle revisions sorted by version.
+    private final Map<String, List<BundleRevision>> m_singletons;
+    // Selected singleton bundle revisions.
+    private final Set<BundleRevision> m_selectedSingletons;
+    // Execution environment.
+    private final String m_fwkExecEnvStr;
+    // Parsed framework environments
+    private final Set<String> m_fwkExecEnvSet;
 
     StatefulResolver(Felix felix)
     {
         m_felix = felix;
         m_logger = m_felix.getLogger();
         m_resolver = new ResolverImpl(m_logger);
-        m_resolverState = new ResolverStateImpl(
-            (String) m_felix.getConfig().get(Constants.FRAMEWORK_EXECUTIONENVIRONMENT));
+
+        m_revisions = new HashSet<BundleRevision>();
+        m_fragments = new HashSet<BundleRevision>();
+        m_capSets = new HashMap<String, CapabilitySet>();
+        m_singletons = new HashMap<String, List<BundleRevision>>();
+        m_selectedSingletons = new HashSet<BundleRevision>();
+
+        String fwkExecEnvStr =
+            (String) m_felix.getConfig().get(Constants.FRAMEWORK_EXECUTIONENVIRONMENT);
+        m_fwkExecEnvStr = (fwkExecEnvStr != null) ? fwkExecEnvStr.trim() : null;
+        m_fwkExecEnvSet = parseExecutionEnvironments(fwkExecEnvStr);
+
+        List<String> indices = new ArrayList<String>();
+        indices.add(BundleRevision.BUNDLE_NAMESPACE);
+        m_capSets.put(BundleRevision.BUNDLE_NAMESPACE, new CapabilitySet(indices, true));
+
+        indices = new ArrayList<String>();
+        indices.add(BundleRevision.PACKAGE_NAMESPACE);
+        m_capSets.put(BundleRevision.PACKAGE_NAMESPACE, new CapabilitySet(indices, true));
+
+        indices = new ArrayList<String>();
+        indices.add(BundleRevision.HOST_NAMESPACE);
+        m_capSets.put(BundleRevision.HOST_NAMESPACE,  new CapabilitySet(indices, true));
     }
 
-    void addRevision(BundleRevision br)
+    synchronized void addRevision(BundleRevision br)
     {
-        m_resolverState.addRevision(br);
+        // Always attempt to remove the revision, since
+        // this method can be used for re-indexing a revision
+        // after it has been resolved.
+        removeRevision(br);
+
+        m_revisions.add(br);
+
+        // Add singletons to the singleton map.
+        boolean isSingleton = Util.isSingleton(br);
+        if (isSingleton)
+        {
+            // Index the new singleton.
+            addToSingletonMap(m_singletons, br);
+        }
+
+        // We always need to index non-singleton bundle capabilities, but
+        // singleton bundles only need to be index if they are resolved.
+        // Unresolved singleton capabilities are only indexed before a
+        // resolve operation when singleton selection is performed.
+        if (!isSingleton || (br.getWiring() != null))
+        {
+            if (Util.isFragment(br))
+            {
+                m_fragments.add(br);
+            }
+            indexCapabilities(br);
+        }
+    }
+
+    synchronized void removeRevision(BundleRevision br)
+    {
+        if (m_revisions.remove(br))
+        {
+            m_fragments.remove(br);
+            deindexCapabilities(br);
+
+            // If this module is a singleton, then remove it from the
+            // singleton map.
+            List<BundleRevision> revisions = m_singletons.get(br.getSymbolicName());
+            if (revisions != null)
+            {
+                revisions.remove(br);
+                if (revisions.isEmpty())
+                {
+                    m_singletons.remove(br.getSymbolicName());
+                }
+            }
+        }
     }
 
-    void removeRevision(BundleRevision br)
+    boolean isEffective(BundleRequirement req)
     {
-        m_resolverState.removeRevision(br);
+        String effective = req.getDirectives().get(Constants.EFFECTIVE_DIRECTIVE);
+        return ((effective == null) || effective.equals(Constants.EFFECTIVE_RESOLVE));
     }
 
-    Set<BundleCapability> getCandidates(BundleRequirementImpl req, boolean obeyMandatory)
+    synchronized List<BundleCapability> findProviders(
+        BundleRequirement req, boolean obeyMandatory)
     {
-        return m_resolverState.getCandidates(req, obeyMandatory);
+        ResolverHookRecord record = new ResolverHookRecord(
+            Collections.<ServiceReference<ResolverHookFactory>, ResolverHook>emptyMap(), null);
+        return findProvidersInternal(record, req, obeyMandatory);
+    }
+
+    synchronized List<BundleCapability> findProvidersInternal(
+        ResolverHookRecord record, BundleRequirement req, boolean obeyMandatory)
+    {
+        List<BundleCapability> result = new ArrayList<BundleCapability>();
+
+        CapabilitySet capSet = m_capSets.get(req.getNamespace());
+        if (capSet != null)
+        {
+            // Get the requirement's filter; if this is our own impl we
+            // have a shortcut to get the already parsed filter, otherwise
+            // we must parse it from the directive.
+            SimpleFilter sf;
+            if (req instanceof BundleRequirementImpl)
+            {
+                sf = ((BundleRequirementImpl) req).getFilter();
+            }
+            else
+            {
+                String filter = req.getDirectives().get(Constants.FILTER_DIRECTIVE);
+                if (filter == null)
+                {
+                    sf = new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
+                }
+                else
+                {
+                    sf = SimpleFilter.parse(filter);
+                }
+            }
+
+            // Find the matching candidates.
+            Set<BundleCapability> matches = capSet.match(sf, obeyMandatory);
+            // Filter matching candidates.
+            for (BundleCapability cap : matches)
+            {
+                // Filter according to security.
+                if (filteredBySecurity(req, cap))
+                {
+                    continue;
+                }
+                // Filter already resolved hosts, since we don't support
+                // dynamic attachment of fragments.
+                if (req.getNamespace().equals(BundleRevision.HOST_NAMESPACE)
+                    && (cap.getRevision().getWiring() != null))
+                {
+                    continue;
+                }
+
+                result.add(cap);
+            }
+        }
+
+        // If we have resolver hooks, then we may need to filter our results
+        // based on a whitelist and/or fine-grained candidate filtering.
+        if (!result.isEmpty() && !record.getResolverHookRefs().isEmpty())
+        {
+            // It we have a whitelist, then first filter out candidates
+            // from disallowed revisions.
+            if (record.getBundleRevisionWhitelist() != null)
+            {
+                for (Iterator<BundleCapability> it = result.iterator(); it.hasNext(); )
+                {
+                    if (!record.getBundleRevisionWhitelist().contains(it.next().getRevision()))
+                    {
+                        it.remove();
+                    }
+                }
+            }
+
+            // Now give the hooks a chance to do fine-grained filtering.
+            ShrinkableCollection<BundleCapability> shrinkable =
+                new ShrinkableCollection<BundleCapability>(result);
+            for (ResolverHook hook : record.getResolverHooks())
+            {
+                try
+                {
+                    Felix.m_secureAction
+                        .invokeResolverHookMatches(hook, req, shrinkable);
+                }
+                catch (Throwable th)
+                {
+                    m_logger.log(Logger.LOG_WARNING, "Resolver hook exception.", th);
+                }
+            }
+        }
+
+        Collections.sort(result, new CandidateComparator());
+
+        return result;
+    }
+
+    private boolean filteredBySecurity(BundleRequirement req, BundleCapability cap)
+    {
+        if (System.getSecurityManager() != null)
+        {
+            BundleRevisionImpl reqRevision = (BundleRevisionImpl) req.getRevision();
+
+            if (req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
+            {
+                if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
+                    new PackagePermission((String) cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
+                    PackagePermission.EXPORTONLY)) ||
+                    !((reqRevision == null) ||
+                        ((BundleProtectionDomain) reqRevision.getProtectionDomain()).impliesDirect(
+                            new PackagePermission((String) cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
+                            cap.getRevision().getBundle(),PackagePermission.IMPORT))
+                    ))
+                {
+                    if (reqRevision != cap.getRevision())
+                    {
+                        return true;
+                    }
+                }
+            }
+            else if (req.getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE))
+            {   if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
+                    new BundlePermission(cap.getRevision().getSymbolicName(), BundlePermission.PROVIDE)) ||
+                    !((reqRevision == null) ||
+                        ((BundleProtectionDomain) reqRevision.getProtectionDomain()).impliesDirect(
+                            new BundlePermission(reqRevision.getSymbolicName(), BundlePermission.REQUIRE))
+                    ))
+                {
+                    return true;
+                }
+            }
+            else if (req.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
+            {
+                if (!((BundleProtectionDomain) reqRevision.getProtectionDomain())
+                    .impliesDirect(new BundlePermission(
+                        reqRevision.getSymbolicName(),
+                        BundlePermission.FRAGMENT))
+                || !((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain())
+                    .impliesDirect(new BundlePermission(
+                        cap.getRevision().getSymbolicName(),
+                        BundlePermission.HOST)))
+                {
+                    return true;
+                }
+            }
+            else  if (!req.getNamespace().equals("osgi.ee"))
+            {
+                if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
+                    new CapabilityPermission(req.getNamespace(), CapabilityPermission.PROVIDE))
+                    ||
+                    !((reqRevision == null) || ((BundleProtectionDomain) reqRevision.getProtectionDomain()).impliesDirect(
+                    new CapabilityPermission(req.getNamespace(), cap.getAttributes(), cap.getRevision().getBundle(), CapabilityPermission.REQUIRE))))
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
     }
 
     void resolve(
@@ -125,11 +363,10 @@ class StatefulResolver
                 ? optional : new HashSet<BundleRevision>(optional);
 
             // Prepare resolver hooks, if any.
-            Set<ServiceReference<ResolverHookFactory>> hookRefs =
-                prepareResolverHooks(mandatory, optional);
+            ResolverHookRecord record = prepareResolverHooks(mandatory, optional);
 
             // Select any singletons in the resolver state.
-            m_resolverState.selectSingletons();
+            selectSingletons(record);
 
             // Extensions are resolved differently.
             for (Iterator<BundleRevision> it = mandatory.iterator(); it.hasNext(); )
@@ -140,7 +377,7 @@ class StatefulResolver
                 {
                     it.remove();
                 }
-                else if (Util.isSingleton(br) && !m_resolverState.isSelectedSingleton(br))
+                else if (Util.isSingleton(br) && !isSelectedSingleton(br))
                 {
                     throw new ResolveException("Singleton conflict.", br, null);
                 }
@@ -153,7 +390,7 @@ class StatefulResolver
                 {
                     it.remove();
                 }
-                else if (Util.isSingleton(br) && !m_resolverState.isSelectedSingleton(br))
+                else if (Util.isSingleton(br) && !isSelectedSingleton(br))
                 {
                     it.remove();
                 }
@@ -166,10 +403,13 @@ class StatefulResolver
             {
                 // Resolve the revision.
                 wireMap = m_resolver.resolve(
-                    m_resolverState,
-                    mandatory,
-                    optional,
-                    m_resolverState.getFragments());
+                    new ResolveContextImpl(
+                        this,
+                        getWirings(),
+                        record,
+                        mandatory,
+                        optional,
+                        getFragments()));
             }
             catch (ResolveException ex)
             {
@@ -177,7 +417,7 @@ class StatefulResolver
             }
 
             // Release resolver hooks, if any.
-            releaseResolverHooks(hookRefs);
+            releaseResolverHooks(record);
 
             // If the resolve failed, rethrow the exception.
             if (rethrow != null)
@@ -192,10 +432,6 @@ class StatefulResolver
         {
             // Clear resolving flag.
             m_isResolving = false;
-            // Clear whitelist.
-            m_whitelist = null;
-            // Always clear any hooks.
-            m_hooks.clear();
             // Always release the global lock.
             m_felix.releaseGlobalLock();
         }
@@ -244,12 +480,12 @@ class StatefulResolver
                 if (provider == null)
                 {
                     // Prepare resolver hooks, if any.
-                    Set<ServiceReference<ResolverHookFactory>> hookRefs =
+                    ResolverHookRecord record =
                         prepareResolverHooks(
                             Collections.singleton(revision), Collections.EMPTY_SET);
 
                     // Select any singletons in the resolver state.
-                    m_resolverState.selectSingletons();
+                    selectSingletons(record);
 
                     // Catch any resolve exception to rethrow later because
                     // we may need to call end() on resolver hooks.
@@ -257,8 +493,14 @@ class StatefulResolver
                     try
                     {
                         wireMap = m_resolver.resolve(
-                            m_resolverState, revision, pkgName,
-                            m_resolverState.getFragments());
+                            new ResolveContextImpl(
+                                this,
+                                getWirings(),
+                                record,
+                                Collections.EMPTY_LIST,
+                                Collections.EMPTY_LIST,
+                                getFragments()),
+                            revision, pkgName);
                     }
                     catch (ResolveException ex)
                     {
@@ -266,7 +508,7 @@ class StatefulResolver
                     }
 
                     // Release resolver hooks, if any.
-                    releaseResolverHooks(hookRefs);
+                    releaseResolverHooks(record);
 
                     // If the resolve failed, rethrow the exception.
                     if (rethrow != null)
@@ -309,10 +551,6 @@ class StatefulResolver
             {
                 // Clear resolving flag.
                 m_isResolving = false;
-                // Clear whitelist.
-                m_whitelist = null;
-                // Always clear any hooks.
-                m_hooks.clear();
                 // Always release the global lock.
                 m_felix.releaseGlobalLock();
             }
@@ -323,13 +561,23 @@ class StatefulResolver
         return provider;
     }
 
-    private Set<ServiceReference<ResolverHookFactory>> prepareResolverHooks(
+    private ResolverHookRecord prepareResolverHooks(
         Set<BundleRevision> mandatory, Set<BundleRevision> optional)
         throws BundleException
     {
+        // This map maps the hook factory service to the actual hook objects. It
+        // needs to be a map that preserves insertion order to ensure that we call 
+        // hooks in the correct order.
+        // The hooks are added in the order that m_felix.getHooks() returns them which
+        // is also the order in which they should be called.
+        Map<ServiceReference<ResolverHookFactory>, ResolverHook> hookMap =
+            new LinkedHashMap<ServiceReference<ResolverHookFactory>, ResolverHook>();
+
         // Get resolver hook factories.
         Set<ServiceReference<ResolverHookFactory>> hookRefs =
             m_felix.getHooks(ResolverHookFactory.class);
+        Collection<BundleRevision> whitelist;
+
         if (!hookRefs.isEmpty())
         {
             // Create triggers list.
@@ -346,6 +594,8 @@ class StatefulResolver
             }
             triggers = Collections.unmodifiableSet(triggers);
 
+            BundleException rethrow = null;
+            
             // Create resolver hook objects by calling begin() on factory.
             for (ServiceReference<ResolverHookFactory> ref : hookRefs)
             {
@@ -359,48 +609,93 @@ class StatefulResolver
                                 .invokeResolverHookFactory(rhf, triggers);
                         if (hook != null)
                         {
-                            m_hooks.add(hook);
+                            hookMap.put(ref, hook);
                         }
                     }
                 }
                 catch (Throwable ex)
                 {
-                    throw new BundleException(
+                    rethrow = new BundleException(
                         "Resolver hook exception: " + ex.getMessage(),
                         BundleException.REJECTED_BY_HOOK,
                         ex);
+                    // Resolver hook spec: if there is an exception during the resolve operation; abort.
+                    // So we break here to make sure that no further resolver hooks are created.
+                    break; 
                 }
             }
 
+            if (rethrow != null)
+            {
+                for (ResolverHook hook : hookMap.values())
+                {
+                    try
+                    {
+                        Felix.m_secureAction.invokeResolverHookEnd(hook);
+                    }
+                    catch (Exception ex)
+                    {
+                        rethrow = new BundleException(
+                                "Resolver hook exception: " + ex.getMessage(),
+                                BundleException.REJECTED_BY_HOOK,
+                                ex);
+                    }
+                }
+
+                throw rethrow;
+            }
+
             // Ask hooks to indicate which revisions should not be resolved.
-            m_whitelist =
-                new ShrinkableCollection<BundleRevision>(
-                    m_resolverState.getUnresolvedRevisions());
-            int originalSize = m_whitelist.size();
-            for (ResolverHook hook : m_hooks)
+            whitelist = new ShrinkableCollection<BundleRevision>(getUnresolvedRevisions());
+            int originalSize = whitelist.size();
+            for (ResolverHook hook : hookMap.values())
             {
                 try
                 {
                     Felix.m_secureAction
-                        .invokeResolverHookResolvable(hook, m_whitelist);
+                        .invokeResolverHookResolvable(hook, whitelist);
                 }
                 catch (Throwable ex)
                 {
-                    throw new BundleException(
+                    rethrow = new BundleException(
                         "Resolver hook exception: " + ex.getMessage(),
                         BundleException.REJECTED_BY_HOOK,
                         ex);
+                    // Resolver hook spec: if there is an exception during the resolve operation; abort.
+                    // So we break here to make sure that no further resolver operations are executed.
+                    break; 
                 }
             }
+
+            if (rethrow != null)
+            {
+                for (ResolverHook hook : hookMap.values())
+                {
+                    try
+                    {
+                        Felix.m_secureAction.invokeResolverHookEnd(hook);
+                    }
+                    catch (Exception ex)
+                    {
+                        rethrow = new BundleException(
+                                "Resolver hook exception: " + ex.getMessage(),
+                                BundleException.REJECTED_BY_HOOK,
+                                ex);
+                    }
+                }
+
+                throw rethrow;
+            }
+
             // If nothing was removed, then just null the whitelist
             // as an optimization.
-            if (m_whitelist.size() == originalSize)
+            if (whitelist.size() == originalSize)
             {
-                m_whitelist = null;
+                whitelist = null;
             }
 
             // Check to make sure the target revisions are allowed to resolve.
-            if (m_whitelist != null)
+            if (whitelist != null)
             {
                 // We only need to check this for the non-dynamic import
                 // case. The dynamic import case will only have one resolved
@@ -409,8 +704,8 @@ class StatefulResolver
                     || !optional.isEmpty()
                     || (mandatory.iterator().next().getWiring() == null))
                 {
-                    mandatory.retainAll(m_whitelist);
-                    optional.retainAll(m_whitelist);
+                    mandatory.retainAll(whitelist);
+                    optional.retainAll(whitelist);
                     if (mandatory.isEmpty() && optional.isEmpty())
                     {
                         throw new ResolveException(
@@ -421,25 +716,22 @@ class StatefulResolver
         }
         else
         {
-            m_hooks.clear();
+            whitelist = null;
         }
 
-        return hookRefs;
+        return new ResolverHookRecord(hookMap, whitelist);
     }
 
-    private void releaseResolverHooks(Set<ServiceReference<ResolverHookFactory>> hookRefs)
+    private void releaseResolverHooks(ResolverHookRecord record)
         throws BundleException
     {
         // If we have resolver hooks, we must call end() on them.
-        if (!hookRefs.isEmpty())
+        if (!record.getResolverHookRefs().isEmpty())
         {
             // Verify that all resolver hook service references are still valid
             // Call end() on resolver hooks.
-            for (ResolverHook hook : m_hooks)
+            for (ResolverHook hook : record.getResolverHooks())
             {
-// TODO: OSGi R4.3/RESOLVER HOOK - We likely need to put these hooks into a map
-//       to their svc ref since we aren't supposed to call end() on unregistered
-//       but currently we call end() on all.
                 try
                 {
                     Felix.m_secureAction.invokeResolverHookEnd(hook);
@@ -453,7 +745,7 @@ class StatefulResolver
             // Verify that all hook service references are still valid
             // and unget all resolver hook factories.
             boolean invalid = false;
-            for (ServiceReference<ResolverHookFactory> ref : hookRefs)
+            for (ServiceReference<ResolverHookFactory> ref : record.getResolverHookRefs())
             {
                 if (ref.getBundle() == null)
                 {
@@ -472,6 +764,7 @@ class StatefulResolver
 
     // This method duplicates a lot of logic from:
     // ResolverImpl.getDynamicImportCandidates()
+    // This is only a rough check since it doesn't include resolver hooks.
     boolean isAllowedDynamicImport(BundleRevision revision, String pkgName)
     {
         // Unresolved revisions cannot dynamically import, nor can the default
@@ -518,7 +811,46 @@ class StatefulResolver
             BundleRevision.PACKAGE_NAMESPACE,
             Collections.EMPTY_MAP,
             attrs);
-        Set<BundleCapability> candidates = m_resolverState.getCandidates(req, false);
+        List<BundleCapability> candidates = findProviders(req, false);
+
+        // Try to find a dynamic requirement that matches the capabilities.
+        BundleRequirementImpl dynReq = null;
+        for (int dynIdx = 0;
+            (candidates.size() > 0) && (dynReq == null) && (dynIdx < dynamics.size());
+            dynIdx++)
+        {
+            for (Iterator<BundleCapability> itCand = candidates.iterator();
+                (dynReq == null) && itCand.hasNext(); )
+            {
+                BundleCapability cap = itCand.next();
+                if (CapabilitySet.matches(
+                    (BundleCapabilityImpl) cap,
+                    ((BundleRequirementImpl) dynamics.get(dynIdx)).getFilter()))
+                {
+                    dynReq = (BundleRequirementImpl) dynamics.get(dynIdx);
+                }
+            }
+        }
+
+        // If we found a matching dynamic requirement, then filter out
+        // any candidates that do not match it.
+        if (dynReq != null)
+        {
+            for (Iterator<BundleCapability> itCand = candidates.iterator();
+                itCand.hasNext(); )
+            {
+                BundleCapability cap = itCand.next();
+                if (!CapabilitySet.matches(
+                    (BundleCapabilityImpl) cap, dynReq.getFilter()))
+                {
+                    itCand.remove();
+                }
+            }
+        }
+        else
+        {
+            candidates.clear();
+        }
 
         return !candidates.isEmpty();
     }
@@ -526,6 +858,8 @@ class StatefulResolver
     private void markResolvedRevisions(Map<BundleRevision, List<ResolverWire>> wireMap)
         throws ResolveException
     {
+        boolean debugLog = m_felix.getLogger().getLogLevel() >= Logger.LOG_DEBUG;
+
         // DO THIS IN THREE PASSES:
         // 1. Aggregate fragments per host.
         // 2. Attach wires and fragments to hosts.
@@ -606,13 +940,19 @@ class StatefulResolver
 
                     if (Util.isFragment(revision))
                     {
-                        m_felix.getLogger().log(
-                            Logger.LOG_DEBUG,
-                            "FRAGMENT WIRE: " + rw.toString());
+                        if (debugLog)
+                        {
+                            m_felix.getLogger().log(
+                                Logger.LOG_DEBUG,
+                                "FRAGMENT WIRE: " + rw.toString());
+                        }
                     }
                     else
                     {
-                        m_felix.getLogger().log(Logger.LOG_DEBUG, "WIRE: " + rw.toString());
+                        if (debugLog)
+                        {
+                            m_felix.getLogger().log(Logger.LOG_DEBUG, "WIRE: " + rw.toString());
+                        }
 
                         if (rw.getCapability().getNamespace()
                             .equals(BundleRevision.PACKAGE_NAMESPACE))
@@ -713,7 +1053,7 @@ class StatefulResolver
                 // Reindex the revision's capabilities since its resolved
                 // capabilities could be different than its declared ones
                 // (e.g., due to substitutable exports).
-                m_resolverState.addRevision(revision);
+                addRevision(revision);
 
                 // Update the state of the revision's bundle to resolved as well.
                 markBundleResolved(revision);
@@ -855,636 +1195,344 @@ class StatefulResolver
         return pkgs;
     }
 
-    class ResolverStateImpl implements Resolver.ResolverState
+    private synchronized void indexCapabilities(BundleRevision br)
     {
-        // Set of all revisions.
-        private final Set<BundleRevision> m_revisions;
-        // Set of all fragments.
-        private final Set<BundleRevision> m_fragments;
-        // Capability sets.
-        private final Map<String, CapabilitySet> m_capSets;
-        // Maps singleton symbolic names to list of bundle revisions sorted by version.
-        private final Map<String, List<BundleRevision>> m_singletons;
-        // Selected singleton bundle revisions.
-        private final Set<BundleRevision> m_selectedSingletons;
-        // Execution environment.
-        private final String m_fwkExecEnvStr;
-        // Parsed framework environments
-        private final Set<String> m_fwkExecEnvSet;
-
-//    void dump()
-//    {
-//        for (Entry<String, CapabilitySet> entry : m_capSets.entrySet())
-//        {
-//            System.out.println("+++ START CAPSET " + entry.getKey());
-//            entry.getValue().dump();
-//            System.out.println("+++ END CAPSET " + entry.getKey());
-//        }
-//    }
-
-        ResolverStateImpl(String fwkExecEnvStr)
+        List<BundleCapability> caps =
+            (Util.isFragment(br) || (br.getWiring() == null))
+                ? br.getDeclaredCapabilities(null)
+                : br.getWiring().getCapabilities(null);
+        if (caps != null)
         {
-            m_revisions = new HashSet<BundleRevision>();
-            m_fragments = new HashSet<BundleRevision>();
-            m_capSets = new HashMap<String, CapabilitySet>();
-            m_singletons = new HashMap<String, List<BundleRevision>>();
-            m_selectedSingletons = new HashSet<BundleRevision>();
-
-            m_fwkExecEnvStr = (fwkExecEnvStr != null) ? fwkExecEnvStr.trim() : null;
-            m_fwkExecEnvSet = parseExecutionEnvironments(fwkExecEnvStr);
-
-            List<String> indices = new ArrayList<String>();
-            indices.add(BundleRevision.BUNDLE_NAMESPACE);
-            m_capSets.put(BundleRevision.BUNDLE_NAMESPACE, new CapabilitySet(indices, true));
-
-            indices = new ArrayList<String>();
-            indices.add(BundleRevision.PACKAGE_NAMESPACE);
-            m_capSets.put(BundleRevision.PACKAGE_NAMESPACE, new CapabilitySet(indices, true));
-
-            indices = new ArrayList<String>();
-            indices.add(BundleRevision.HOST_NAMESPACE);
-            m_capSets.put(BundleRevision.HOST_NAMESPACE,  new CapabilitySet(indices, true));
-        }
-
-        synchronized Set<BundleRevision> getUnresolvedRevisions()
-        {
-            Set<BundleRevision> unresolved = new HashSet<BundleRevision>();
-            for (BundleRevision revision : m_revisions)
+            for (BundleCapability cap : caps)
             {
-                if (revision.getWiring() == null)
+                // If the capability is from a different revision, then
+                // don't index it since it is a capability from a fragment.
+                // In that case, the fragment capability is still indexed.
+                // It will be the resolver's responsibility to find all
+                // attached hosts for fragments.
+                if (cap.getRevision() == br)
                 {
-                    unresolved.add(revision);
+                    CapabilitySet capSet = m_capSets.get(cap.getNamespace());
+                    if (capSet == null)
+                    {
+                        capSet = new CapabilitySet(null, true);
+                        m_capSets.put(cap.getNamespace(), capSet);
+                    }
+                    capSet.addCapability(cap);
                 }
             }
-            return unresolved;
         }
+    }
 
-        synchronized void addRevision(BundleRevision br)
+    private synchronized void deindexCapabilities(BundleRevision br)
+    {
+        // We only need be concerned with declared capabilities here,
+        // because resolved capabilities will be a subset, since fragment
+        // capabilities are not considered to be part of the host.
+        List<BundleCapability> caps = br.getDeclaredCapabilities(null);
+        if (caps != null)
         {
-            // Always attempt to remove the revision, since
-            // this method can be used for re-indexing a revision
-            // after it has been resolved.
-            removeRevision(br);
-
-            m_revisions.add(br);
-
-            // Add singletons to the singleton map.
-            boolean isSingleton = Util.isSingleton(br);
-            if (isSingleton)
-            {
-                // Index the new singleton.
-                addToSingletonMap(m_singletons, br);
-            }
-
-            // We always need to index non-singleton bundle capabilities, but
-            // singleton bundles only need to be index if they are resolved.
-            // Unresolved singleton capabilities are only indexed before a
-            // resolve operation when singleton selection is performed.
-            if (!isSingleton || (br.getWiring() != null))
+            for (BundleCapability cap : caps)
             {
-                if (Util.isFragment(br))
+                CapabilitySet capSet = m_capSets.get(cap.getNamespace());
+                if (capSet != null)
                 {
-                    m_fragments.add(br);
+                    capSet.removeCapability(cap);
                 }
-                indexCapabilities(br);
             }
         }
+    }
+
+    private synchronized boolean isSelectedSingleton(BundleRevision br)
+    {
+        return m_selectedSingletons.contains(br);
+    }
 
-        private synchronized void indexCapabilities(BundleRevision br)
+    private synchronized void selectSingletons(ResolverHookRecord record)
+        throws BundleException
+    {
+        // First deindex any unresolved singletons to make sure
+        // there aren't any available from previous resolves.
+        // Also remove them from the fragment list, for the same
+        // reason.
+        m_selectedSingletons.clear();
+        for (Entry<String, List<BundleRevision>> entry : m_singletons.entrySet())
         {
-            List<BundleCapability> caps =
-                (Util.isFragment(br) || (br.getWiring() == null))
-                    ? br.getDeclaredCapabilities(null)
-                    : br.getWiring().getCapabilities(null);
-            if (caps != null)
+            for (BundleRevision singleton : entry.getValue())
             {
-                for (BundleCapability cap : caps)
+                if (singleton.getWiring() == null)
                 {
-                    // If the capability is from a different revision, then
-                    // don't index it since it is a capability from a fragment.
-                    // In that case, the fragment capability is still indexed.
-                    // It will be the resolver's responsibility to find all
-                    // attached hosts for fragments.
-                    if (cap.getRevision() == br)
-                    {
-                        CapabilitySet capSet = m_capSets.get(cap.getNamespace());
-                        if (capSet == null)
-                        {
-                            capSet = new CapabilitySet(null, true);
-                            m_capSets.put(cap.getNamespace(), capSet);
-                        }
-                        capSet.addCapability(cap);
-                    }
+                    deindexCapabilities(singleton);
+                    m_fragments.remove(singleton);
                 }
             }
         }
 
-        private synchronized void deindexCapabilities(BundleRevision br)
+        // If no resolver hooks, then use default singleton selection
+        // algorithm, otherwise defer to the resolver hooks.
+        if (record.getResolverHookRefs().isEmpty())
         {
-            // We only need be concerned with declared capabilities here,
-            // because resolved capabilities will be a subset, since fragment
-            // capabilities are not considered to be part of the host.
-            List<BundleCapability> caps = br.getDeclaredCapabilities(null);
-            if (caps != null)
-            {
-                for (BundleCapability cap : caps)
-                {
-                    CapabilitySet capSet = m_capSets.get(cap.getNamespace());
-                    if (capSet != null)
-                    {
-                        capSet.removeCapability(cap);
-                    }
-                }
-            }
+            selectDefaultSingletons(record);
         }
-
-        synchronized void removeRevision(BundleRevision br)
+        else
         {
-            if (m_revisions.remove(br))
-            {
-                m_fragments.remove(br);
-                deindexCapabilities(br);
+            selectSingletonsUsingHooks(record);
+        }
+    }
 
-                // If this module is a singleton, then remove it from the
-                // singleton map.
-                List<BundleRevision> revisions = m_singletons.get(br.getSymbolicName());
-                if (revisions != null)
-                {
-                    revisions.remove(br);
-                    if (revisions.isEmpty())
-                    {
-                        m_singletons.remove(br.getSymbolicName());
-                    }
-                }
-            }
+    /*
+     * Selects the singleton with the highest version from groupings
+     * based on the symbolic name. No selection is made if the group
+     * already has a resolved singleton.
+     */
+    private void selectDefaultSingletons(ResolverHookRecord record)
+    {
+        // Now select the singletons available for this resolve operation.
+        for (Entry<String, List<BundleRevision>> entry : m_singletons.entrySet())
+        {
+            selectSingleton(record, entry.getValue());
         }
+    }
 
-        synchronized Set<BundleRevision> getFragments()
+    /*
+     * Groups singletons based on resolver hook filtering and then selects
+     * the singleton from each group with the highest version that is in
+     * the resolver hook whitelist. No selection is made if a group already
+     * has a resolved singleton in it.
+     */
+    private void selectSingletonsUsingHooks(ResolverHookRecord record)
+        throws BundleException
+    {
+        // Convert singleton bundle revision map into a map using
+        // bundle capabilities instead, since this is what the resolver
+        // hooks require.
+        Map<BundleCapability, Collection<BundleCapability>> allCollisions
+            = new HashMap<BundleCapability, Collection<BundleCapability>>();
+        for (Entry<String, List<BundleRevision>> entry : m_singletons.entrySet())
         {
-            Set<BundleRevision> fragments = new HashSet(m_fragments);
-            // Filter out any fragments that are not the current revision.
-            for (Iterator<BundleRevision> it = fragments.iterator(); it.hasNext(); )
+            Collection<BundleCapability> bundleCaps =
+                new ArrayList<BundleCapability>();
+            for (BundleRevision br : entry.getValue())
             {
-                BundleRevision fragment = it.next();
-                BundleRevision currentFragmentRevision =
-                    fragment.getBundle().adapt(BundleRevision.class);
-                if (fragment != currentFragmentRevision)
+                List<BundleCapability> caps =
+                    br.getDeclaredCapabilities(BundleRevision.BUNDLE_NAMESPACE);
+                if (!caps.isEmpty())
                 {
-                    it.remove();
+                    bundleCaps.add(caps.get(0));
                 }
             }
-            return fragments;
-        }
 
-        synchronized boolean isSelectedSingleton(BundleRevision br)
-        {
-            return m_selectedSingletons.contains(br);
+            for (BundleCapability bc : bundleCaps)
+            {
+                Collection<BundleCapability> capCopy =
+                    new ShrinkableCollection<BundleCapability>(
+                        new ArrayList<BundleCapability>(bundleCaps));
+                capCopy.remove(bc);
+                allCollisions.put(bc, capCopy);
+            }
         }
 
-        synchronized void selectSingletons()
-            throws BundleException
+        // Invoke hooks to allow them to filter singleton collisions.
+        for (ResolverHook hook : record.getResolverHooks())
         {
-            // First deindex any unresolved singletons to make sure
-            // there aren't any available from previous resolves.
-            // Also remove them from the fragment list, for the same
-            // reason.
-            m_selectedSingletons.clear();
-            for (Entry<String, List<BundleRevision>> entry : m_singletons.entrySet())
+            for (Entry<BundleCapability, Collection<BundleCapability>> entry
+                : allCollisions.entrySet())
             {
-                for (BundleRevision singleton : entry.getValue())
+                try
                 {
-                    if (singleton.getWiring() == null)
-                    {
-                        deindexCapabilities(singleton);
-                        m_fragments.remove(singleton);
-                    }
+                    Felix.m_secureAction
+                        .invokeResolverHookSingleton(hook, entry.getKey(), entry.getValue());
+                }
+                catch (Throwable ex)
+                {
+                    throw new BundleException(
+                        "Resolver hook exception: " + ex.getMessage(),
+                        BundleException.REJECTED_BY_HOOK,
+                        ex);
                 }
             }
+        }
 
-            // If no resolver hooks, then use default singleton selection
-            // algorithm, otherwise defer to the resolver hooks.
-            if (m_hooks.isEmpty())
-            {
-                selectDefaultSingletons();
-            }
-            else
-            {
-                selectSingletonsUsingHooks();
-            }
+        // Create groups according to how the resolver hooks filtered the
+        // collisions.
+        List<List<BundleRevision>> groups = new ArrayList<List<BundleRevision>>();
+        while (!allCollisions.isEmpty())
+        {
+            BundleCapability target = allCollisions.entrySet().iterator().next().getKey();
+            groups.add(groupSingletons(allCollisions, target, new ArrayList<BundleRevision>()));
         }
 
-        /*
-         * Selects the singleton with the highest version from groupings
-         * based on the symbolic name. No selection is made if the group
-         * already has a resolved singleton.
-         */
-        private void selectDefaultSingletons()
+        // Now select the singletons available for this resolve operation.
+        for (List<BundleRevision> group : groups)
         {
-            // Now select the singletons available for this resolve operation.
-            for (Entry<String, List<BundleRevision>> entry : m_singletons.entrySet())
-            {
-                selectSingleton(entry.getValue());
-            }
+            selectSingleton(record, group);
         }
+    }
 
-        /*
-         * Groups singletons based on resolver hook filtering and then selects
-         * the singleton from each group with the highest version that is in
-         * the resolver hook whitelist. No selection is made if a group already
-         * has a resolved singleton in it.
-         */
-        private void selectSingletonsUsingHooks()
-            throws BundleException
+    private List<BundleRevision> groupSingletons(
+        Map<BundleCapability, Collection<BundleCapability>> allCollisions,
+        BundleCapability target, List<BundleRevision> group)
+    {
+        if (!group.contains(target.getRevision()))
         {
-            // Convert singleton bundle revision map into a map using
-            // bundle capabilities instead, since this is what the resolver
-            // hooks require.
-            Map<BundleCapability, Collection<BundleCapability>> allCollisions
-                = new HashMap<BundleCapability, Collection<BundleCapability>>();
-            for (Entry<String, List<BundleRevision>> entry : m_singletons.entrySet())
-            {
-                Collection<BundleCapability> bundleCaps =
-                    new ArrayList<BundleCapability>();
-                for (BundleRevision br : entry.getValue())
-                {
-                    List<BundleCapability> caps =
-                        br.getDeclaredCapabilities(BundleRevision.BUNDLE_NAMESPACE);
-                    if (!caps.isEmpty())
-                    {
-                        bundleCaps.add(caps.get(0));
-                    }
-                }
+            // Add the target since it is implicitly part of the group.
+            group.add(target.getRevision());
 
-                for (BundleCapability bc : bundleCaps)
-                {
-                    Collection<BundleCapability> capCopy =
-                        new ShrinkableCollection<BundleCapability>(
-                            new ArrayList<BundleCapability>(bundleCaps));
-                    capCopy.remove(bc);
-                    allCollisions.put(bc, capCopy);
-                }
+            // Recursively add the revisions of any singleton's in the
+            // target's collisions.
+            Collection<BundleCapability> collisions = allCollisions.remove(target);
+            for (BundleCapability collision : collisions)
+            {
+                groupSingletons(allCollisions, collision, group);
             }
 
-            // Invoke hooks to allow them to filter singleton collisions.
-            for (ResolverHook hook : m_hooks)
+            // Need to check the values of other collisions for this target
+            // and add those to the target's group too, since collisions are
+            // treated as two-way relationships. Repeat until there are no
+            // collision groups left that contain the target capability.
+            boolean repeat;
+            do
             {
-                for (Entry<BundleCapability, Collection<BundleCapability>> entry
-                    : allCollisions.entrySet())
+                repeat = false;
+                for (Entry<BundleCapability, Collection<BundleCapability>> entry:
+                    allCollisions.entrySet())
                 {
-                    try
-                    {
-                        Felix.m_secureAction
-                            .invokeResolverHookSingleton(hook, entry.getKey(), entry.getValue());
-                    }
-                    catch (Throwable ex)
+                    if (entry.getValue().contains(target))
                     {
-                        throw new BundleException(
-                            "Resolver hook exception: " + ex.getMessage(),
-                            BundleException.REJECTED_BY_HOOK,
-                            ex);
+                        repeat = true;
+                        groupSingletons(allCollisions, entry.getKey(), group);
+                        break;
                     }
                 }
             }
+            while (repeat);
+        }
+        return group;
+    }
 
-            // Create groups according to how the resolver hooks filtered the
-            // collisions.
-            List<List<BundleRevision>> groups = new ArrayList<List<BundleRevision>>();
-            while (!allCollisions.isEmpty())
+    /*
+     * Selects the highest bundle revision from the group that is
+     * in the resolver hook whitelist (if there are hooks). No
+     * selection is made if there is an already resolved singleton
+     * in the group, since it is already indexed.
+     */
+    private void selectSingleton(ResolverHookRecord record, List<BundleRevision> singletons)
+    {
+        BundleRevision selected = null;
+        for (BundleRevision singleton : singletons)
+        {
+            // If a singleton is already resolved,
+            // then there is nothing to do.
+            if (singleton.getWiring() != null)
             {
-                BundleCapability target = allCollisions.entrySet().iterator().next().getKey();
-                groups.add(groupSingletons(allCollisions, target, new ArrayList<BundleRevision>()));
+                selected = null;
+                break;
             }
-
-            // Now select the singletons available for this resolve operation.
-            for (List<BundleRevision> group : groups)
+            // If this singleton is not in the whitelist, then it cannot
+            // be selected. If it is, in can only be selected if it has
+            // a higher version than the currently selected singleton, if
+            // there is one.
+            if (((record.getBundleRevisionWhitelist() == null) || record.getBundleRevisionWhitelist().contains(singleton))
+                && ((selected == null)
+                    || (selected.getVersion().compareTo(singleton.getVersion()) > 0)))
             {
-                selectSingleton(group);
+                selected = singleton;
             }
         }
-
-        private List<BundleRevision> groupSingletons(
-            Map<BundleCapability, Collection<BundleCapability>> allCollisions,
-            BundleCapability target, List<BundleRevision> group)
+        if (selected != null)
         {
-            if (!group.contains(target.getRevision()))
+            // Record the selected singleton.
+            m_selectedSingletons.add(selected);
+            // Index its capabilities.
+            indexCapabilities(selected);
+            // If the selected singleton is a fragment, then
+            // add it to the list of fragments.
+            if (Util.isFragment(selected))
             {
-                // Add the target since it is implicitly part of the group.
-                group.add(target.getRevision());
-
-                // Recursively add the revisions of any singleton's in the
-                // target's collisions.
-                Collection<BundleCapability> collisions = allCollisions.remove(target);
-                for (BundleCapability collision : collisions)
-                {
-                    groupSingletons(allCollisions, collision, group);
-                }
-
-                // Need to check the values of other collisions for this target
-                // and add those to the target's group too, since collisions are
-                // treated as two-way relationships. Repeat until there are no
-                // collision groups left that contain the target capability.
-                boolean repeat;
-                do
-                {
-                    repeat = false;
-                    for (Entry<BundleCapability, Collection<BundleCapability>> entry:
-                        allCollisions.entrySet())
-                    {
-                        if (entry.getValue().contains(target))
-                        {
-                            repeat = true;
-                            groupSingletons(allCollisions, entry.getKey(), group);
-                            break;
-                        }
-                    }
-                }
-                while (repeat);
+                m_fragments.add(selected);
             }
-            return group;
         }
+    }
 
-        /*
-         * Selects the highest bundle revision from the group that is
-         * in the resolver hook whitelist (if there are hooks). No
-         * selection is made if there is an already resolved singleton
-         * in the group, since it is already indexed.
-         */
-        private void selectSingleton(List<BundleRevision> singletons)
+    private synchronized Set<BundleRevision> getFragments()
+    {
+        Set<BundleRevision> fragments = new HashSet(m_fragments);
+        // Filter out any fragments that are not the current revision.
+        for (Iterator<BundleRevision> it = fragments.iterator(); it.hasNext(); )
         {
-            BundleRevision selected = null;
-            for (BundleRevision singleton : singletons)
-            {
-                // If a singleton is already resolved,
-                // then there is nothing to do.
-                if (singleton.getWiring() != null)
-                {
-                    selected = null;
-                    break;
-                }
-                // If this singleton is not in the whitelist, then it cannot
-                // be selected. If it is, in can only be selected if it has
-                // a higher version than the currently selected singleton, if
-                // there is one.
-                if (((m_whitelist == null) || m_whitelist.contains(singleton))
-                    && ((selected == null)
-                        || (selected.getVersion().compareTo(singleton.getVersion()) > 0)))
-                {
-                    selected = singleton;
-                }
-            }
-            if (selected != null)
+            BundleRevision fragment = it.next();
+            BundleRevision currentFragmentRevision =
+                fragment.getBundle().adapt(BundleRevision.class);
+            if (fragment != currentFragmentRevision)
             {
-                // Record the selected singleton.
-                m_selectedSingletons.add(selected);
-                // Index its capabilities.
-                indexCapabilities(selected);
-                // If the selected singleton is a fragment, then
-                // add it to the list of fragments.
-                if (Util.isFragment(selected))
-                {
-                    m_fragments.add(selected);
-                }
+                it.remove();
             }
         }
+        return fragments;
+    }
 
-        //
-        // ResolverState methods.
-        //
-
-        public boolean isEffective(BundleRequirement req)
-        {
-            String effective = req.getDirectives().get(Constants.EFFECTIVE_DIRECTIVE);
-            return ((effective == null) || effective.equals(Constants.EFFECTIVE_RESOLVE));
-        }
-
-        public synchronized SortedSet<BundleCapability> getCandidates(
-            BundleRequirement req, boolean obeyMandatory)
+    void checkNativeLibraries(BundleRevision revision) throws ResolveException
+    {
+        // Next, try to resolve any native code, since the revision is
+        // not resolvable if its native code cannot be loaded.
+        List<R4Library> libs = ((BundleRevisionImpl) revision).getDeclaredNativeLibraries();
+        if (libs != null)
         {
-            BundleRevisionImpl reqRevision = (BundleRevisionImpl) req.getRevision();
-            SortedSet<BundleCapability> result =
-                new TreeSet<BundleCapability>(new CandidateComparator());
-
-            CapabilitySet capSet = m_capSets.get(req.getNamespace());
-            if (capSet != null)
+            String msg = null;
+            // Verify that all native libraries exist in advance; this will
+            // throw an exception if the native library does not exist.
+            for (int libIdx = 0; (msg == null) && (libIdx < libs.size()); libIdx++)
             {
-                // Get the requirement's filter; if this is our own impl we
-                // have a shortcut to get the already parsed filter, otherwise
-                // we must parse it from the directive.
-                SimpleFilter sf = null;
-                if (req instanceof BundleRequirementImpl)
-                {
-                    sf = ((BundleRequirementImpl) req).getFilter();
-                }
-                else
-                {
-                    String filter = req.getDirectives().get(Constants.FILTER_DIRECTIVE);
-                    if (filter == null)
-                    {
-                        sf = new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
-                    }
-                    else
-                    {
-                        sf = SimpleFilter.parse(filter);
-                    }
-                }
-
-                // Find the matching candidates.
-                Set<BundleCapability> matches = capSet.match(sf, obeyMandatory);
-                // Filter matching candidates.
-                for (BundleCapability cap : matches)
+                String entryName = libs.get(libIdx).getEntryName();
+                if (entryName != null)
                 {
-                    // Filter according to security.
-                    if (filteredBySecurity(req, cap))
-                    {
-                        continue;
-                    }
-                    // Filter already resolved hosts, since we don't support
-                    // dynamic attachment of fragments.
-                    if (req.getNamespace().equals(BundleRevision.HOST_NAMESPACE)
-                        && (cap.getRevision().getWiring() != null))
+                    if (!((BundleRevisionImpl) revision).getContent().hasEntry(entryName))
                     {
-                        continue;
+                        msg = "Native library does not exist: " + entryName;
                     }
-
-                    result.add(cap);
                 }
             }
-
-            // If we have resolver hooks, then we may need to filter our results
-            // based on a whitelist and/or fine-grained candidate filtering.
-            if (!result.isEmpty() && !m_hooks.isEmpty())
+            // If we have a zero-length native library array, then
+            // this means no native library class could be selected
+            // so we should fail to resolve.
+            if (libs.isEmpty())
             {
-                // It we have a whitelist, then first filter out candidates
-                // from disallowed revisions.
-                if (m_whitelist != null)
-                {
-                    for (Iterator<BundleCapability> it = result.iterator(); it.hasNext(); )
-                    {
-                        if (!m_whitelist.contains(it.next().getRevision()))
-                        {
-                            it.remove();
-                        }
-                    }
-                }
-
-                // Now give the hooks a chance to do fine-grained filtering.
-                ShrinkableCollection<BundleCapability> shrinkable =
-                    new ShrinkableCollection<BundleCapability>(result);
-                for (ResolverHook hook : m_hooks)
-                {
-                    try
-                    {
-                        Felix.m_secureAction
-                            .invokeResolverHookMatches(hook, req, shrinkable);
-                    }
-                    catch (Throwable th)
-                    {
-                        m_logger.log(Logger.LOG_WARNING, "Resolver hook exception.", th);
-                    }
-                }
+                msg = "No matching native libraries found.";
             }
-
-            return result;
-        }
-
-        private boolean filteredBySecurity(BundleRequirement req, BundleCapability cap)
-        {
-            if (System.getSecurityManager() != null)
+            if (msg != null)
             {
-                BundleRevisionImpl reqRevision = (BundleRevisionImpl) req.getRevision();
-
-                if (req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-                {
-                    if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
-                        new PackagePermission((String) cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
-                        PackagePermission.EXPORTONLY)) ||
-                        !((reqRevision == null) ||
-                            ((BundleProtectionDomain) reqRevision.getProtectionDomain()).impliesDirect(
-                                new PackagePermission((String) cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
-                                cap.getRevision().getBundle(),PackagePermission.IMPORT))
-                        ))
-                    {
-                        if (reqRevision != cap.getRevision())
-                        {
-                            return true;
-                        }
-                    }
-                }
-                else if (req.getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE))
-                {   if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
-                        new BundlePermission(cap.getRevision().getSymbolicName(), BundlePermission.PROVIDE)) ||
-                        !((reqRevision == null) ||
-                            ((BundleProtectionDomain) reqRevision.getProtectionDomain()).impliesDirect(
-                                new BundlePermission(reqRevision.getSymbolicName(), BundlePermission.REQUIRE))
-                        ))
-                    {
-                        return true;
-                    }
-                }
-                else if (req.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
-                {
-                    if (!((BundleProtectionDomain) reqRevision.getProtectionDomain())
-                        .impliesDirect(new BundlePermission(
-                            reqRevision.getSymbolicName(),
-                            BundlePermission.FRAGMENT))
-                    || !((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain())
-                        .impliesDirect(new BundlePermission(
-                            cap.getRevision().getSymbolicName(),
-                            BundlePermission.HOST)))
-                    {
-                        return true;
-                    }
-                }
-                else  if (!req.getNamespace().equals("osgi.ee"))
-                {
-                    if (!((BundleProtectionDomain) ((BundleRevisionImpl) cap.getRevision()).getProtectionDomain()).impliesDirect(
-                        new CapabilityPermission(req.getNamespace(), CapabilityPermission.PROVIDE))
-                        ||
-                        !((reqRevision == null) || ((BundleProtectionDomain) reqRevision.getProtectionDomain()).impliesDirect(
-                        new CapabilityPermission(req.getNamespace(), cap.getAttributes(), cap.getRevision().getBundle(), CapabilityPermission.REQUIRE))))
-                    {
-                        return true;
-                    }
-                }
+                throw new ResolveException(msg, revision, null);
             }
-            return false;
         }
+    }
 
-        public void checkExecutionEnvironment(BundleRevision revision) throws ResolveException
+    private synchronized Set<BundleRevision> getUnresolvedRevisions()
+    {
+        Set<BundleRevision> unresolved = new HashSet<BundleRevision>();
+        for (BundleRevision revision : m_revisions)
         {
-            String bundleExecEnvStr = (String)
-                ((BundleRevisionImpl) revision).getHeaders().get(
-                    Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT);
-            if (bundleExecEnvStr != null)
+            if (revision.getWiring() == null)
             {
-                bundleExecEnvStr = bundleExecEnvStr.trim();
-
-                // If the bundle has specified an execution environment and the
-                // framework has an execution environment specified, then we must
-                // check for a match.
-                if (!bundleExecEnvStr.equals("")
-                    && (m_fwkExecEnvStr != null)
-                    && (m_fwkExecEnvStr.length() > 0))
-                {
-                    StringTokenizer tokens = new StringTokenizer(bundleExecEnvStr, ",");
-                    boolean found = false;
-                    while (tokens.hasMoreTokens() && !found)
-                    {
-                        if (m_fwkExecEnvSet.contains(tokens.nextToken().trim()))
-                        {
-                            found = true;
-                        }
-                    }
-                    if (!found)
-                    {
-                        throw new ResolveException(
-                            "Execution environment not supported: "
-                            + bundleExecEnvStr, revision, null);
-                    }
-                }
+                unresolved.add(revision);
             }
         }
+        return unresolved;
+    }
 
-        public void checkNativeLibraries(BundleRevision revision) throws ResolveException
+    private synchronized Map<BundleRevision, BundleWiring> getWirings()
+    {
+        Map<BundleRevision, BundleWiring> wirings = new HashMap<BundleRevision, BundleWiring>();
+
+        for (BundleRevision revision : m_revisions)
         {
-            // Next, try to resolve any native code, since the revision is
-            // not resolvable if its native code cannot be loaded.
-            List<R4Library> libs = ((BundleRevisionImpl) revision).getDeclaredNativeLibraries();
-            if (libs != null)
+            if (revision.getWiring() != null)
             {
-                String msg = null;
-                // Verify that all native libraries exist in advance; this will
-                // throw an exception if the native library does not exist.
-                for (int libIdx = 0; (msg == null) && (libIdx < libs.size()); libIdx++)
-                {
-                    String entryName = libs.get(libIdx).getEntryName();
-                    if (entryName != null)
-                    {
-                        if (!((BundleRevisionImpl) revision).getContent().hasEntry(entryName))
-                        {
-                            msg = "Native library does not exist: " + entryName;
-                        }
-                    }
-                }
-                // If we have a zero-length native library array, then
-                // this means no native library class could be selected
-                // so we should fail to resolve.
-                if (libs.isEmpty())
-                {
-                    msg = "No matching native libraries found.";
-                }
-                if (msg != null)
-                {
-                    throw new ResolveException(msg, revision, null);
-                }
+                wirings.put(revision, revision.getWiring());
             }
         }
+        return wirings;
     }
 
-    //
-    // Utility methods.
-    //
-
     /**
      * Updates the framework wide execution environment string and a cached Set of
      * execution environment tokens from the comma delimited list specified by the
@@ -1517,4 +1565,90 @@ class StatefulResolver
         revisions.add(br);
         singletons.put(br.getSymbolicName(), revisions);
     }
-}
\ No newline at end of file
+
+    static class ResolverHookRecord
+    {
+        final Map<ServiceReference<ResolverHookFactory>, ResolverHook> m_resolveHookMap;
+        final Collection<BundleRevision> m_brWhitelist;
+ 
+        /** The map passed in must be of an ordered type, so that the iteration order over the values
+         * is predictable.
+         */
+        ResolverHookRecord(Map<ServiceReference<ResolverHookFactory>, ResolverHook> resolveHookMap,
+            Collection<BundleRevision> brWhiteList)
+        {
+            m_resolveHookMap = resolveHookMap;
+            m_brWhitelist = brWhiteList;
+        }
+        
+        Collection<BundleRevision> getBundleRevisionWhitelist() 
+        {
+            return m_brWhitelist;
+        }
+
+        Set<ServiceReference<ResolverHookFactory>> getResolverHookRefs()
+        {
+            return m_resolveHookMap.keySet();
+        }
+
+        // This slightly over the top implementation to obtain the hooks is to ensure that at the point that
+        // the actual hook is obtained, the service is still registered. There are CT tests that unregister
+        // the hook service while iterating over the hooks and expect that the unregistered hook is not called
+        // in that case.
+        Iterable<ResolverHook> getResolverHooks()
+        {
+            return new Iterable<ResolverHook>()
+            {
+                public Iterator<ResolverHook> iterator()
+                {
+                    return new Iterator<ResolverHook>()
+                    {
+                        private Iterator<Map.Entry<ServiceReference<ResolverHookFactory>, ResolverHook>> it =
+                            m_resolveHookMap.entrySet().iterator();
+                        private Entry<ServiceReference<ResolverHookFactory>, ResolverHook> next = null;
+
+                        public boolean hasNext()
+                        {
+                            if (next == null)
+                                findNext();
+
+                            return next != null;
+                        }
+
+                        public ResolverHook next()
+                        {
+                            if (next == null)
+                                findNext();
+
+                            if (next == null)
+                                throw new NoSuchElementException();
+
+                            ResolverHook hook = next.getValue();
+                            next = null;
+                            return hook;
+                        }
+
+                        // Find the next hook on the iterator, but only if the service is still registered.
+                        // If the service has since been unregistered, skip the hook.
+                        private void findNext()
+                        {
+                            while (it.hasNext())
+                            {
+                                next = it.next();
+                                if (next.getKey().getBundle() != null)
+                                    return;
+                                else
+                                    next = null;
+                            }
+                        }
+
+                        public void remove()
+                        {
+                            throw new UnsupportedOperationException();
+                        }
+                    };
+                }
+            };
+        }
+    }
+}
diff --git a/src/main/java/org/apache/felix/framework/URLHandlers.java b/src/main/java/org/apache/felix/framework/URLHandlers.java
index e3aa475..dfe0828 100644
--- a/src/main/java/org/apache/felix/framework/URLHandlers.java
+++ b/src/main/java/org/apache/felix/framework/URLHandlers.java
@@ -1,4 +1,4 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -85,11 +85,11 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
     private static volatile SecurityManagerEx m_sm = null;
     private static volatile URLHandlers m_handler = null;
 
-    // This maps classloaders of URLHandlers in other classloaders to lists of 
+    // This maps classloaders of URLHandlers in other classloaders to lists of
     // their frameworks.
     private static Map m_classloaderToFrameworkLists = new HashMap();
 
-    // The list to hold all enabled frameworks registered with this handlers 
+    // The list to hold all enabled frameworks registered with this handlers
     private static final List m_frameworks = new ArrayList();
     private static int m_counter = 0;
 
@@ -104,8 +104,8 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
     private static final String m_streamPkgs;
     private static final Map m_builtIn = new HashMap();
     private static final boolean m_loaded;
-    
-    static 
+
+    static
     {
         String pkgs = new SecureAction().getSystemProperty(STREAM_HANDLER_PACKAGE_PROP, "");
         m_streamPkgs = (pkgs.equals(""))
@@ -115,45 +115,74 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
             (null != URLHandlersContentHandlerProxy.class) && (null != URLStreamHandlerService.class);
     }
 
-    
+
     private static final Map m_handlerToURL = new HashMap();
-    private void init(String protocol)
+    private void init(String protocol, URLStreamHandlerFactory factory)
     {
         try
         {
-            m_handlerToURL.put(getBuiltInStreamHandler(protocol, null), new URL(protocol + ":") );
+            URLStreamHandler handler = getBuiltInStreamHandler(protocol, factory);
+            if (handler != null)
+            {
+                URL url = new URL(protocol, null, -1, "", handler);
+                m_handlerToURL.put(handler, url);
+            }
         }
         catch (Throwable ex)
         {
             // Ignore, this is a best effort (maybe log it or something).
         }
     }
-    
+
     /**
      * <p>
-     * Only one instance of this class is created per classloader 
+     * Only one instance of this class is created per classloader
      * and that one instance is registered as the stream and content handler
      * factories for the JVM. Unless, we already register one from a different
      * classloader. In this case we attach to this root.
-     * </p> 
+     * </p>
     **/
     private URLHandlers()
     {
-        init("file");
-        init("ftp");
-        init("http");
-        init("https");
-        try 
-        {
-            getBuiltInStreamHandler("jar", null);
-        }
-        catch (Throwable ex)
-        {
-            // Ignore, this is a best effort (maybe log it or something)
-        }
         m_sm = new SecurityManagerEx();
         synchronized (URL.class)
         {
+            URLStreamHandlerFactory currentFactory = null;
+            try
+            {
+                currentFactory = (URLStreamHandlerFactory) m_secureAction.swapStaticFieldIfNotClass(URL.class,
+                    URLStreamHandlerFactory.class, URLHANDLERS_CLASS, "streamHandlerLock");
+            }
+            catch (Throwable ex)
+            {
+                // Ignore, this is a best effort (maybe log it or something)
+            }
+
+            init("file", currentFactory);
+            init("ftp", currentFactory);
+            init("http", currentFactory);
+            init("https", currentFactory);
+            try
+            {
+                getBuiltInStreamHandler("jar", currentFactory);
+            }
+            catch (Throwable ex)
+            {
+                // Ignore, this is a best effort (maybe log it or something)
+            }
+
+            if (currentFactory != null)
+            {
+                try
+                {
+                    URL.setURLStreamHandlerFactory(currentFactory);
+                }
+                catch (Throwable ex)
+                {
+                    // Ignore, this is a best effort (maybe log it or something)
+                }
+            }
+
             try
             {
                 URL.setURLStreamHandlerFactory(this);
@@ -175,9 +204,9 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
                 {
                     // there already is a factory set so try to swap it with ours.
                     m_streamHandlerFactory = (URLStreamHandlerFactory)
-                        m_secureAction.swapStaticFieldIfNotClass(URL.class, 
+                        m_secureAction.swapStaticFieldIfNotClass(URL.class,
                         URLStreamHandlerFactory.class, URLHANDLERS_CLASS, "streamHandlerLock");
-                    
+
                     if (m_streamHandlerFactory == null)
                     {
                         throw err;
@@ -192,16 +221,16 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
                         try
                         {
                             m_secureAction.invoke(
-                                m_secureAction.getDeclaredMethod(m_streamHandlerFactory.getClass(), 
-                                "registerFrameworkListsForContextSearch", 
-                                new Class[]{ClassLoader.class, List.class}), 
-                                m_streamHandlerFactory, new Object[]{ URLHANDLERS_CLASS.getClassLoader(), 
+                                m_secureAction.getDeclaredMethod(m_streamHandlerFactory.getClass(),
+                                "registerFrameworkListsForContextSearch",
+                                new Class[]{ClassLoader.class, List.class}),
+                                m_streamHandlerFactory, new Object[]{ URLHANDLERS_CLASS.getClassLoader(),
                                     m_frameworks });
                             m_rootURLHandlers = m_streamHandlerFactory;
                         }
                         catch (Exception ex)
                         {
-                            new RuntimeException(ex.getMessage());
+                            throw new RuntimeException(ex.getMessage());
                         }
                     }
                 }
@@ -210,7 +239,7 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
                     throw err;
                 }
             }
-            
+
             try
             {
                 URLConnection.setContentHandlerFactory(this);
@@ -229,10 +258,10 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
             {
                 // there already is a factory set so try to swap it with ours.
                 try
-                {   
-                    m_contentHandlerFactory = (ContentHandlerFactory) 
+                {
+                    m_contentHandlerFactory = (ContentHandlerFactory)
                         m_secureAction.swapStaticFieldIfNotClass(
-                            URLConnection.class, ContentHandlerFactory.class, 
+                            URLConnection.class, ContentHandlerFactory.class,
                             URLHANDLERS_CLASS, null);
                     if (m_contentHandlerFactory == null)
                     {
@@ -260,7 +289,7 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
         }
     }
 
-    static void registerFrameworkListsForContextSearch(ClassLoader index, 
+    static void registerFrameworkListsForContextSearch(ClassLoader index,
         List frameworkLists)
     {
         synchronized (URL.class)
@@ -287,7 +316,7 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
                         {
                             try
                             {
-                                m_secureAction.swapStaticFieldIfNotClass(URL.class, 
+                                m_secureAction.swapStaticFieldIfNotClass(URL.class,
                                     URLStreamHandlerFactory.class, null, "streamHandlerLock");
                             }
                             catch (Exception ex)
@@ -295,7 +324,7 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
                                 // TODO log this
                                 ex.printStackTrace();
                             }
-                            
+
                             if (m_streamHandlerFactory.getClass() != URLHANDLERS_CLASS)
                             {
                                 URL.setURLStreamHandlerFactory(m_streamHandlerFactory);
@@ -303,7 +332,7 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
                             try
                             {
                                 m_secureAction.swapStaticFieldIfNotClass(
-                                    URLConnection.class, ContentHandlerFactory.class, 
+                                    URLConnection.class, ContentHandlerFactory.class,
                                     null, null);
                             }
                             catch (Exception ex)
@@ -311,7 +340,7 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
                                 // TODO log this
                                 ex.printStackTrace();
                             }
-                            
+
                             if (m_contentHandlerFactory.getClass() != URLHANDLERS_CLASS)
                             {
                                 URLConnection.setContentHandlerFactory(m_contentHandlerFactory);
@@ -342,6 +371,15 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
         }
         // Check for built-in handlers for the mime type.
         // Iterate over built-in packages.
+        URLStreamHandler handler = loadBuiltInStreamHandler(protocol, null);
+        if (handler == null)
+        {
+            handler = loadBuiltInStreamHandler(protocol, ClassLoader.getSystemClassLoader());
+        }
+        return addToCache(protocol, handler);
+    }
+
+    private URLStreamHandler loadBuiltInStreamHandler(String protocol, ClassLoader classLoader) {
         StringTokenizer pkgTok = new StringTokenizer(m_streamPkgs, "| ");
         while (pkgTok.hasMoreTokens())
         {
@@ -350,11 +388,10 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
             try
             {
                 // If a built-in handler is found then cache and return it
-                Class handler = m_secureAction.forName(className); 
+                Class handler = m_secureAction.forName(className, classLoader);
                 if (handler != null)
                 {
-                    return addToCache(protocol, 
-                        (URLStreamHandler) handler.newInstance());
+                    return (URLStreamHandler) handler.newInstance();
                 }
             }
             catch (Throwable ex)
@@ -364,19 +401,60 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
                 // case other than ignore it.
             }
         }
-        return addToCache(protocol, null);
+        // This is a workaround for android - Starting with 4.1 the built-in core handler
+        // are not following the normal naming nore package schema :-(
+        String androidHandler = null;
+        if ("file".equalsIgnoreCase(protocol))
+        {
+            androidHandler = "libcore.net.url.FileHandler";
+        }
+        else if ("ftp".equalsIgnoreCase(protocol))
+        {
+            androidHandler = "libcore.net.url.FtpHandler";
+        }
+        else if ("http".equalsIgnoreCase(protocol))
+        {
+            androidHandler = "libcore.net.http.HttpHandler";
+        }
+        else if ("https".equalsIgnoreCase(protocol))
+        {
+            androidHandler = "libcore.net.http.HttpsHandler";
+        }
+        else if ("jar".equalsIgnoreCase(protocol))
+        {
+            androidHandler = "libcore.net.url.JarHandler";
+        }
+        if (androidHandler != null)
+        {
+            try
+            {
+                // If a built-in handler is found then cache and return it
+                Class handler = m_secureAction.forName(androidHandler, classLoader);
+                if (handler != null)
+                {
+                    return (URLStreamHandler) handler.newInstance();
+                }
+            }
+            catch (Throwable ex)
+            {
+                // This could be a class not found exception or an
+                // instantiation exception, not much we can do in either
+                // case other than ignore it.
+            }
+        }
+        return null;
     }
 
     private synchronized URLStreamHandler addToCache(String protocol, URLStreamHandler result)
     {
         if (!m_builtIn.containsKey(protocol))
-        {
-            m_builtIn.put(protocol, result);
-            return result;
-        }
+            {
+                m_builtIn.put(protocol, result);
+                return result;
+            }
         return (URLStreamHandler) m_builtIn.get(protocol);
     }
-    
+
     /**
      * <p>
      * This is a method implementation for the <tt>URLStreamHandlerFactory</tt>
@@ -396,7 +474,7 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
         // handlers and also because caching behavior may not be guaranteed
         // across different JRE implementations.
         URLStreamHandler handler = getFromStreamCache(protocol);
-        
+
         if (handler != null)
         {
             return handler;
@@ -406,16 +484,16 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
         // allowed to deal with it.
         if (protocol.equals(FelixConstants.BUNDLE_URL_PROTOCOL))
         {
-            return addToStreamCache(protocol, 
+            return addToStreamCache(protocol,
                 new URLHandlersBundleStreamHandler(m_secureAction));
         }
 
-       handler = getBuiltInStreamHandler(protocol, 
+       handler = getBuiltInStreamHandler(protocol,
            (m_streamHandlerFactory != this) ? m_streamHandlerFactory : null);
 
         // If built-in content handler, then create a proxy handler.
-        return addToStreamCache(protocol, 
-            new URLHandlersStreamHandlerProxy(protocol, m_secureAction, 
+        return addToStreamCache(protocol,
+            new URLHandlersStreamHandlerProxy(protocol, m_secureAction,
                 handler, (URL) m_handlerToURL.get(handler)));
     }
 
@@ -438,14 +516,14 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
         // handlers and also because caching behavior may not be guaranteed
         // across different JRE implementations.
         ContentHandler handler = getFromContentCache(mimeType);
-        
+
         if (handler != null)
         {
             return handler;
         }
 
-        return addToContentCache(mimeType, 
-            new URLHandlersContentHandlerProxy(mimeType, m_secureAction, 
+        return addToContentCache(mimeType,
+            new URLHandlersContentHandlerProxy(mimeType, m_secureAction,
             (m_contentHandlerFactory != this) ? m_contentHandlerFactory : null));
     }
 
@@ -457,10 +535,10 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
         }
         return (ContentHandler) addToCache(m_contentHandlerCache, mimeType, handler);
     }
-    
+
     private synchronized ContentHandler getFromContentCache(String mimeType)
     {
-        return (ContentHandler) ((m_contentHandlerCache != null) ? 
+        return (ContentHandler) ((m_contentHandlerCache != null) ?
             m_contentHandlerCache.get(mimeType) : null);
     }
 
@@ -472,22 +550,22 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
         }
         return (URLStreamHandler) addToCache(m_streamHandlerCache, protocol, handler);
     }
-    
+
     private synchronized URLStreamHandler getFromStreamCache(String protocol)
     {
-        return (URLStreamHandler) ((m_streamHandlerCache != null) ? 
+        return (URLStreamHandler) ((m_streamHandlerCache != null) ?
             m_streamHandlerCache.get(protocol) : null);
     }
-    
+
     private Object addToCache(Map cache, String key, Object value)
     {
         if (value == null)
         {
             return null;
         }
-        
+
         Object result = cache.get(key);
-            
+
         if (result == null)
         {
             cache.put(key, value);
@@ -542,7 +620,7 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
         {
             m_counter--;
             if (m_frameworks.remove(framework))
-            {    
+            {
                 if (m_frameworks.isEmpty())
                 {
                     unregister = true;
@@ -555,9 +633,9 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
              try
              {
                  m_secureAction.invoke(m_secureAction.getDeclaredMethod(
-                     m_rootURLHandlers.getClass(), 
-                     "unregisterFrameworkListsForContextSearch", 
-                     new Class[]{ ClassLoader.class}), 
+                     m_rootURLHandlers.getClass(),
+                     "unregisterFrameworkListsForContextSearch",
+                     new Class[]{ ClassLoader.class}),
                      m_rootURLHandlers,
                      new Object[] {URLHANDLERS_CLASS.getClassLoader()});
              }
@@ -602,18 +680,19 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
         Class targetClass = null;
         for (int i = 0; i < stack.length; i++)
         {
-            if (stack[i].getClassLoader() != null) 
+            if (stack[i].getClassLoader() != null)
             {
                 String name = stack[i].getClassLoader().getClass().getName();
                 if (name.startsWith("org.apache.felix.framework.ModuleImpl$ModuleClassLoader")
-                    || name.equals("org.apache.felix.framework.searchpolicy.ContentClassLoader"))
+                    || name.equals("org.apache.felix.framework.searchpolicy.ContentClassLoader")
+                    || name.startsWith("org.apache.felix.framework.BundleWiringImpl$BundleClassLoader"))
                 {
                     targetClass = stack[i];
                     break;
                 }
             }
         }
-        
+
         // If we found a class loaded from a bundle, then iterate
         // over the framework instances and see which framework owns
         // the bundle that loaded the class.
@@ -622,11 +701,11 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
             synchronized (m_classloaderToFrameworkLists)
             {
                 ClassLoader index = targetClass.getClassLoader().getClass().getClassLoader();
-                
+
                 List frameworks = (List) m_classloaderToFrameworkLists.get(
                     index);
-                
-                if ((frameworks == null) && (index == URLHANDLERS_CLASS.getClassLoader())) 
+
+                if ((frameworks == null) && (index == URLHANDLERS_CLASS.getClassLoader()))
                 {
                     frameworks = m_frameworks;
                 }
@@ -641,7 +720,7 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
                             try
                             {
                                 if (m_secureAction.invoke(
-                                    m_secureAction.getDeclaredMethod(framework.getClass(), 
+                                    m_secureAction.getDeclaredMethod(framework.getClass(),
                                     "getBundle", CLASS_TYPE),
                                     framework, new Object[]{targetClass}) != null)
                                 {
@@ -650,7 +729,7 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
                             }
                             catch (Exception ex)
                             {
-                                // This should not happen but if it does there is 
+                                // This should not happen but if it does there is
                                 // not much we can do other then ignore it.
                                 // Maybe log this or something.
                                 ex.printStackTrace();
@@ -662,4 +741,4 @@ class URLHandlers implements URLStreamHandlerFactory, ContentHandlerFactory
         }
         return null;
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java b/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java
index e701477..091f682 100644
--- a/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java
+++ b/src/main/java/org/apache/felix/framework/URLHandlersBundleStreamHandler.java
@@ -117,6 +117,11 @@ class URLHandlersBundleStreamHandler extends URLStreamHandler
         return result.toString();
     }
     
+    protected java.net.InetAddress getHostAddress(URL u)
+    {
+        return null;
+    }
+
     private boolean checkPermission(URL u)
     {
         SecurityManager sm = System.getSecurityManager();
@@ -146,4 +151,4 @@ class URLHandlersBundleStreamHandler extends URLStreamHandler
         }
         return false;
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java b/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java
index 4d51311..354fab8 100644
--- a/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java
+++ b/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java
@@ -1,4 +1,4 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -56,11 +56,11 @@ class URLHandlersContentHandlerProxy extends ContentHandler
 
     private static final String CONTENT_HANDLER_PACKAGE_PROP = "java.content.handler.pkgs";
     private static final String DEFAULT_CONTENT_HANDLER_PACKAGE = "sun.net.www.content|com.ibm.oti.net.www.content|gnu.java.net.content|org.apache.harmony.luni.internal.net.www.content|COM.newmonics.www.content";
-    
+
     private static final Map m_builtIn = new HashMap();
     private static final String m_pkgs;
 
-    static 
+    static
     {
         String pkgs = new SecureAction().getSystemProperty(CONTENT_HANDLER_PACKAGE_PROP, "");
         m_pkgs = (pkgs.equals(""))
@@ -73,13 +73,13 @@ class URLHandlersContentHandlerProxy extends ContentHandler
     private final String m_mimeType;
     private final SecureAction m_action;
 
-    public URLHandlersContentHandlerProxy(String mimeType, SecureAction action, 
+    public URLHandlersContentHandlerProxy(String mimeType, SecureAction action,
         ContentHandlerFactory factory)
     {
         m_mimeType = mimeType;
         m_action = action;
         m_factory = factory;
-    } 
+    }
 
     //
     // ContentHandler interface method.
@@ -111,11 +111,11 @@ class URLHandlersContentHandlerProxy extends ContentHandler
         // Get the framework instance associated with call stack.
         Object framework = URLHandlers.getFrameworkFromContext();
 
-        if (framework == null) 
+        if (framework == null)
         {
             return getBuiltIn();
         }
-        try 
+        try
         {
             ContentHandler service;
             if (framework instanceof Felix)
@@ -125,10 +125,10 @@ class URLHandlersContentHandlerProxy extends ContentHandler
             else
             {
                 service = (ContentHandler) m_action.invoke(
-                    m_action.getMethod(framework.getClass(), "getContentHandlerService", STRING_TYPES),
+                    m_action.getDeclaredMethod(framework.getClass(), "getContentHandlerService", STRING_TYPES),
                     framework, new Object[]{m_mimeType});
             }
-            
+
             return (service == null) ? getBuiltIn() : service;
         }
         catch (Exception ex)
@@ -169,10 +169,10 @@ class URLHandlersContentHandlerProxy extends ContentHandler
             try
             {
                 // If a built-in handler is found then cache and return it
-                Class handler = m_action.forName(className); 
+                Class handler = m_action.forName(className, null);
                 if (handler != null)
                 {
-                    return addToCache(m_mimeType, 
+                    return addToCache(m_mimeType,
                         (ContentHandler) handler.newInstance());
                 }
             }
diff --git a/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java b/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java
index debd1fb..de4fea1 100644
--- a/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java
+++ b/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java
@@ -1,4 +1,4 @@
-/* 
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -69,21 +69,21 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
     private static final Method OPEN_CONNECTION_PROXY;
     private static final Method SAME_FILE;
     private static final Method TO_EXTERNAL_FORM;
-    
+
     static {
         SecureAction action = new SecureAction();
         try
         {
-            EQUALS = URLStreamHandler.class.getDeclaredMethod("equals", 
+            EQUALS = URLStreamHandler.class.getDeclaredMethod("equals",
                 new Class[]{URL.class, URL.class});
             action.setAccesssible(EQUALS);
-            GET_DEFAULT_PORT = URLStreamHandler.class.getDeclaredMethod("getDefaultPort", 
+            GET_DEFAULT_PORT = URLStreamHandler.class.getDeclaredMethod("getDefaultPort",
                 (Class[]) null);
             action.setAccesssible(GET_DEFAULT_PORT);
             GET_HOST_ADDRESS = URLStreamHandler.class.getDeclaredMethod(
                     "getHostAddress", new Class[]{URL.class});
             action.setAccesssible(GET_HOST_ADDRESS);
-            HASH_CODE = URLStreamHandler.class.getDeclaredMethod( 
+            HASH_CODE = URLStreamHandler.class.getDeclaredMethod(
                     "hashCode", new Class[]{URL.class});
             action.setAccesssible(HASH_CODE);
             HOSTS_EQUAL = URLStreamHandler.class.getDeclaredMethod(
@@ -95,7 +95,7 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
             SAME_FILE = URLStreamHandler.class.getDeclaredMethod(
                     "sameFile", new Class[]{URL.class, URL.class});
             action.setAccesssible(SAME_FILE);
-            TO_EXTERNAL_FORM = URLStreamHandler.class.getDeclaredMethod( 
+            TO_EXTERNAL_FORM = URLStreamHandler.class.getDeclaredMethod(
                    "toExternalForm", new Class[]{URL.class});
             action.setAccesssible(TO_EXTERNAL_FORM);
         }
@@ -115,7 +115,7 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         }
         catch (Throwable ex)
         {
-           open_connection_proxy = null; 
+           open_connection_proxy = null;
            url_proxy_class = null;
         }
         OPEN_CONNECTION_PROXY = open_connection_proxy;
@@ -128,7 +128,7 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
     private final URL m_builtInURL;
     private final String m_protocol;
 
-    public URLHandlersStreamHandlerProxy(String protocol, 
+    public URLHandlersStreamHandlerProxy(String protocol,
         SecureAction action, URLStreamHandler builtIn, URL builtInURL)
     {
         m_protocol = protocol;
@@ -137,7 +137,7 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         m_builtIn = builtIn;
         m_builtInURL = builtInURL;
     }
-    
+
     private URLHandlersStreamHandlerProxy(Object service, SecureAction action)
     {
         m_protocol = null;
@@ -162,11 +162,11 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         {
             return ((URLStreamHandlerService) svc).equals(url1, url2);
         }
-        try 
+        try
         {
             return ((Boolean) EQUALS.invoke(svc, new Object[]{url1, url2})).booleanValue();
-        } 
-        catch (Exception ex)  
+        }
+        catch (Exception ex)
         {
             throw new IllegalStateException("Stream handler unavailable due to: " + ex.getMessage());
         }
@@ -183,11 +183,11 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         {
             return ((URLStreamHandlerService) svc).getDefaultPort();
         }
-        try 
+        try
         {
             return ((Integer) GET_DEFAULT_PORT.invoke(svc, null)).intValue();
-        } 
-        catch (Exception ex)  
+        }
+        catch (Exception ex)
         {
             throw new IllegalStateException("Stream handler unavailable due to: " + ex.getMessage());
         }
@@ -205,11 +205,11 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         {
             return ((URLStreamHandlerService) svc).getHostAddress(url);
         }
-        try 
+        try
         {
             return (InetAddress) GET_HOST_ADDRESS.invoke(svc, new Object[]{url});
-        } 
-        catch (Exception ex)  
+        }
+        catch (Exception ex)
         {
             throw new IllegalStateException("Stream handler unavailable due to: " + ex.getMessage());
         }
@@ -227,11 +227,11 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         {
             return ((URLStreamHandlerService) svc).hashCode(url);
         }
-        try 
+        try
         {
             return ((Integer) HASH_CODE.invoke(svc, new Object[]{url})).intValue();
-        } 
-        catch (Exception ex)  
+        }
+        catch (Exception ex)
         {
             throw new IllegalStateException("Stream handler unavailable due to: " + ex.getMessage());
         }
@@ -249,11 +249,11 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         {
             return ((URLStreamHandlerService) svc).hostsEqual(url1, url2);
         }
-        try 
+        try
         {
             return ((Boolean) HOSTS_EQUAL.invoke(svc, new Object[]{url1, url2})).booleanValue();
-        } 
-        catch (Exception ex)  
+        }
+        catch (Exception ex)
         {
             throw new IllegalStateException("Stream handler unavailable due to: " + ex.getMessage());
         }
@@ -270,7 +270,7 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         {
             return ((URLStreamHandlerService) svc).openConnection(url);
         }
-        try 
+        try
         {
             if ("http".equals(url.getProtocol()) &&
                 "felix.extensions".equals(url.getHost()) &&
@@ -280,15 +280,15 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
                 {
                     Object handler =  m_action.getDeclaredField(
                         ExtensionManager.class, "m_extensionManager", null);
-    
+
                     if (handler != null)
                     {
                         return (URLConnection) m_action.invoke(
-                            m_action.getMethod(handler.getClass(), 
-                            "openConnection", new Class[]{URL.class}), handler, 
+                            m_action.getMethod(handler.getClass(),
+                            "openConnection", new Class[]{URL.class}), handler,
                             new Object[]{url});
                     }
-                    
+
                     throw new IOException("Extensions not supported or ambiguous context.");
                 }
                 catch (IOException ex)
@@ -301,12 +301,12 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
                 }
             }
             return (URLConnection) OPEN_CONNECTION.invoke(svc, new Object[]{url});
-        } 
+        }
         catch (IOException ex)
         {
             throw ex;
         }
-        catch (Exception ex)  
+        catch (Exception ex)
         {
             throw new IllegalStateException("Stream handler unavailable due to: " + ex.getMessage());
         }
@@ -322,22 +322,22 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         if (svc instanceof URLStreamHandlerService)
         {
             Method method;
-            try 
+            try
             {
                 method = svc.getClass().getMethod("openConnection", URL_PROXY_CLASS);
-            } 
-            catch (NoSuchMethodException e) 
+            }
+            catch (NoSuchMethodException e)
             {
                 RuntimeException rte = new UnsupportedOperationException(e.getMessage());
                 rte.initCause(e);
                 throw rte;
             }
-            try 
+            try
             {
                 m_action.setAccesssible(method);
                 return (URLConnection) method.invoke(svc, new Object[]{url, proxy});
             }
-            catch (Exception e) 
+            catch (Exception e)
             {
                 if (e instanceof IOException)
                 {
@@ -346,11 +346,11 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
                 throw new IOException(e.getMessage());
             }
         }
-        try 
+        try
         {
             return (URLConnection) OPEN_CONNECTION_PROXY.invoke(svc, new Object[]{url, proxy});
-        } 
-        catch (Exception ex)  
+        }
+        catch (Exception ex)
         {
             if (ex instanceof IOException)
             {
@@ -360,7 +360,7 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         }
     }
 
-    // We use this thread local to detect whether we have a reentrant entry to the parseURL 
+    // We use this thread local to detect whether we have a reentrant entry to the parseURL
     // method. This can happen do to some difference between gnu/classpath and sun jvms
     // For more see inside the method.
     private static final ThreadLocal m_loopCheck = new ThreadLocal();
@@ -378,22 +378,22 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         }
         else
         {
-            try 
+            try
             {
                 URL test = null;
-                // In order to cater for built-in urls being over-writable we need to use a 
+                // In order to cater for built-in urls being over-writable we need to use a
                 // somewhat strange hack. We use a hidden feature inside the jdk which passes
                 // the handler of the url given as a context to a new URL to that URL as its
                 // handler. This way, we can create a new URL which will use the given built-in
                 // handler to parse the url. Subsequently, we can use the information from that
-                // URL to call set with the correct values. 
+                // URL to call set with the correct values.
                 if (m_builtInURL != null)
                 {
                     // However, if we are on gnu/classpath we have to pass the handler directly
                     // because the hidden feature is not there. Funnily, the workaround to pass
                     // pass the handler directly doesn't work on sun as their handler detects
                     // that it is not the same as the one inside the url and throws an exception
-                    // Luckily it doesn't do that on gnu/classpath. We detect that we need to 
+                    // Luckily it doesn't do that on gnu/classpath. We detect that we need to
                     // pass the handler directly by using the m_loopCheck thread local to detect
                     // that we parseURL has been called inside a call to parseURL.
                     if (m_loopCheck.get() != null)
@@ -418,15 +418,15 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
                 else
                 {
                     // We don't have a url with a built-in handler for this but still want to create
-                    // the url with the buil-in handler as we could find one now. This might not 
-                    // work for all handlers on sun but it is better then doing nothing. 
+                    // the url with the buil-in handler as we could find one now. This might not
+                    // work for all handlers on sun but it is better then doing nothing.
                     test = m_action.createURL(url, spec, (URLStreamHandler) svc);
                 }
 
-                super.setURL(url, test.getProtocol(), test.getHost(), test.getPort(),test.getAuthority(), 
+                super.setURL(url, test.getProtocol(), test.getHost(), test.getPort(),test.getAuthority(),
                     test.getUserInfo(), test.getPath(), test.getQuery(), test.getRef());
-            } 
-            catch (Exception ex)  
+            }
+            catch (Exception ex)
             {
                 throw new IllegalStateException("Stream handler unavailable due to: " + ex.getMessage());
             }
@@ -445,12 +445,12 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         {
             return ((URLStreamHandlerService) svc).sameFile(url1, url2);
         }
-        try 
+        try
         {
-            return ((Boolean) SAME_FILE.invoke( 
+            return ((Boolean) SAME_FILE.invoke(
                 svc, new Object[]{url1, url2})).booleanValue();
-        } 
-        catch (Exception ex)  
+        }
+        catch (Exception ex)
         {
             throw new IllegalStateException("Stream handler unavailable due to: " + ex.getMessage());
         }
@@ -473,7 +473,7 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
     {
         return toExternalForm(url, getStreamHandlerService());
     }
-    
+
     private String toExternalForm(URL url, Object svc)
     {
         if (svc == null)
@@ -487,18 +487,18 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         }
         try
         {
-            try 
+            try
             {
-                String result = (String) TO_EXTERNAL_FORM.invoke( 
+                String result = (String) TO_EXTERNAL_FORM.invoke(
                     svc, new Object[]{url});
-                
-                // mika does return an invalid format if we have a url with the 
+
+                // mika does return an invalid format if we have a url with the
                 // protocol only (<proto>://null) - we catch this case now
                 if ((result != null) && (result.equals(url.getProtocol() + "://null")))
                 {
                     result = url.getProtocol() + ":";
                 }
-                
+
                 return result;
             }
             catch (InvocationTargetException ex)
@@ -521,16 +521,16 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         catch (NullPointerException ex)
         {
             // workaround for harmony and possibly J9. The issue is that
-            // their implementation of URLStreamHandler.toExternalForm() 
+            // their implementation of URLStreamHandler.toExternalForm()
             // assumes that URL.getFile() doesn't return null but in our
             // case it can -- hence, we catch the NPE and do the work
             // ourselvs. The only difference is that we check whether the
-            // URL.getFile() is null or not. 
+            // URL.getFile() is null or not.
             StringBuffer answer = new StringBuffer();
             answer.append(url.getProtocol());
             answer.append(':');
             String authority = url.getAuthority();
-            if ((authority != null) && (authority.length() > 0)) 
+            if ((authority != null) && (authority.length() > 0))
             {
                 answer.append("//"); //$NON-NLS-1$
                 answer.append(url.getAuthority());
@@ -542,19 +542,19 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
             {
                 answer.append(file);
             }
-            if (ref != null) 
+            if (ref != null)
             {
                 answer.append('#');
                 answer.append(ref);
             }
             return answer.toString();
         }
-        catch (Exception ex)  
+        catch (Exception ex)
         {
             throw new IllegalStateException("Stream handler unavailable due to: " + ex.getMessage());
         }
     }
-    
+
     /**
      * <p>
      * Private method to retrieve the stream handler service from the
@@ -572,12 +572,13 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         {
             // Get the framework instance associated with call stack.
             Object framework = URLHandlers.getFrameworkFromContext();
-    
-            if (framework == null) 
+         
+            if (framework == null)
             {
                 return m_builtIn;
             }
 
+
             Object service = null;
             if (framework instanceof Felix)
             {
@@ -586,11 +587,11 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
             else
             {
                 service = m_action.invoke(
-                    m_action.getMethod(framework.getClass(), "getStreamHandlerService", STRING_TYPES), 
+                    m_action.getDeclaredMethod(framework.getClass(), "getStreamHandlerService", STRING_TYPES),
                     framework, new Object[]{m_protocol});
             }
 
-            if (service == null) 
+            if (service == null)
             {
                 return m_builtIn;
             }
@@ -599,8 +600,8 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
                 return (URLStreamHandlerService) service;
             }
             return (URLStreamHandlerService) Proxy.newProxyInstance(
-                URLStreamHandlerService.class.getClassLoader(), 
-                new Class[]{URLStreamHandlerService.class}, 
+                URLStreamHandlerService.class.getClassLoader(),
+                new Class[]{URLStreamHandlerService.class},
                 new URLHandlersStreamHandlerProxy(service, m_action));
         }
         catch (ThreadDeath td)
@@ -610,12 +611,12 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
         catch (Throwable t)
         {
             // In case that we are inside tomcat - the problem is that the webapp classloader
-            // creates a new url to load a class. This gets us to this method. Now, if we 
+            // creates a new url to load a class. This gets us to this method. Now, if we
             // trigger a classload while executing tomcat is creating a new url and we end-up with
-            // a loop which is cut short after two iterations (because of a circularclassload). 
+            // a loop which is cut short after two iterations (because of a circularclassload).
             // We catch this exception (and all others) and just return the built-in handler
-            // (if we have any) as this way we at least eventually get started (this just means 
-            // that we don't use the potentially provided built-in handler overwrite). 
+            // (if we have any) as this way we at least eventually get started (this just means
+            // that we don't use the potentially provided built-in handler overwrite).
             return m_builtIn;
         }
     }
@@ -625,18 +626,23 @@ public class URLHandlersStreamHandlerProxy extends URLStreamHandler
     {
         try
         {
+
             Class[] types = method.getParameterTypes();
+            if (m_service == null)
+            {
+                return m_action.invoke(m_action.getMethod(this.getClass(), method.getName(), types), this, params);
+            }
             if ("parseURL".equals(method.getName()))
             {
                 types[0] = m_service.getClass().getClassLoader().loadClass(
                     URLStreamHandlerSetter.class.getName());
                 params[0] = Proxy.newProxyInstance(
-                    m_service.getClass().getClassLoader(), new Class[]{types[0]}, 
+                    m_service.getClass().getClassLoader(), new Class[]{types[0]},
                     (URLHandlersStreamHandlerProxy) params[0]);
             }
-            return m_action.invokeDirect(m_action.getMethod(m_service.getClass(), 
+            return m_action.invokeDirect(m_action.getDeclaredMethod(m_service.getClass(),
                 method.getName(), types), m_service, params);
-        } 
+        }
         catch (Exception ex)
         {
             throw ex;
diff --git a/src/main/java/org/apache/felix/framework/WovenClassImpl.java b/src/main/java/org/apache/felix/framework/WovenClassImpl.java
index 8402d80..2f44e5a 100644
--- a/src/main/java/org/apache/felix/framework/WovenClassImpl.java
+++ b/src/main/java/org/apache/felix/framework/WovenClassImpl.java
@@ -21,14 +21,12 @@ package org.apache.felix.framework;
 import java.security.ProtectionDomain;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
+import org.apache.felix.framework.util.ImmutableList;
 import org.apache.felix.framework.util.manifestparser.ManifestParser;
-import org.apache.felix.framework.util.manifestparser.ParsedHeaderClause;
 import org.osgi.framework.AdminPermission;
-import org.osgi.framework.Constants;
 import org.osgi.framework.hooks.weaving.WovenClass;
 import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleWiring;
@@ -55,8 +53,8 @@ class WovenClassImpl implements WovenClass, List<String>
         m_definedClass = definedClass;
         m_bytes = (bytes == null) ? m_bytes : bytes;
         m_imports = (imports == null)
-            ? Collections.unmodifiableList(m_imports)
-            : Collections.unmodifiableList(imports);
+            ? ImmutableList.newInstance(m_imports)
+            : ImmutableList.newInstance(imports);
     }
 
     public synchronized byte[] getBytes()
@@ -365,7 +363,7 @@ class WovenClassImpl implements WovenClass, List<String>
         return m_imports.subList(i, i1);
     }
 
-    byte[] _getBytes() 
+    byte[] _getBytes()
     {
         byte[] bytes = m_bytes;
         if (m_isComplete)
diff --git a/src/main/java/org/apache/felix/framework/cache/BundleCache.java b/src/main/java/org/apache/felix/framework/cache/BundleCache.java
index b5a81bf..ee44091 100644
--- a/src/main/java/org/apache/felix/framework/cache/BundleCache.java
+++ b/src/main/java/org/apache/felix/framework/cache/BundleCache.java
@@ -426,9 +426,12 @@ public class BundleCache
         if (getSecureAction().isFileDirectory(target))
         {
             File[] files = getSecureAction().listDirectory(target);
-            for (int i = 0; i < files.length; i++)
+            if (files != null)
             {
-                deleteDirectoryTreeRecursive(files[i]);
+                for (int i = 0; i < files.length; i++)
+                {
+                    deleteDirectoryTreeRecursive(files[i]);
+                }
             }
         }
 
diff --git a/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java b/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
index c1269c0..baebe1d 100644
--- a/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
+++ b/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
@@ -89,7 +89,7 @@ class DirectoryRevision extends BundleArchiveRevision
             // Get manifest.
             Manifest mf = new Manifest(is);
             // Create a case insensitive map of manifest attributes.
-            return new StringMap(mf.getMainAttributes(), false);
+            return new StringMap(mf.getMainAttributes());
         }
         finally
         {
diff --git a/src/main/java/org/apache/felix/framework/cache/JarRevision.java b/src/main/java/org/apache/felix/framework/cache/JarRevision.java
index 7a539da..99d9679 100644
--- a/src/main/java/org/apache/felix/framework/cache/JarRevision.java
+++ b/src/main/java/org/apache/felix/framework/cache/JarRevision.java
@@ -99,7 +99,7 @@ class JarRevision extends BundleArchiveRevision
     public Map getManifestHeader() throws Exception
     {
         // Create a case insensitive map of manifest attributes.
-        Map headers = new StringMap(false);
+        Map headers = new StringMap();
         // Read and parse headers.
         getMainAttributes(headers, m_zipFile);
         return headers;
diff --git a/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java b/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
index 9d5fd48..738652e 100644
--- a/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
+++ b/src/main/java/org/apache/felix/framework/capabilityset/CapabilitySet.java
@@ -20,6 +20,8 @@ package org.apache.felix.framework.capabilityset;
 
 import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -41,34 +43,34 @@ public class CapabilitySet
     private final Set<BundleCapability> m_capSet = new HashSet<BundleCapability>();
     private final static SecureAction m_secureAction = new SecureAction();
 
-public void dump()
-{
-    for (Entry<String, Map<Object, Set<BundleCapability>>> entry : m_indices.entrySet())
+    public void dump()
     {
-        boolean header1 = false;
-        for (Entry<Object, Set<BundleCapability>> entry2 : entry.getValue().entrySet())
+        for (Entry<String, Map<Object, Set<BundleCapability>>> entry : m_indices.entrySet())
         {
-            boolean header2 = false;
-            for (BundleCapability cap : entry2.getValue())
+            boolean header1 = false;
+            for (Entry<Object, Set<BundleCapability>> entry2 : entry.getValue().entrySet())
             {
-                if (cap.getRevision().getBundle().getBundleId() != 0)
+                boolean header2 = false;
+                for (BundleCapability cap : entry2.getValue())
                 {
-                    if (!header1)
-                    {
-                        System.out.println(entry.getKey() + ":");
-                        header1 = true;
-                    }
-                    if (!header2)
+                    if (cap.getRevision().getBundle().getBundleId() != 0)
                     {
-                        System.out.println("   " + entry2.getKey());
-                        header2 = true;
+                        if (!header1)
+                        {
+                            System.out.println(entry.getKey() + ":");
+                            header1 = true;
+                        }
+                        if (!header2)
+                        {
+                            System.out.println("   " + entry2.getKey());
+                            header2 = true;
+                        }
+                        System.out.println("      " + cap);
                     }
-                    System.out.println("      " + cap);
                 }
             }
         }
     }
-}
 
     public CapabilitySet(List<String> indexProps, boolean caseSensitive)
     {
@@ -366,10 +368,16 @@ public void dump()
         return false;
     }
 
-    private static final Class[] STRING_CLASS = new Class[] { String.class };
+    private static final Class<?>[] STRING_CLASS = new Class[] { String.class };
+    private static final String VALUE_OF_METHOD_NAME = "valueOf";
 
     private static boolean compare(Object lhs, Object rhsUnknown, int op)
     {
+        if (lhs == null)
+        {
+            return false;
+        }
+
         // If this is a PRESENT operation, then just return true immediately
         // since we wouldn't be here if the attribute wasn't present.
         if (op == SimpleFilter.PRESENT)
@@ -564,9 +572,30 @@ public void dump()
                 {
                     rhsString = rhsString.trim();
                 }
-                Constructor ctor = m_secureAction.getConstructor(lhs.getClass(), STRING_CLASS);
-                m_secureAction.setAccesssible(ctor);
-                rhs = ctor.newInstance(new Object[] { rhsString });
+
+                try
+                {
+                    // Try to find a suitable static valueOf method
+                    Method valueOfMethod = m_secureAction.getDeclaredMethod(
+                        lhs.getClass(), VALUE_OF_METHOD_NAME, STRING_CLASS);
+                    if (valueOfMethod.getReturnType().isAssignableFrom(lhs.getClass())
+                        && ((valueOfMethod.getModifiers() & Modifier.STATIC) > 0))
+                    {
+                        m_secureAction.setAccesssible(valueOfMethod);
+                        rhs = valueOfMethod.invoke(null, new Object[] { rhsString });
+                    }
+                }
+                catch (Exception ex)
+                {
+                    // Static valueOf fails, try the next conversion mechanism
+                }
+
+                if (rhs == null)
+                {
+                    Constructor ctor = m_secureAction.getConstructor(lhs.getClass(), STRING_CLASS);
+                    m_secureAction.setAccesssible(ctor);
+                    rhs = ctor.newInstance(new Object[] { rhsString });
+                }
             }
         }
         catch (Exception ex)
@@ -599,4 +628,4 @@ public void dump()
         }
         return list;
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/felix/framework/capabilityset/SimpleFilter.java b/src/main/java/org/apache/felix/framework/capabilityset/SimpleFilter.java
index cc4e0fe..1bd517b 100644
--- a/src/main/java/org/apache/felix/framework/capabilityset/SimpleFilter.java
+++ b/src/main/java/org/apache/felix/framework/capabilityset/SimpleFilter.java
@@ -403,24 +403,23 @@ loop:   for (;;)
             char c = value.charAt(idx++);
             if (!escaped && (c == '*'))
             {
-                if (wasStar)
-                {
-                    // encountered two successive stars;
-                    // I assume this is illegal
-                    throw new IllegalArgumentException("Invalid filter string: " + value);
-                }
-                if (ss.length() > 0)
-                {
-                    pieces.add(ss.toString()); // accumulate the pieces
-                    // between '*' occurrences
-                }
-                ss.setLength(0);
-                // if this is a leading star, then track it
-                if (pieces.isEmpty())
+                // If we have successive '*' characters, then we can
+                // effectively collapse them by ignoring succeeding ones.
+                if (!wasStar)
                 {
-                    leftstar = true;
+                    if (ss.length() > 0)
+                    {
+                        pieces.add(ss.toString()); // accumulate the pieces
+                        // between '*' occurrences
+                    }
+                    ss.setLength(0);
+                    // if this is a leading star, then track it
+                    if (pieces.isEmpty())
+                    {
+                        leftstar = true;
+                    }
+                    wasStar = true;
                 }
-                wasStar = true;
             }
             else if (!escaped && (c == '\\'))
             {
@@ -502,9 +501,9 @@ loop:   for (int i = 0; i < len; i++)
 
             // If this is the last piece, then make sure the
             // string ends with it.
-            if (i == len - 1)
+            if (i == (len - 1))
             {
-                if (s.endsWith(piece))
+                if (s.endsWith(piece) && (s.length() >= (index + piece.length())))
                 {
                     result = true;
                 }
diff --git a/src/main/java/org/apache/felix/framework/resolver/Candidates.java b/src/main/java/org/apache/felix/framework/resolver/Candidates.java
index a411bcb..9f57f95 100644
--- a/src/main/java/org/apache/felix/framework/resolver/Candidates.java
+++ b/src/main/java/org/apache/felix/framework/resolver/Candidates.java
@@ -27,11 +27,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-import java.util.SortedSet;
 import java.util.TreeMap;
-import java.util.TreeSet;
-import org.apache.felix.framework.BundleRevisionImpl;
-import org.apache.felix.framework.resolver.Resolver.ResolverState;
+
+import org.apache.felix.framework.ResolveContextImpl;
 import org.apache.felix.framework.util.FelixConstants;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
@@ -50,15 +48,14 @@ class Candidates
     public static final int OPTIONAL = 1;
     public static final int ON_DEMAND = 2;
 
-    // Set of all mandatory bundle revisions.
     private final Set<BundleRevision> m_mandatoryRevisions;
     // Maps a capability to requirements that match it.
     private final Map<BundleCapability, Set<BundleRequirement>> m_dependentMap;
     // Maps a requirement to the capability it matches.
-    private final Map<BundleRequirement, SortedSet<BundleCapability>> m_candidateMap;
+    private final Map<BundleRequirement, List<BundleCapability>> m_candidateMap;
     // Maps a bundle revision to its associated wrapped revision; this only happens
     // when a revision being resolved has fragments to attach to it.
-    private final Map<BundleRevision, HostBundleRevision> m_allWrappedHosts;
+    private final Map<BundleRevision, WrappedRevision> m_allWrappedHosts;
     // Map used when populating candidates to hold intermediate and final results.
     private final Map<BundleRevision, Object> m_populateResultCache;
 
@@ -75,8 +72,8 @@ class Candidates
     private Candidates(
         Set<BundleRevision> mandatoryRevisions,
         Map<BundleCapability, Set<BundleRequirement>> dependentMap,
-        Map<BundleRequirement, SortedSet<BundleCapability>> candidateMap,
-        Map<BundleRevision, HostBundleRevision> wrappedHosts, Map<BundleRevision, Object> populateResultCache,
+        Map<BundleRequirement, List<BundleCapability>> candidateMap,
+        Map<BundleRevision, WrappedRevision> wrappedHosts, Map<BundleRevision, Object> populateResultCache,
         boolean fragmentsPresent)
     {
         m_mandatoryRevisions = mandatoryRevisions;
@@ -94,8 +91,8 @@ class Candidates
     {
         m_mandatoryRevisions = new HashSet<BundleRevision>();
         m_dependentMap = new HashMap<BundleCapability, Set<BundleRequirement>>();
-        m_candidateMap = new HashMap<BundleRequirement, SortedSet<BundleCapability>>();
-        m_allWrappedHosts = new HashMap<BundleRevision, HostBundleRevision>();
+        m_candidateMap = new HashMap<BundleRequirement, List<BundleCapability>>();
+        m_allWrappedHosts = new HashMap<BundleRevision, WrappedRevision>();
         m_populateResultCache = new HashMap<BundleRevision, Object>();
     }
 
@@ -116,7 +113,7 @@ class Candidates
      * @param resolution indicates the resolution type.
      */
     public final void populate(
-        ResolverState state, BundleRevision revision, int resolution)
+        ResolveContext rc, BundleRevision revision, int resolution)
     {
         // Get the current result cache value, to make sure the revision
         // hasn't already been populated.
@@ -146,7 +143,7 @@ class Candidates
         // However, for on-demand fragments only populate if their host
         // is already populated.
         if ((resolution != ON_DEMAND)
-            || (isFragment && populateFragmentOndemand(state, revision)))
+            || (isFragment && populateFragmentOndemand(rc, revision)))
         {
             if (resolution == MANDATORY)
             {
@@ -155,7 +152,7 @@ class Candidates
             try
             {
                 // Try to populate candidates for the optional revision.
-                populateRevision(state, revision);
+                populateRevision(rc, revision);
             }
             catch (ResolveException ex)
             {
@@ -174,7 +171,7 @@ class Candidates
      * @param revision the revision whose candidates should be populated.
      */
 // TODO: FELIX3 - Modify to not be recursive.
-    private void populateRevision(ResolverState state, BundleRevision revision)
+    private void populateRevision(ResolveContext rc, BundleRevision revision)
     {
         // Determine if we've already calculated this revision's candidates.
         // The result cache will have one of three values:
@@ -196,7 +193,7 @@ class Candidates
 
         // Keeps track of the candidates we've already calculated for the
         // current revision's requirements.
-        Map<BundleRequirement, SortedSet<BundleCapability>> localCandidateMap = null;
+        Map<BundleRequirement, List<BundleCapability>> localCandidateMap = null;
 
         // Keeps track of the current revision's requirements for which we
         // haven't yet found candidates.
@@ -233,11 +230,8 @@ class Candidates
         // do some one-time checks and initialization.
         if ((remainingReqs == null) && (localCandidateMap == null))
         {
-            // Verify that any required execution environment is satisfied.
-            state.checkExecutionEnvironment(revision);
-
             // Verify that any native libraries match the current platform.
-            state.checkNativeLibraries(revision);
+            ((ResolveContextImpl) rc).checkNativeLibraries(revision);
 
             // Record cycle count.
             cycleCount = new Integer(0);
@@ -257,13 +251,13 @@ class Candidates
         }
 
         // If we have requirements remaining, then find candidates for them.
-        while (remainingReqs.size() > 0)
+        while (!remainingReqs.isEmpty())
         {
             BundleRequirement req = remainingReqs.remove(0);
 
             // Ignore non-effective and dynamic requirements.
             String resolution = req.getDirectives().get(Constants.RESOLUTION_DIRECTIVE);
-            if (!state.isEffective(req)
+            if (!rc.isEffective(req)
                 || ((resolution != null)
                     && resolution.equals(FelixConstants.RESOLUTION_DYNAMIC)))
             {
@@ -272,14 +266,19 @@ class Candidates
 
             // Process the candidates, removing any candidates that
             // cannot resolve.
-            SortedSet<BundleCapability> candidates =
-                state.getCandidates((BundleRequirementImpl) req, true);
-            ResolveException rethrow = processCandidates(state, revision, candidates);
-
-            // If there are no candidates for the current requirement
-            // and it is not optional, then create, cache, and throw
-            // a resolve exception.
-            if (candidates.isEmpty() && !((BundleRequirementImpl) req).isOptional())
+            List<BundleCapability> candidates = rc.findProviders(req, true);
+            ResolveException rethrow = processCandidates(rc, revision, candidates);
+
+            // First, due to cycles, makes sure we haven't already failed in
+            // a deeper recursion.
+            Object result = m_populateResultCache.get(revision);
+            if (result instanceof ResolveException)
+            {
+                throw (ResolveException) result;
+            }
+            // Next, if are no candidates remaining and the requirement is not
+            // not optional, then record and throw a resolve exception.
+            else if (candidates.isEmpty() && !((BundleRequirementImpl) req).isOptional())
             {
                 String msg = "Unable to resolve " + revision
                     + ": missing requirement " + req;
@@ -291,7 +290,7 @@ class Candidates
                 m_populateResultCache.put(revision, rethrow);
                 throw rethrow;
             }
-            // If we actually have candidates for the requirement, then
+            // Otherwise, if we actually have candidates for the requirement, then
             // add them to the local candidate map.
             else if (candidates.size() > 0)
             {
@@ -318,7 +317,7 @@ class Candidates
         }
     }
 
-    private boolean populateFragmentOndemand(ResolverState state, BundleRevision revision)
+    private boolean populateFragmentOndemand(ResolveContext rc, BundleRevision revision)
         throws ResolveException
     {
         // Create a modifiable list of the revision's requirements.
@@ -338,8 +337,7 @@ class Candidates
             }
         }
         // Get candidates hosts and keep any that have been populated.
-        SortedSet<BundleCapability> hosts =
-            state.getCandidates((BundleRequirementImpl) hostReq, false);
+        List<BundleCapability> hosts = rc.findProviders(hostReq, false);
         for (Iterator<BundleCapability> it = hosts.iterator(); it.hasNext(); )
         {
             BundleCapability host = it.next();
@@ -357,17 +355,15 @@ class Candidates
         // If there are populates host candidates, then finish up
         // some other checks and prepopulate the result cache with
         // the work we've done so far.
-        // Verify that any required execution environment is satisfied.
-        state.checkExecutionEnvironment(revision);
         // Verify that any native libraries match the current platform.
-        state.checkNativeLibraries(revision);
+        ((ResolveContextImpl) rc).checkNativeLibraries(revision);
         // Record cycle count, but start at -1 since it will
         // be incremented again in populate().
         Integer cycleCount = new Integer(-1);
         // Create a local map for populating candidates first, just in case
         // the revision is not resolvable.
-        Map<BundleRequirement, SortedSet<BundleCapability>> localCandidateMap =
-            new HashMap<BundleRequirement, SortedSet<BundleCapability>>();
+        Map<BundleRequirement, List<BundleCapability>> localCandidateMap =
+            new HashMap<BundleRequirement, List<BundleCapability>>();
         // Add the discovered host candidates to the local candidate map.
         localCandidateMap.put(hostReq, hosts);
         // Add these value to the result cache so we know we are
@@ -379,8 +375,8 @@ class Candidates
     }
 
     public void populateDynamic(
-        ResolverState state, BundleRevision revision,
-        BundleRequirement req, SortedSet<BundleCapability> candidates)
+        ResolveContext rc, BundleRevision revision,
+        BundleRequirement req, List<BundleCapability> candidates)
     {
         // Record the revision associated with the dynamic require
         // as a mandatory revision.
@@ -391,7 +387,7 @@ class Candidates
 
         // Process the candidates, removing any candidates that
         // cannot resolve.
-        ResolveException rethrow = processCandidates(state, revision, candidates);
+        ResolveException rethrow = processCandidates(rc, revision, candidates);
 
         if (candidates.isEmpty())
         {
@@ -417,9 +413,9 @@ class Candidates
      * @return a resolve exception to be re-thrown, if any, or null.
      */
     private ResolveException processCandidates(
-        ResolverState state,
+        ResolveContext rc,
         BundleRevision revision,
-        SortedSet<BundleCapability> candidates)
+        List<BundleCapability> candidates)
     {
         // Get satisfying candidates and populate their candidates if necessary.
         ResolveException rethrow = null;
@@ -455,13 +451,12 @@ class Candidates
             // since we effectively chain exception messages for each level
             // of recursion; thus, any avoided recursion results in fewer
             // exceptions to chain when an error does occur.
-            if (isFragment
-                || ((candCap.getRevision().getWiring() == null)
-                    && !candCap.getRevision().equals(revision)))
+            if ((isFragment || (candCap.getRevision().getWiring() == null))
+                && !candCap.getRevision().equals(revision))
             {
                 try
                 {
-                    populateRevision(state, candCap.getRevision());
+                    populateRevision(rc, candCap.getRevision());
                 }
                 catch (ResolveException ex)
                 {
@@ -500,8 +495,19 @@ class Candidates
                         {
                             // Note that we can just add this as a candidate
                             // directly, since we know it is already resolved.
-                            candidates.add(
-                                new HostedCapability(
+                            // NOTE: We are synthesizing a hosted capability here,
+                            // but we are not using a ShadowList like we do when
+                            // we synthesizing capabilities for unresolved hosts.
+                            // It is not necessary to use the ShadowList here since
+                            // the host is resolved, because in that case we can
+                            // calculate the proper package space by traversing
+                            // the wiring. In the unresolved case, this isn't possible
+                            // so we need to use the ShadowList so we can keep
+                            // a reference to a synthesized resource with attached
+                            // fragments so we can correctly calculate its package
+                            // space.
+                            rc.insertHostedCapability(candidates,
+                                new WrappedCapability(
                                     wire.getCapability().getRevision(),
                                     (BundleCapabilityImpl) fragCand));
                         }
@@ -535,7 +541,7 @@ class Candidates
      * @param req the requirement to add.
      * @param candidates the candidates matching the requirement.
     **/
-    private void add(BundleRequirement req, SortedSet<BundleCapability> candidates)
+    private void add(BundleRequirement req, List<BundleCapability> candidates)
     {
         if (req.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
         {
@@ -552,9 +558,9 @@ class Candidates
      * be further modified by the caller.
      * @param candidates the bulk requirements and candidates to add.
     **/
-    private void add(Map<BundleRequirement, SortedSet<BundleCapability>> candidates)
+    private void add(Map<BundleRequirement, List<BundleCapability>> candidates)
     {
-        for (Entry<BundleRequirement, SortedSet<BundleCapability>> entry : candidates.entrySet())
+        for (Entry<BundleRequirement, List<BundleCapability>> entry : candidates.entrySet())
         {
             add(entry.getKey(), entry.getValue());
         }
@@ -578,7 +584,7 @@ class Candidates
      * @param req the requirement whose candidates are desired.
      * @return the matching candidates or null.
     **/
-    public SortedSet<BundleCapability> getCandidates(BundleRequirement req)
+    public List<BundleCapability> getCandidates(BundleRequirement req)
     {
         return m_candidateMap.get(req);
     }
@@ -599,7 +605,7 @@ class Candidates
      * @throws ResolveException if the removal of any unselected fragments result
      *         in the root module being unable to resolve.
     **/
-    public void prepare()
+    public void prepare(ResolveContext rc)
     {
         // Maps a host capability to a map containing its potential fragments;
         // the fragment map maps a fragment symbolic name to a map that maps
@@ -627,7 +633,7 @@ class Candidates
         //      with host's attached fragment capabilities.
 
         // Steps 1 and 2
-        List<HostBundleRevision> hostRevisions = new ArrayList<HostBundleRevision>();
+        List<WrappedRevision> hostRevisions = new ArrayList<WrappedRevision>();
         List<BundleRevision> unselectedFragments = new ArrayList<BundleRevision>();
         for (Entry<BundleCapability, Map<String, Map<Version, List<BundleRequirement>>>>
             hostEntry : hostFragments.entrySet())
@@ -662,7 +668,7 @@ class Candidates
                         else
                         {
                             m_dependentMap.get(hostCap).remove(hostReq);
-                            SortedSet<BundleCapability> hosts = m_candidateMap.get(hostReq);
+                            List<BundleCapability> hosts = m_candidateMap.get(hostReq);
                             hosts.remove(hostCap);
                             if (hosts.isEmpty())
                             {
@@ -674,8 +680,8 @@ class Candidates
             }
 
             // Step 2
-            HostBundleRevision wrappedHost =
-                new HostBundleRevision(hostCap.getRevision(), selectedFragments);
+            WrappedRevision wrappedHost =
+                new WrappedRevision(hostCap.getRevision(), selectedFragments);
             hostRevisions.add(wrappedHost);
             m_allWrappedHosts.put(hostCap.getRevision(), wrappedHost);
         }
@@ -689,7 +695,7 @@ class Candidates
         }
 
         // Step 4
-        for (HostBundleRevision hostRevision : hostRevisions)
+        for (WrappedRevision hostRevision : hostRevisions)
         {
             // Replaces capabilities from fragments with the capabilities
             // from the merged host.
@@ -699,8 +705,7 @@ class Candidates
                 // really be attached to the original host, not the wrapper.
                 if (!c.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
                 {
-                    BundleCapability origCap =
-                        ((HostedCapability) c).getOriginalCapability();
+                    BundleCapability origCap = ((HostedCapability) c).getDeclaredCapability();
                     // Note that you might think we could remove the original cap
                     // from the dependent map, but you can't since it may come from
                     // a fragment that is attached to multiple hosts, so each host
@@ -712,9 +717,63 @@ class Candidates
                         m_dependentMap.put(c, dependents);
                         for (BundleRequirement r : dependents)
                         {
-                            Set<BundleCapability> cands = m_candidateMap.get(r);
-                            cands.remove(origCap);
-                            cands.add(c);
+                            // We have synthesized hosted capabilities for all
+                            // fragments that have been attached to hosts by
+                            // wrapping the host bundle and their attached
+                            // fragments. We need to use the ResolveContext to
+                            // determine the proper priority order for hosted
+                            // capabilities since the order may depend on the
+                            // declaring host/fragment combination. However,
+                            // internally we completely wrap the host revision
+                            // and make all capabilities/requirements point back
+                            // to the wrapped host not the declaring host. The
+                            // ResolveContext expects HostedCapabilities to point
+                            // to the declaring revision, so we need two separate
+                            // candidate lists: one for the ResolveContext with
+                            // HostedCapabilities pointing back to the declaring
+                            // host and one for the resolver with HostedCapabilities
+                            // pointing back to the wrapped host. We ask the
+                            // ResolveContext to insert its appropriate HostedCapability
+                            // into its list, then we mirror the insert into a
+                            // shadow list with the resolver's HostedCapability.
+                            // We only need to ask the ResolveContext to find
+                            // the insert position for fragment caps since these
+                            // were synthesized and we don't know their priority.
+                            // However, in the resolver's candidate list we need
+                            // to replace all caps with the wrapped caps, no
+                            // matter if they come from the host or fragment,
+                            // since we are completing replacing the declaring
+                            // host and fragments with the wrapped host.
+                            List<BundleCapability> cands = m_candidateMap.get(r);
+                            if (!(cands instanceof ShadowList))
+                            {
+                                ShadowList<BundleCapability> shadow =
+                                    new ShadowList<BundleCapability>(cands);
+                                m_candidateMap.put(r, shadow);
+                                cands = shadow;
+                            }
+
+                            // If the original capability is from a fragment, then
+                            // ask the ResolveContext to insert it and update the
+                            // shadow copy of the list accordingly.
+                            if (!origCap.getRevision().equals(hostRevision.getHost()))
+                            {
+                                List<BundleCapability> original = ((ShadowList) cands).getOriginal();
+                                int removeIdx = original.indexOf(origCap);
+                                original.remove(removeIdx);
+                                int insertIdx = rc.insertHostedCapability(
+                                    original,
+                                    new SimpleHostedCapability(hostRevision.getHost(), origCap));
+                                cands.remove(removeIdx);
+                                cands.add(insertIdx, c);
+                            }
+                            // If the original capability is from the host, then
+                            // we just need to replace it in the shadow list.
+                            else
+                            {
+                                int idx = cands.indexOf(origCap);
+                                cands.set(idx, c);
+                            }
                         }
                     }
                 }
@@ -724,11 +783,11 @@ class Candidates
             for (BundleRequirement r : hostRevision.getDeclaredRequirements(null))
             {
                 BundleRequirement origReq =
-                    ((HostedRequirement) r).getOriginalRequirement();
-                SortedSet<BundleCapability> cands = m_candidateMap.get(origReq);
+                    ((WrappedRequirement) r).getOriginalRequirement();
+                List<BundleCapability> cands = m_candidateMap.get(origReq);
                 if (cands != null)
                 {
-                    m_candidateMap.put(r, new TreeSet<BundleCapability>(cands));
+                    m_candidateMap.put(r, new ArrayList<BundleCapability>(cands));
                     for (BundleCapability cand : cands)
                     {
                         Set<BundleRequirement> dependents = m_dependentMap.get(cand);
@@ -761,11 +820,10 @@ class Candidates
         Map<BundleCapability, Map<String, Map<Version, List<BundleRequirement>>>>
             hostFragments = new HashMap<BundleCapability,
                 Map<String, Map<Version, List<BundleRequirement>>>>();
-        for (Entry<BundleRequirement, SortedSet<BundleCapability>> entry
-            : m_candidateMap.entrySet())
+        for (Entry<BundleRequirement, List<BundleCapability>> entry : m_candidateMap.entrySet())
         {
             BundleRequirement req = entry.getKey();
-            SortedSet<BundleCapability> caps = entry.getValue();
+            List<BundleCapability> caps = entry.getValue();
             for (BundleCapability cap : caps)
             {
                 // Record the requirement as dependent on the capability.
@@ -866,7 +924,7 @@ class Candidates
     {
         boolean isFragment = req.getNamespace().equals(BundleRevision.HOST_NAMESPACE);
 
-        SortedSet<BundleCapability> candidates = m_candidateMap.remove(req);
+        List<BundleCapability> candidates = m_candidateMap.remove(req);
         if (candidates != null)
         {
             for (BundleCapability cap : candidates)
@@ -897,7 +955,7 @@ class Candidates
         {
             for (BundleRequirement r : dependents)
             {
-                SortedSet<BundleCapability> candidates = m_candidateMap.get(r);
+                List<BundleCapability> candidates = m_candidateMap.get(r);
                 candidates.remove(c);
                 if (candidates.isEmpty())
                 {
@@ -930,13 +988,13 @@ class Candidates
             dependentMap.put(entry.getKey(), dependents);
         }
 
-        Map<BundleRequirement, SortedSet<BundleCapability>> candidateMap =
-            new HashMap<BundleRequirement, SortedSet<BundleCapability>>();
-        for (Entry<BundleRequirement, SortedSet<BundleCapability>> entry
+        Map<BundleRequirement, List<BundleCapability>> candidateMap =
+            new HashMap<BundleRequirement, List<BundleCapability>>();
+        for (Entry<BundleRequirement, List<BundleCapability>> entry
             : m_candidateMap.entrySet())
         {
-            SortedSet<BundleCapability> candidates =
-                new TreeSet<BundleCapability>(entry.getValue());
+            List<BundleCapability> candidates =
+                new ArrayList<BundleCapability>(entry.getValue());
             candidateMap.put(entry.getKey(), candidates);
         }
 
@@ -949,7 +1007,7 @@ class Candidates
     {
         // Create set of all revisions from requirements.
         Set<BundleRevision> revisions = new HashSet<BundleRevision>();
-        for (Entry<BundleRequirement, SortedSet<BundleCapability>> entry
+        for (Entry<BundleRequirement, List<BundleCapability>> entry
             : m_candidateMap.entrySet())
         {
             revisions.add(entry.getKey().getRevision());
@@ -965,7 +1023,7 @@ class Candidates
                 : br.getDeclaredRequirements(null);
             for (BundleRequirement req : reqs)
             {
-                Set<BundleCapability> candidates = m_candidateMap.get(req);
+                List<BundleCapability> candidates = m_candidateMap.get(req);
                 if ((candidates != null) && (candidates.size() > 0))
                 {
                     System.out.println("    " + req + ": " + candidates);
@@ -976,7 +1034,7 @@ class Candidates
                 : Util.getDynamicRequirements(br.getDeclaredRequirements(null));
             for (BundleRequirement req : reqs)
             {
-                Set<BundleCapability> candidates = m_candidateMap.get(req);
+                List<BundleCapability> candidates = m_candidateMap.get(req);
                 if ((candidates != null) && (candidates.size() > 0))
                 {
                     System.out.println("    " + req + ": " + candidates);
diff --git a/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java b/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java
index dbdad1c..fc45301 100644
--- a/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java
+++ b/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java
@@ -1,122 +1,26 @@
 /*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
  *
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 package org.apache.felix.framework.resolver;
 
-import java.util.List;
-import java.util.Map;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRevision;
 
-public class HostedCapability extends BundleCapabilityImpl
-{
-    private final BundleRevision m_host;
-    private final BundleCapabilityImpl m_cap;
-
-    public HostedCapability(BundleRevision host, BundleCapabilityImpl cap)
-    {
-        super(host, cap.getNamespace(), cap.getDirectives(), cap.getAttributes());
-        m_host = host;
-        m_cap = cap;
-    }
-
-    @Override
-    public boolean equals(Object obj)
-    {
-        if (obj == null)
-        {
-            return false;
-        }
-        if (getClass() != obj.getClass())
-        {
-            return false;
-        }
-        final HostedCapability other = (HostedCapability) obj;
-        if (m_host != other.m_host && (m_host == null || !m_host.equals(other.m_host)))
-        {
-            return false;
-        }
-        if (m_cap != other.m_cap && (m_cap == null || !m_cap.equals(other.m_cap)))
-        {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode()
-    {
-        int hash = 7;
-        hash = 37 * hash + (m_host != null ? m_host.hashCode() : 0);
-        hash = 37 * hash + (m_cap != null ? m_cap.hashCode() : 0);
-        return hash;
-    }
-
-    public BundleCapabilityImpl getOriginalCapability()
-    {
-        return m_cap;
-    }
-
-    @Override
-    public BundleRevision getRevision()
-    {
-        return m_host;
-    }
-
-    @Override
-    public String getNamespace()
-    {
-        return m_cap.getNamespace();
-    }
-
-    @Override
-    public Map<String, String> getDirectives()
-    {
-        return m_cap.getDirectives();
-    }
-
-    @Override
-    public Map<String, Object> getAttributes()
-    {
-        return m_cap.getAttributes();
-    }
+public interface HostedCapability extends BundleCapability {
 
-    @Override
-    public List<String> getUses()
-    {
-        return m_cap.getUses();
-    }
+	BundleRevision getRevision();
 
-    @Override
-    public String toString()
-    {
-        if (m_host == null)
-        {
-            return getAttributes().toString();
-        }
-        if (getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
-        {
-            return "[" + m_host + "] "
-                + getNamespace()
-                + "; "
-                + getAttributes().get(BundleRevision.PACKAGE_NAMESPACE);
-        }
-        return "[" + m_host + "] " + getNamespace() + "; " + getAttributes();
-    }
-}
\ No newline at end of file
+	BundleCapability getDeclaredCapability();
+}
diff --git a/src/main/java/org/apache/felix/framework/resolver/ResolveContext.java b/src/main/java/org/apache/felix/framework/resolver/ResolveContext.java
new file mode 100644
index 0000000..2af0696
--- /dev/null
+++ b/src/main/java/org/apache/felix/framework/resolver/ResolveContext.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.framework.resolver;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWiring;
+
+public abstract class ResolveContext
+{
+    public Collection<BundleRevision> getMandatoryRevisions()
+    {
+        return emptyCollection();
+    }
+
+    public Collection<BundleRevision> getOptionalRevisions()
+    {
+        return emptyCollection();
+    }
+
+    private static <T> Collection<T> emptyCollection()
+    {
+        return Collections.EMPTY_LIST;
+    }
+
+    public abstract List<BundleCapability> findProviders(BundleRequirement br, boolean obeyMandatory);
+
+    public abstract int insertHostedCapability(List<BundleCapability> caps, HostedCapability hc);
+
+    public abstract boolean isEffective(BundleRequirement br);
+
+    public abstract Map<BundleRevision, BundleWiring> getWirings();
+}
diff --git a/src/main/java/org/apache/felix/framework/resolver/Resolver.java b/src/main/java/org/apache/felix/framework/resolver/Resolver.java
index eabfdd1..107e4a7 100644
--- a/src/main/java/org/apache/felix/framework/resolver/Resolver.java
+++ b/src/main/java/org/apache/felix/framework/resolver/Resolver.java
@@ -28,21 +28,7 @@ import org.osgi.framework.wiring.BundleRevision;
 
 public interface Resolver
 {
+    Map<BundleRevision, List<ResolverWire>> resolve(ResolveContext rc);
     Map<BundleRevision, List<ResolverWire>> resolve(
-        ResolverState state,
-        Set<BundleRevision> mandatoryRevisions,
-        Set<BundleRevision> optionalRevisions,
-        Set<BundleRevision> ondemandFragments);
-    Map<BundleRevision, List<ResolverWire>> resolve(
-        ResolverState state, BundleRevision revision, String pkgName,
-        Set<BundleRevision> ondemandFragments);
-
-    public static interface ResolverState
-    {
-        boolean isEffective(BundleRequirement req);
-        SortedSet<BundleCapability> getCandidates(
-            BundleRequirement req, boolean obeyMandatory);
-        void checkExecutionEnvironment(BundleRevision revision) throws ResolveException;
-        void checkNativeLibraries(BundleRevision revision) throws ResolveException;
-    }
+        ResolveContext rc, BundleRevision revision, String pkgName);
 }
\ No newline at end of file
diff --git a/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java b/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
index a62a09e..2512144 100644
--- a/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
+++ b/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
@@ -19,6 +19,7 @@
 package org.apache.felix.framework.resolver;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -30,6 +31,7 @@ import java.util.Set;
 import java.util.SortedSet;
 import org.apache.felix.framework.BundleWiringImpl;
 import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.ResolveContextImpl;
 import org.apache.felix.framework.capabilityset.CapabilitySet;
 import org.apache.felix.framework.util.FelixConstants;
 import org.apache.felix.framework.util.Util;
@@ -57,17 +59,17 @@ public class ResolverImpl implements Resolver
         m_logger = logger;
     }
 
-    public Map<BundleRevision, List<ResolverWire>> resolve(
-        ResolverState state,
-        Set<BundleRevision> mandatoryRevisions,
-        Set<BundleRevision> optionalRevisions,
-        Set<BundleRevision> ondemandFragments)
+    public Map<BundleRevision, List<ResolverWire>> resolve(ResolveContext rc)
     {
         Map<BundleRevision, List<ResolverWire>> wireMap =
             new HashMap<BundleRevision, List<ResolverWire>>();
         Map<BundleRevision, Packages> revisionPkgMap =
             new HashMap<BundleRevision, Packages>();
 
+        Collection<BundleRevision> mandatoryRevisions = rc.getMandatoryRevisions();
+        Collection<BundleRevision> optionalRevisions = rc.getOptionalRevisions();
+        Collection<BundleRevision> ondemandFragments = (rc instanceof ResolveContextImpl)
+            ? ((ResolveContextImpl) rc).getOndemandRevisions() : Collections.EMPTY_LIST;
         boolean retry;
         do
         {
@@ -86,7 +88,7 @@ public class ResolverImpl implements Resolver
                     BundleRevision br = it.next();
                     if (Util.isFragment(br) || (br.getWiring() == null))
                     {
-                        allCandidates.populate(state, br, Candidates.MANDATORY);
+                        allCandidates.populate(rc, br, Candidates.MANDATORY);
                     }
                     else
                     {
@@ -101,7 +103,7 @@ public class ResolverImpl implements Resolver
                     boolean isFragment = Util.isFragment(br);
                     if (isFragment || (br.getWiring() == null))
                     {
-                        allCandidates.populate(state, br, Candidates.OPTIONAL);
+                        allCandidates.populate(rc, br, Candidates.OPTIONAL);
                     }
                 }
 
@@ -112,12 +114,12 @@ public class ResolverImpl implements Resolver
                     boolean isFragment = Util.isFragment(br);
                     if (isFragment)
                     {
-                        allCandidates.populate(state, br, Candidates.ON_DEMAND);
+                        allCandidates.populate(rc, br, Candidates.ON_DEMAND);
                     }
                 }
 
                 // Merge any fragments into hosts.
-                allCandidates.prepare();
+                allCandidates.prepare(rc);
 
                 // Create a combined list of populated revisions; for
                 // optional revisions. We do not need to consider ondemand
@@ -188,7 +190,7 @@ public class ResolverImpl implements Resolver
                         try
                         {
                             checkPackageSpaceConsistency(
-                                false, allCandidates.getWrappedHost(target),
+                                rc, false, allCandidates.getWrappedHost(target),
                                 allCandidates, revisionPkgMap, new HashMap());
                         }
                         catch (ResolveException ex)
@@ -207,11 +209,11 @@ public class ResolverImpl implements Resolver
                 if (rethrow != null)
                 {
                     BundleRevision faultyRevision =
-                        getActualBundleRevision(rethrow.getRevision());
-                    if (rethrow.getRequirement() instanceof HostedRequirement)
+                        getDeclaringBundleRevision(rethrow.getRevision());
+                    if (rethrow.getRequirement() instanceof WrappedRequirement)
                     {
                         faultyRevision =
-                            ((HostedRequirement) rethrow.getRequirement())
+                            ((WrappedRequirement) rethrow.getRequirement())
                                 .getOriginalRequirement().getRevision();
                     }
                     if (optionalRevisions.remove(faultyRevision))
@@ -267,8 +269,7 @@ public class ResolverImpl implements Resolver
     }
 
     public Map<BundleRevision, List<ResolverWire>> resolve(
-        ResolverState state, BundleRevision revision, String pkgName,
-        Set<BundleRevision> ondemandFragments)
+        ResolveContext rc, BundleRevision revision, String pkgName)
     {
         // We can only create a dynamic import if the following
         // conditions are met:
@@ -280,11 +281,16 @@ public class ResolverImpl implements Resolver
         // The following call checks all of these conditions and returns
         // the associated dynamic import and matching capabilities.
         Candidates allCandidates =
-            getDynamicImportCandidates(state, revision, pkgName);
+            getDynamicImportCandidates(rc, revision, pkgName);
         if (allCandidates != null)
         {
-            Map<BundleRevision, List<ResolverWire>> wireMap = new HashMap<BundleRevision, List<ResolverWire>>();
-            Map<BundleRevision, Packages> revisionPkgMap = new HashMap<BundleRevision, Packages>();
+            Collection<BundleRevision> ondemandFragments = (rc instanceof ResolveContextImpl)
+                ? ((ResolveContextImpl) rc).getOndemandRevisions() : Collections.EMPTY_LIST;
+
+            Map<BundleRevision, List<ResolverWire>> wireMap =
+                new HashMap<BundleRevision, List<ResolverWire>>();
+            Map<BundleRevision, Packages> revisionPkgMap =
+                new HashMap<BundleRevision, Packages>();
 
             boolean retry;
             do
@@ -298,12 +304,12 @@ public class ResolverImpl implements Resolver
                     {
                         if (Util.isFragment(br))
                         {
-                            allCandidates.populate(state, br, Candidates.ON_DEMAND);
+                            allCandidates.populate(rc, br, Candidates.ON_DEMAND);
                         }
                     }
 
                     // Merge any fragments into hosts.
-                    allCandidates.prepare();
+                    allCandidates.prepare(rc);
 
                     // Record the initial candidate permutation.
                     m_usesPermutations.add(allCandidates);
@@ -337,7 +343,7 @@ public class ResolverImpl implements Resolver
                         try
                         {
                             checkPackageSpaceConsistency(
-                                false, allCandidates.getWrappedHost(revision),
+                                rc, false, allCandidates.getWrappedHost(revision),
                                 allCandidates, revisionPkgMap, new HashMap());
                         }
                         catch (ResolveException ex)
@@ -355,11 +361,11 @@ public class ResolverImpl implements Resolver
                     if (rethrow != null)
                     {
                         BundleRevision faultyRevision =
-                            getActualBundleRevision(rethrow.getRevision());
-                        if (rethrow.getRequirement() instanceof HostedRequirement)
+                            getDeclaringBundleRevision(rethrow.getRevision());
+                        if (rethrow.getRequirement() instanceof WrappedRequirement)
                         {
                             faultyRevision =
-                                ((HostedRequirement) rethrow.getRequirement())
+                                ((WrappedRequirement) rethrow.getRequirement())
                                     .getOriginalRequirement().getRevision();
                         }
                         if (ondemandFragments.remove(faultyRevision))
@@ -394,7 +400,7 @@ public class ResolverImpl implements Resolver
     }
 
     private static Candidates getDynamicImportCandidates(
-        ResolverState state, BundleRevision revision, String pkgName)
+        ResolveContext rc, BundleRevision revision, String pkgName)
     {
         // Unresolved revisions cannot dynamically import, nor can the default
         // package be dynamically imported.
@@ -438,7 +444,7 @@ public class ResolverImpl implements Resolver
             BundleRevision.PACKAGE_NAMESPACE,
             Collections.EMPTY_MAP,
             attrs);
-        SortedSet<BundleCapability> candidates = state.getCandidates(req, false);
+        List<BundleCapability> candidates = rc.findProviders(req, false);
 
         // Try to find a dynamic requirement that matches the capabilities.
         BundleRequirementImpl dynReq = null;
@@ -484,7 +490,7 @@ public class ResolverImpl implements Resolver
         if (candidates.size() > 0)
         {
             allCandidates = new Candidates();
-            allCandidates.populateDynamic(state, revision, dynReq, candidates);
+            allCandidates.populateDynamic(rc, revision, dynReq, candidates);
         }
 
         return allCandidates;
@@ -503,6 +509,20 @@ public class ResolverImpl implements Resolver
         }
         cycle.add(revision);
 
+        // Make sure package space hasn't already been calculated.
+        Packages revisionPkgs = revisionPkgMap.get(revision);
+        if (revisionPkgs != null)
+        {
+            if (revisionPkgs.m_isCalculated)
+            {
+                return;
+            }
+            else
+            {
+                revisionPkgs.m_isCalculated = true;
+            }
+        }
+
         // Create parallel arrays for requirement and proposed candidate
         // capability or actual capability if revision is resolved or not.
         List<BundleRequirement> reqs = new ArrayList();
@@ -523,7 +543,7 @@ public class ResolverImpl implements Resolver
                     || ((r.getDirectives().get(Constants.RESOLUTION_DIRECTIVE) != null)
                         && r.getDirectives().get(Constants.RESOLUTION_DIRECTIVE).equals("dynamic")))
                 {
-                    r = new HostedRequirement(
+                    r = new WrappedRequirement(
                         wire.getRequirerWiring().getRevision(),
                         (BundleRequirementImpl) r);
                 }
@@ -532,7 +552,7 @@ public class ResolverImpl implements Resolver
                 BundleCapability c = wire.getCapability();
                 if (!c.getRevision().equals(wire.getProviderWiring().getRevision()))
                 {
-                    c = new HostedCapability(
+                    c = new WrappedCapability(
                         wire.getProviderWiring().getRevision(),
                         (BundleCapabilityImpl) c);
                 }
@@ -547,15 +567,15 @@ public class ResolverImpl implements Resolver
                 : Util.getDynamicRequirements(revision.getWiring().getRequirements(null)))
             {
                 // Get the candidates for the current requirement.
-                SortedSet<BundleCapability> candCaps =
-                    allCandidates.getCandidates((BundleRequirementImpl) req);
+                List<BundleCapability> candCaps = allCandidates.getCandidates(req);
                 // Optional requirements may not have any candidates.
                 if (candCaps == null)
                 {
                     continue;
                 }
 
-                BundleCapability cap = candCaps.iterator().next();
+                // Grab first (i.e., highest priority) candidate.
+                BundleCapability cap = candCaps.get(0);
                 reqs.add(req);
                 caps.add(cap);
                 isDynamicImporting = true;
@@ -573,15 +593,15 @@ public class ResolverImpl implements Resolver
                     || !resolution.equals(FelixConstants.RESOLUTION_DYNAMIC))
                 {
                     // Get the candidates for the current requirement.
-                    SortedSet<BundleCapability> candCaps =
-                        allCandidates.getCandidates((BundleRequirementImpl) req);
+                    List<BundleCapability> candCaps = allCandidates.getCandidates(req);
                     // Optional requirements may not have any candidates.
                     if (candCaps == null)
                     {
                         continue;
                     }
 
-                    BundleCapability cap = candCaps.iterator().next();
+                    // Grab first (i.e., highest priority) candidate.
+                    BundleCapability cap = candCaps.get(0);
                     reqs.add(req);
                     caps.add(cap);
                 }
@@ -590,7 +610,7 @@ public class ResolverImpl implements Resolver
 
         // First, add all exported packages to the target revision's package space.
         calculateExportedPackages(revision, allCandidates, revisionPkgMap);
-        Packages revisionPkgs = revisionPkgMap.get(revision);
+        revisionPkgs = revisionPkgMap.get(revision);
 
         // Second, add all imported packages to the target revision's package space.
         for (int i = 0; i < reqs.size(); i++)
@@ -905,6 +925,7 @@ public class ResolverImpl implements Resolver
     }
 
     private void checkPackageSpaceConsistency(
+        ResolveContext rc,
         boolean isDynamicImporting,
         BundleRevision revision,
         Candidates allCandidates,
@@ -958,9 +979,9 @@ public class ResolverImpl implements Resolver
                             + blame.m_cap.getRevision().getSymbolicName()
                             + " [" + blame.m_cap.getRevision()
                             + "] via two dependency chains.\n\nChain 1:\n"
-                            + toStringBlame(sourceBlame)
+                            + toStringBlame(rc, allCandidates, sourceBlame)
                             + "\n\nChain 2:\n"
-                            + toStringBlame(blame),
+                            + toStringBlame(rc, allCandidates, blame),
                             revision,
                             blame.m_reqs.get(0));
                         m_logger.log(
@@ -974,6 +995,7 @@ public class ResolverImpl implements Resolver
             }
         }
 
+        // Check if there are any uses conflicts with exported packages.
         for (Entry<String, Blame> entry : pkgs.m_exportedPkgs.entrySet())
         {
             String pkgName = entry.getKey();
@@ -1003,7 +1025,7 @@ public class ResolverImpl implements Resolver
                             + usedBlame.m_cap.getRevision().getSymbolicName()
                             + " [" + usedBlame.m_cap.getRevision()
                             + "] via the following dependency chain:\n\n"
-                            + toStringBlame(usedBlame),
+                            + toStringBlame(rc, allCandidates, usedBlame),
                             null,
                             null);
 
@@ -1026,14 +1048,12 @@ public class ResolverImpl implements Resolver
                         // See if we can permutate the candidates for blamed
                         // requirement; there may be no candidates if the revision
                         // associated with the requirement is already resolved.
-                        SortedSet<BundleCapability> candidates =
-                            permutation.getCandidates(req);
+                        List<BundleCapability> candidates = permutation.getCandidates(req);
                         if ((candidates != null) && (candidates.size() > 1))
                         {
                             mutated.add(req);
-                            Iterator it = candidates.iterator();
-                            it.next();
-                            it.remove();
+                            // Remove the conflicting candidate.
+                            candidates.remove(0);
                             // Continue with the next uses constraint.
                             break;
                         }
@@ -1090,9 +1110,9 @@ public class ResolverImpl implements Resolver
                                 + usedBlame.m_cap.getRevision().getSymbolicName()
                                 + " [" + usedBlame.m_cap.getRevision()
                                 + "] via two dependency chains.\n\nChain 1:\n"
-                                + toStringBlame(importBlame)
+                                + toStringBlame(rc, allCandidates, importBlame)
                                 + "\n\nChain 2:\n"
-                                + toStringBlame(usedBlame),
+                                + toStringBlame(rc, allCandidates, usedBlame),
                                 null,
                                 null);
 
@@ -1115,14 +1135,12 @@ public class ResolverImpl implements Resolver
                             // See if we can permutate the candidates for blamed
                             // requirement; there may be no candidates if the revision
                             // associated with the requirement is already resolved.
-                            SortedSet<BundleCapability> candidates =
-                                permutation.getCandidates(req);
+                            List<BundleCapability> candidates = permutation.getCandidates(req);
                             if ((candidates != null) && (candidates.size() > 1))
                             {
                                 mutated.add(req);
-                                Iterator it = candidates.iterator();
-                                it.next();
-                                it.remove();
+                                // Remove the conflicting candidate.
+                                candidates.remove(0);
                                 // Continue with the next uses constraint.
                                 break;
                             }
@@ -1183,7 +1201,7 @@ public class ResolverImpl implements Resolver
                     try
                     {
                         checkPackageSpaceConsistency(
-                            false, importBlame.m_cap.getRevision(),
+                            rc, false, importBlame.m_cap.getRevision(),
                             allCandidates, revisionPkgMap, resultCache);
                     }
                     catch (ResolveException ex)
@@ -1207,14 +1225,12 @@ public class ResolverImpl implements Resolver
     private static void permutate(
         Candidates allCandidates, BundleRequirement req, List<Candidates> permutations)
     {
-        SortedSet<BundleCapability> candidates = allCandidates.getCandidates(req);
+        List<BundleCapability> candidates = allCandidates.getCandidates(req);
         if (candidates.size() > 1)
         {
             Candidates perm = allCandidates.copy();
             candidates = perm.getCandidates(req);
-            Iterator it = candidates.iterator();
-            it.next();
-            it.remove();
+            candidates.remove(0);
             permutations.add(perm);
         }
     }
@@ -1222,7 +1238,7 @@ public class ResolverImpl implements Resolver
     private static void permutateIfNeeded(
         Candidates allCandidates, BundleRequirement req, List<Candidates> permutations)
     {
-        SortedSet<BundleCapability> candidates = allCandidates.getCandidates(req);
+        List<BundleCapability> candidates = allCandidates.getCandidates(req);
         if (candidates.size() > 1)
         {
             // Check existing permutations to make sure we haven't
@@ -1234,8 +1250,8 @@ public class ResolverImpl implements Resolver
             boolean permutated = false;
             for (Candidates existingPerm : permutations)
             {
-                Set<BundleCapability> existingPermCands = existingPerm.getCandidates(req);
-                if (!existingPermCands.iterator().next().equals(candidates.iterator().next()))
+                List<BundleCapability> existingPermCands = existingPerm.getCandidates(req);
+                if (!existingPermCands.get(0).equals(candidates.get(0)))
                 {
                     permutated = true;
                 }
@@ -1273,7 +1289,7 @@ public class ResolverImpl implements Resolver
             {
                 if (!cap.getRevision().equals(revision))
                 {
-                    cap = new HostedCapability(revision, (BundleCapabilityImpl) cap);
+                    cap = new WrappedCapability(revision, (BundleCapabilityImpl) cap);
                 }
                 exports.put(
                     (String) cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
@@ -1293,11 +1309,10 @@ public class ResolverImpl implements Resolver
                 {
                     if (req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
                     {
-                        Set<BundleCapability> cands =
-                            allCandidates.getCandidates((BundleRequirementImpl) req);
+                        List<BundleCapability> cands = allCandidates.getCandidates(req);
                         if ((cands != null) && !cands.isEmpty())
                         {
-                            String pkgName = (String) cands.iterator().next()
+                            String pkgName = (String) cands.get(0)
                                 .getAttributes().get(BundleRevision.PACKAGE_NAMESPACE);
                             exports.remove(pkgName);
                         }
@@ -1391,12 +1406,22 @@ public class ResolverImpl implements Resolver
             List<BundleCapability> caps = (cap.getRevision().getWiring() != null)
                 ? cap.getRevision().getWiring().getCapabilities(null)
                 : cap.getRevision().getDeclaredCapabilities(null);
-            for (int capIdx = 0; capIdx < caps.size(); capIdx++)
+            for (BundleCapability sourceCap : caps)
             {
-                if (caps.get(capIdx).getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
-                    && caps.get(capIdx).getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).equals(pkgName))
+                if (sourceCap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
+                    && sourceCap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).equals(pkgName))
                 {
-                    sources.add(caps.get(capIdx));
+                    // Since capabilities may come from fragments, we need to check
+                    // for that case and wrap them.
+                    if (!cap.getRevision().equals(sourceCap.getRevision()))
+                    {
+                        sources.add(
+                            new WrappedCapability(cap.getRevision(), (BundleCapabilityImpl) sourceCap));
+                    }
+                    else
+                    {
+                        sources.add(sourceCap);
+                    }
                 }
             }
 
@@ -1415,29 +1440,29 @@ public class ResolverImpl implements Resolver
         return sources;
     }
 
-    private static BundleRevision getActualBundleRevision(BundleRevision br)
+    private static BundleRevision getDeclaringBundleRevision(BundleRevision br)
     {
-        if (br instanceof HostBundleRevision)
+        if (br instanceof WrappedRevision)
         {
-            return ((HostBundleRevision) br).getHost();
+            return ((WrappedRevision) br).getHost();
         }
         return br;
     }
 
-    private static BundleCapability getActualCapability(BundleCapability c)
+    private static BundleCapability getDeclaredCapability(BundleCapability c)
     {
         if (c instanceof HostedCapability)
         {
-            return ((HostedCapability) c).getOriginalCapability();
+            return ((HostedCapability) c).getDeclaredCapability();
         }
         return c;
     }
 
-    private static BundleRequirement getActualRequirement(BundleRequirement r)
+    private static BundleRequirement getDeclaredRequirement(BundleRequirement r)
     {
-        if (r instanceof HostedRequirement)
+        if (r instanceof WrappedRequirement)
         {
-            return ((HostedRequirement) r).getOriginalRequirement();
+            return ((WrappedRequirement) r).getOriginalRequirement();
         }
         return r;
     }
@@ -1447,7 +1472,7 @@ public class ResolverImpl implements Resolver
         Map<BundleRevision, List<ResolverWire>> wireMap,
         Candidates allCandidates)
     {
-        BundleRevision unwrappedRevision = getActualBundleRevision(revision);
+        BundleRevision unwrappedRevision = getDeclaringBundleRevision(revision);
         if ((unwrappedRevision.getWiring() == null)
             && !wireMap.containsKey(unwrappedRevision))
         {
@@ -1459,10 +1484,10 @@ public class ResolverImpl implements Resolver
 
             for (BundleRequirement req : revision.getDeclaredRequirements(null))
             {
-                SortedSet<BundleCapability> cands = allCandidates.getCandidates(req);
+                List<BundleCapability> cands = allCandidates.getCandidates(req);
                 if ((cands != null) && (cands.size() > 0))
                 {
-                    BundleCapability cand = cands.iterator().next();
+                    BundleCapability cand = cands.get(0);
                     // Ignore revisions that import themselves.
                     if (!revision.equals(cand.getRevision()))
                     {
@@ -1474,9 +1499,9 @@ public class ResolverImpl implements Resolver
                         Packages candPkgs = revisionPkgMap.get(cand.getRevision());
                         ResolverWire wire = new ResolverWireImpl(
                             unwrappedRevision,
-                            getActualRequirement(req),
-                            getActualBundleRevision(cand.getRevision()),
-                            getActualCapability(cand));
+                            getDeclaredRequirement(req),
+                            getDeclaringBundleRevision(cand.getRevision()),
+                            getDeclaredCapability(cand));
                         if (req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
                         {
                             packageWires.add(wire);
@@ -1499,9 +1524,9 @@ public class ResolverImpl implements Resolver
             wireMap.put(unwrappedRevision, packageWires);
 
             // Add host wire for any fragments.
-            if (revision instanceof HostBundleRevision)
+            if (revision instanceof WrappedRevision)
             {
-                List<BundleRevision> fragments = ((HostBundleRevision) revision).getFragments();
+                List<BundleRevision> fragments = ((WrappedRevision) revision).getFragments();
                 for (BundleRevision fragment : fragments)
                 {
                     List<ResolverWire> hostWires = wireMap.get(fragment);
@@ -1512,7 +1537,7 @@ public class ResolverImpl implements Resolver
                     }
                     hostWires.add(
                         new ResolverWireImpl(
-                            getActualBundleRevision(fragment),
+                            getDeclaringBundleRevision(fragment),
                             fragment.getDeclaredRequirements(
                                 BundleRevision.HOST_NAMESPACE).get(0),
                             unwrappedRevision,
@@ -1539,8 +1564,7 @@ public class ResolverImpl implements Resolver
             : Util.getDynamicRequirements(revision.getWiring().getRequirements(null)))
         {
             // Get the candidates for the current dynamic requirement.
-            SortedSet<BundleCapability> candCaps =
-                allCandidates.getCandidates((BundleRequirementImpl) req);
+            List<BundleCapability> candCaps = allCandidates.getCandidates(req);
             // Optional requirements may not have any candidates.
             if ((candCaps == null) || candCaps.isEmpty())
             {
@@ -1549,7 +1573,7 @@ public class ResolverImpl implements Resolver
 
             // Record the dynamic requirement.
             dynReq = req;
-            dynCand = candCaps.first();
+            dynCand = candCaps.get(0);
 
             // Can only dynamically import one at a time, so break
             // out of the loop after the first.
@@ -1564,14 +1588,12 @@ public class ResolverImpl implements Resolver
                     allCandidates);
             }
 
-            Map<String, Object> attrs = new HashMap(1);
-            attrs.put(BundleRevision.PACKAGE_NAMESPACE, pkgName);
             packageWires.add(
                 new ResolverWireImpl(
                     revision,
                     dynReq,
-                    getActualBundleRevision(dynCand.getRevision()),
-                    getActualCapability(dynCand)));
+                    getDeclaringBundleRevision(dynCand.getRevision()),
+                    getDeclaredCapability(dynCand)));
         }
 
         wireMap.put(revision, packageWires);
@@ -1614,7 +1636,8 @@ public class ResolverImpl implements Resolver
         }
     }
 
-    private static String toStringBlame(Blame blame)
+    private static String toStringBlame(
+        ResolveContext rc, Candidates allCandidates, Blame blame)
     {
         StringBuffer sb = new StringBuffer();
         if ((blame.m_reqs != null) && !blame.m_reqs.isEmpty())
@@ -1647,27 +1670,20 @@ public class ResolverImpl implements Resolver
                 }
                 if ((i + 1) < blame.m_reqs.size())
                 {
-                    BundleCapability cap = Util.getSatisfyingCapability(
-                        blame.m_reqs.get(i + 1).getRevision(),
-                        (BundleRequirementImpl) blame.m_reqs.get(i));
+                    BundleCapability cap = getSatisfyingCapability(
+                        rc,
+                        allCandidates,
+                        blame.m_reqs.get(i));
                     if (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
                     {
                         sb.append(BundleRevision.PACKAGE_NAMESPACE);
                         sb.append("=");
                         sb.append(cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).toString());
-                        BundleCapability usedCap;
-                        if ((i + 2) < blame.m_reqs.size())
-                        {
-                            usedCap = Util.getSatisfyingCapability(
-                                blame.m_reqs.get(i + 2).getRevision(),
-                                (BundleRequirementImpl) blame.m_reqs.get(i + 1));
-                        }
-                        else
-                        {
-                            usedCap = Util.getSatisfyingCapability(
-                                blame.m_cap.getRevision(),
-                                (BundleRequirementImpl) blame.m_reqs.get(i + 1));
-                        }
+                        BundleCapability usedCap =
+                            getSatisfyingCapability(
+                                rc,
+                                allCandidates,
+                                blame.m_reqs.get(i + 1));
                         sb.append("; uses:=");
                         sb.append(usedCap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE));
                     }
@@ -1679,9 +1695,10 @@ public class ResolverImpl implements Resolver
                 }
                 else
                 {
-                    BundleCapability export = Util.getSatisfyingCapability(
-                        blame.m_cap.getRevision(),
-                        (BundleRequirementImpl) blame.m_reqs.get(i));
+                    BundleCapability export = getSatisfyingCapability(
+                        rc,
+                        allCandidates,
+                        blame.m_reqs.get(i));
                     sb.append(export.getNamespace());
                     sb.append("=");
                     sb.append(export.getAttributes().get(export.getNamespace()).toString());
@@ -1712,6 +1729,42 @@ public class ResolverImpl implements Resolver
         return sb.toString();
     }
 
+    private static BundleCapability getSatisfyingCapability(
+        ResolveContext rc, Candidates allCandidates, BundleRequirement req)
+    {
+        BundleCapability cap = null;
+
+        // If the requiring revision is not resolved, then check in the
+        // candidate map for its matching candidate.
+        List<BundleCapability> cands = allCandidates.getCandidates(req);
+        if (cands != null)
+        {
+            cap = cands.get(0);
+        }
+        // Otherwise, if the requiring revision is resolved then check
+        // in its wires for the capability satisfying the requirement.
+        else if (rc.getWirings().containsKey(req.getRevision()))
+        {
+            List<BundleWire> wires = rc.getWirings().get(req.getRevision()).getRequiredWires(null);
+            req = getDeclaredRequirement(req);
+            for (BundleWire w : wires)
+            {
+                if (w.getRequirement().equals(req))
+                {
+// TODO: RESOLVER - This is not 100% correct, since requirements for
+//       dynamic imports with wildcards will reside on many wires and
+//       this code only finds the first one, not necessarily the correct
+//       one. This is only used for the diagnostic message, but it still
+//       could confuse the user.
+                    cap = w.getCapability();
+                    break;
+                }
+            }
+        }
+
+        return cap;
+    }
+
     private static class Packages
     {
         private final BundleRevision m_revision;
@@ -1719,6 +1772,7 @@ public class ResolverImpl implements Resolver
         public final Map<String, List<Blame>> m_importedPkgs = new HashMap();
         public final Map<String, List<Blame>> m_requiredPkgs = new HashMap();
         public final Map<String, List<Blame>> m_usedPkgs = new HashMap();
+        public boolean m_isCalculated = false;
 
         public Packages(BundleRevision revision)
         {
@@ -1754,4 +1808,4 @@ public class ResolverImpl implements Resolver
                 && m_cap.equals(((Blame) o).m_cap);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/felix/framework/resolver/ShadowList.java b/src/main/java/org/apache/felix/framework/resolver/ShadowList.java
new file mode 100644
index 0000000..e64b559
--- /dev/null
+++ b/src/main/java/org/apache/felix/framework/resolver/ShadowList.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.resolver;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+public class ShadowList<T> implements List<T>
+{
+    private final List<T> m_original;
+    private final List<T> m_shadow;
+
+    public ShadowList(List<T> original)
+    {
+        m_original = original;
+        m_shadow = new ArrayList<T>(original);
+    }
+
+    public List<T> getOriginal()
+    {
+        return m_original;
+    }
+
+    public int size()
+    {
+        return m_shadow.size();
+    }
+
+    public boolean isEmpty()
+    {
+        return m_shadow.isEmpty();
+    }
+
+    public boolean contains(Object o)
+    {
+        return m_shadow.contains(o);
+    }
+
+    public Iterator<T> iterator()
+    {
+        return m_shadow.iterator();
+    }
+
+    public Object[] toArray()
+    {
+        return m_shadow.toArray();
+    }
+
+    public <T> T[] toArray(T[] ts)
+    {
+        return m_shadow.toArray(ts);
+    }
+
+    public boolean add(T e)
+    {
+        return m_shadow.add(e);
+    }
+
+    public boolean remove(Object o)
+    {
+        return m_shadow.remove(o);
+    }
+
+    public boolean containsAll(Collection<?> clctn)
+    {
+        return m_shadow.containsAll(clctn);
+    }
+
+    public boolean addAll(Collection<? extends T> clctn)
+    {
+        return m_shadow.addAll(clctn);
+    }
+
+    public boolean addAll(int i, Collection<? extends T> clctn)
+    {
+        return m_shadow.addAll(i, clctn);
+    }
+
+    public boolean removeAll(Collection<?> clctn)
+    {
+        return m_shadow.removeAll(clctn);
+    }
+
+    public boolean retainAll(Collection<?> clctn)
+    {
+        return m_shadow.retainAll(clctn);
+    }
+
+    public void clear()
+    {
+        m_shadow.clear();
+    }
+
+    public T get(int i)
+    {
+        return m_shadow.get(i);
+    }
+
+    public T set(int i, T e)
+    {
+        return m_shadow.set(i, e);
+    }
+
+    public void add(int i, T e)
+    {
+        m_shadow.add(i, e);
+    }
+
+    public T remove(int i)
+    {
+        return m_shadow.remove(i);
+    }
+
+    public int indexOf(Object o)
+    {
+        return m_shadow.indexOf(o);
+    }
+
+    public int lastIndexOf(Object o)
+    {
+        return m_shadow.lastIndexOf(o);
+    }
+
+    public ListIterator<T> listIterator()
+    {
+        return m_shadow.listIterator();
+    }
+
+    public ListIterator<T> listIterator(int i)
+    {
+        return m_shadow.listIterator(i);
+    }
+
+    public List<T> subList(int i, int i1)
+    {
+        return m_shadow.subList(i, i1);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/felix/framework/resolver/Resolver.java b/src/main/java/org/apache/felix/framework/resolver/SimpleHostedCapability.java
similarity index 51%
copy from src/main/java/org/apache/felix/framework/resolver/Resolver.java
copy to src/main/java/org/apache/felix/framework/resolver/SimpleHostedCapability.java
index eabfdd1..89b2984 100644
--- a/src/main/java/org/apache/felix/framework/resolver/Resolver.java
+++ b/src/main/java/org/apache/felix/framework/resolver/SimpleHostedCapability.java
@@ -18,31 +18,48 @@
  */
 package org.apache.felix.framework.resolver;
 
-import java.util.List;
 import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
 import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleRevision;
 
-public interface Resolver
+class SimpleHostedCapability implements HostedCapability
 {
-    Map<BundleRevision, List<ResolverWire>> resolve(
-        ResolverState state,
-        Set<BundleRevision> mandatoryRevisions,
-        Set<BundleRevision> optionalRevisions,
-        Set<BundleRevision> ondemandFragments);
-    Map<BundleRevision, List<ResolverWire>> resolve(
-        ResolverState state, BundleRevision revision, String pkgName,
-        Set<BundleRevision> ondemandFragments);
-
-    public static interface ResolverState
+    private final BundleRevision m_host;
+    private final BundleCapability m_cap;
+
+    SimpleHostedCapability(BundleRevision host, BundleCapability cap)
+    {
+        m_host = host;
+        m_cap = cap;
+    }
+
+    public BundleRevision getResource()
+    {
+        return m_host;
+    }
+
+    public BundleRevision getRevision()
+    {
+        return m_host;
+    }
+
+    public BundleCapability getDeclaredCapability()
+    {
+        return m_cap;
+    }
+
+    public String getNamespace()
+    {
+        return m_cap.getNamespace();
+    }
+
+    public Map<String, String> getDirectives()
+    {
+        return m_cap.getDirectives();
+    }
+
+    public Map<String, Object> getAttributes()
     {
-        boolean isEffective(BundleRequirement req);
-        SortedSet<BundleCapability> getCandidates(
-            BundleRequirement req, boolean obeyMandatory);
-        void checkExecutionEnvironment(BundleRevision revision) throws ResolveException;
-        void checkNativeLibraries(BundleRevision revision) throws ResolveException;
+        return m_cap.getAttributes();
     }
 }
\ No newline at end of file
diff --git a/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java b/src/main/java/org/apache/felix/framework/resolver/WrappedCapability.java
similarity index 68%
copy from src/main/java/org/apache/felix/framework/resolver/HostedCapability.java
copy to src/main/java/org/apache/felix/framework/resolver/WrappedCapability.java
index dbdad1c..ee159ff 100644
--- a/src/main/java/org/apache/felix/framework/resolver/HostedCapability.java
+++ b/src/main/java/org/apache/felix/framework/resolver/WrappedCapability.java
@@ -1,20 +1,17 @@
 /*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
  *
- *   http://www.apache.org/licenses/LICENSE-2.0
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 package org.apache.felix.framework.resolver;
 
@@ -23,13 +20,14 @@ import java.util.Map;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.resource.Resource;
 
-public class HostedCapability extends BundleCapabilityImpl
+public class WrappedCapability extends BundleCapabilityImpl implements HostedCapability
 {
     private final BundleRevision m_host;
     private final BundleCapabilityImpl m_cap;
 
-    public HostedCapability(BundleRevision host, BundleCapabilityImpl cap)
+    public WrappedCapability(BundleRevision host, BundleCapabilityImpl cap)
     {
         super(host, cap.getNamespace(), cap.getDirectives(), cap.getAttributes());
         m_host = host;
@@ -47,7 +45,7 @@ public class HostedCapability extends BundleCapabilityImpl
         {
             return false;
         }
-        final HostedCapability other = (HostedCapability) obj;
+        final WrappedCapability other = (WrappedCapability) obj;
         if (m_host != other.m_host && (m_host == null || !m_host.equals(other.m_host)))
         {
             return false;
@@ -68,12 +66,18 @@ public class HostedCapability extends BundleCapabilityImpl
         return hash;
     }
 
-    public BundleCapabilityImpl getOriginalCapability()
+    public BundleCapability getDeclaredCapability()
     {
         return m_cap;
     }
 
     @Override
+    public BundleRevision getResource()
+    {
+        return m_host;
+    }
+
+    @Override
     public BundleRevision getRevision()
     {
         return m_host;
diff --git a/src/main/java/org/apache/felix/framework/resolver/HostedRequirement.java b/src/main/java/org/apache/felix/framework/resolver/WrappedRequirement.java
similarity index 93%
rename from src/main/java/org/apache/felix/framework/resolver/HostedRequirement.java
rename to src/main/java/org/apache/felix/framework/resolver/WrappedRequirement.java
index 58dadce..c0d15e0 100644
--- a/src/main/java/org/apache/felix/framework/resolver/HostedRequirement.java
+++ b/src/main/java/org/apache/felix/framework/resolver/WrappedRequirement.java
@@ -23,12 +23,12 @@ import org.apache.felix.framework.capabilityset.SimpleFilter;
 import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.osgi.framework.wiring.BundleRevision;
 
-public class HostedRequirement extends BundleRequirementImpl
+public class WrappedRequirement extends BundleRequirementImpl
 {
     private final BundleRevision m_host;
     private final BundleRequirementImpl m_req;
 
-    public HostedRequirement(BundleRevision host, BundleRequirementImpl req)
+    public WrappedRequirement(BundleRevision host, BundleRequirementImpl req)
     {
         super(host, req.getNamespace(), req.getDirectives(), req.getAttributes());
         m_host = host;
@@ -46,7 +46,7 @@ public class HostedRequirement extends BundleRequirementImpl
         {
             return false;
         }
-        final HostedRequirement other = (HostedRequirement) obj;
+        final WrappedRequirement other = (WrappedRequirement) obj;
         if (m_host != other.m_host && (m_host == null || !m_host.equals(other.m_host)))
         {
             return false;
diff --git a/src/main/java/org/apache/felix/framework/resolver/HostBundleRevision.java b/src/main/java/org/apache/felix/framework/resolver/WrappedRevision.java
similarity index 75%
rename from src/main/java/org/apache/felix/framework/resolver/HostBundleRevision.java
rename to src/main/java/org/apache/felix/framework/resolver/WrappedRevision.java
index 3f052bb..fa4ab5d 100644
--- a/src/main/java/org/apache/felix/framework/resolver/HostBundleRevision.java
+++ b/src/main/java/org/apache/felix/framework/resolver/WrappedRevision.java
@@ -19,8 +19,8 @@
 package org.apache.felix.framework.resolver;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
+import org.apache.felix.framework.util.ImmutableList;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.osgi.framework.Bundle;
@@ -29,15 +29,17 @@ import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
 
-class HostBundleRevision implements BundleRevision
+class WrappedRevision implements BundleRevision
 {
     private final BundleRevision m_host;
     private final List<BundleRevision> m_fragments;
     private List<BundleCapability> m_cachedCapabilities = null;
     private List<BundleRequirement> m_cachedRequirements = null;
 
-    public HostBundleRevision(BundleRevision host, List<BundleRevision> fragments)
+    public WrappedRevision(BundleRevision host, List<BundleRevision> fragments)
     {
         m_host = host;
         m_fragments = fragments;
@@ -63,6 +65,16 @@ class HostBundleRevision implements BundleRevision
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
+    public List<Capability> getCapabilities(String namespace)
+    {
+        return asCapabilityList(getDeclaredCapabilities(namespace));
+    }
+
+    private static List<Capability> asCapabilityList(List caps)
+    {
+        return (List<Capability>) caps;
+    }
+
     public List<BundleCapability> getDeclaredCapabilities(String namespace)
     {
         if (m_cachedCapabilities == null)
@@ -72,7 +84,7 @@ class HostBundleRevision implements BundleRevision
             // Wrap host capabilities.
             for (BundleCapability cap : m_host.getDeclaredCapabilities(null))
             {
-                caps.add(new HostedCapability(this, (BundleCapabilityImpl) cap));
+                caps.add(new WrappedCapability(this, (BundleCapabilityImpl) cap));
             }
 
             // Wrap fragment capabilities.
@@ -84,15 +96,25 @@ class HostBundleRevision implements BundleRevision
                     {
 // TODO: OSGi R4.4 - OSGi R4.4 may introduce an identity capability, if so
 //       that will need to be excluded from here.
-                        caps.add(new HostedCapability(this, (BundleCapabilityImpl) cap));
+                        caps.add(new WrappedCapability(this, (BundleCapabilityImpl) cap));
                     }
                 }
             }
-            m_cachedCapabilities = Collections.unmodifiableList(caps);
+            m_cachedCapabilities = ImmutableList.newInstance(caps);
         }
         return m_cachedCapabilities;
     }
 
+    public List<Requirement> getRequirements(String namespace)
+    {
+        return asRequirementList(getDeclaredRequirements(namespace));
+    }
+
+    private static List<Requirement> asRequirementList(List reqs)
+    {
+        return (List<Requirement>) reqs;
+    }
+
     public List<BundleRequirement> getDeclaredRequirements(String namespace)
     {
         if (m_cachedRequirements == null)
@@ -102,7 +124,7 @@ class HostBundleRevision implements BundleRevision
             // Wrap host requirements.
             for (BundleRequirement req : m_host.getDeclaredRequirements(null))
             {
-                reqs.add(new HostedRequirement(this, (BundleRequirementImpl) req));
+                reqs.add(new WrappedRequirement(this, (BundleRequirementImpl) req));
             }
 
             // Wrap fragment requirements.
@@ -114,12 +136,12 @@ class HostBundleRevision implements BundleRevision
                     {
                         if (!req.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
                         {
-                            reqs.add(new HostedRequirement(this, (BundleRequirementImpl) req));
+                            reqs.add(new WrappedRequirement(this, (BundleRequirementImpl) req));
                         }
                     }
                 }
             }
-            m_cachedRequirements = Collections.unmodifiableList(reqs);
+            m_cachedRequirements = ImmutableList.newInstance(reqs);
         }
         return m_cachedRequirements;
     }
@@ -139,6 +161,7 @@ class HostBundleRevision implements BundleRevision
         return m_host.getBundle();
     }
 
+    @Override
     public String toString()
     {
         return m_host.toString();
diff --git a/src/main/java/org/apache/felix/framework/util/EventDispatcher.java b/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
index a08f4a6..c5c264c 100644
--- a/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
+++ b/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
@@ -48,6 +48,7 @@ import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServicePermission;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.framework.UnfilteredServiceListener;
 import org.osgi.framework.hooks.service.ListenerHook;
 import org.osgi.framework.launch.Framework;
 
@@ -640,15 +641,15 @@ public class EventDispatcher
         return listeners;
     }
 
-    private Set<BundleContext> createWhitelistFromHooks(
+    private <T> Set<BundleContext> createWhitelistFromHooks(
         EventObject event, Framework felix,
         Map<BundleContext, List<ListenerInfo>> listeners1,
         Map<BundleContext, List<ListenerInfo>> listeners2,
-        Class hookClass)
+        Class<T> hookClass)
     {
         // Create a whitelist of bundle context, if we have hooks.
         Set<BundleContext> whitelist = null;
-        Set<ServiceReference> hooks = m_registry.getHooks(hookClass);
+        Set<ServiceReference<T>> hooks = m_registry.getHooks(hookClass);
         if ((hooks != null) && !hooks.isEmpty())
         {
             whitelist = new HashSet<BundleContext>();
@@ -667,11 +668,11 @@ public class EventDispatcher
             int originalSize = whitelist.size();
             ShrinkableCollection<BundleContext> shrinkable =
                 new ShrinkableCollection<BundleContext>(whitelist);
-            for (ServiceReference sr : hooks)
+            for (ServiceReference<T> sr : hooks)
             {
                 if (felix != null)
                 {
-                    Object eh = null;
+                    T eh = null;
                     try
                     {
                         eh = m_registry.getService(felix, sr);
@@ -908,8 +909,18 @@ public class EventDispatcher
         if (hasPermission)
         {
             // Dispatch according to the filter.
-            boolean matched = (filter == null)
-                || filter.match(((ServiceEvent) event).getServiceReference());
+            boolean matched;
+            if (l instanceof UnfilteredServiceListener)
+            {
+                // An UnfilteredServiceListener always matches, regardless of the filter.
+                // The filter is still passed on to the Service Registry Hooks.
+                matched = true;
+            }
+            else
+            {
+                matched = (filter == null)
+                        || filter.match(((ServiceEvent) event).getServiceReference());
+            }
 
             if (matched)
             {
@@ -1112,4 +1123,4 @@ public class EventDispatcher
         public Map<BundleContext, List<ListenerInfo>> m_listeners = null;
         public EventObject m_event = null;
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/felix/framework/util/FelixConstants.java b/src/main/java/org/apache/felix/framework/util/FelixConstants.java
index df8ba28..511657c 100644
--- a/src/main/java/org/apache/felix/framework/util/FelixConstants.java
+++ b/src/main/java/org/apache/felix/framework/util/FelixConstants.java
@@ -64,4 +64,5 @@ public interface FelixConstants extends org.osgi.framework.Constants
     // Miscellaneous properties values.
     String FAKE_URL_PROTOCOL_VALUE = "location:";
     String FELIX_EXTENSION_ACTIVATOR = "Felix-Activator";
-}
\ No newline at end of file
+    String SECURITY_DEFAULT_POLICY = "felix.security.defaultpolicy";
+}
diff --git a/src/main/java/org/apache/felix/framework/util/ImmutableList.java b/src/main/java/org/apache/felix/framework/util/ImmutableList.java
new file mode 100644
index 0000000..f0a1a9c
--- /dev/null
+++ b/src/main/java/org/apache/felix/framework/util/ImmutableList.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.util;
+
+import java.util.AbstractList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.ListIterator;
+import java.util.RandomAccess;
+
+public class ImmutableList<E> extends AbstractList<E> implements RandomAccess
+{
+    final Object[] elements;
+
+    public static <E> ImmutableList<E> newInstance(E... elements)
+    {
+        return new ImmutableList<E>(elements);
+    }
+
+    public static <E> ImmutableList<E> newInstance(Collection<? extends E> elements)
+    {
+        if (elements instanceof ImmutableList)
+        {
+            return (ImmutableList<E>) elements;
+        }
+        else
+        {
+            return new ImmutableList<E>(elements);
+        }
+    }
+
+    protected ImmutableList(E... elements)
+    {
+        this.elements = elements.clone();
+    }
+
+    protected ImmutableList(Collection<? extends E> elements)
+    {
+        this.elements = elements.toArray();
+    }
+
+    public E get(int index)
+    {
+        return (E) elements[index];
+    }
+
+    public int size()
+    {
+        return elements.length;
+    }
+
+    @Override
+    public boolean remove(Object o)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean removeAll(Collection<?> clctn)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Iterator<E> iterator()
+    {
+        return listIterator();
+    }
+
+    @Override
+    public ListIterator<E> listIterator(int index)
+    {
+        return new ListItr(index);
+    }
+
+    private class ListItr implements ListIterator<E>
+    {
+        int cursor;
+
+        private ListItr(int cursor)
+        {
+            this.cursor = cursor;
+        }
+
+        public boolean hasNext()
+        {
+            return cursor != size();
+        }
+
+        public E next()
+        {
+            return (E) elements[cursor++];
+        }
+
+        public boolean hasPrevious()
+        {
+            return cursor != 0;
+        }
+
+        public E previous()
+        {
+            return (E) elements[--cursor];
+        }
+
+        public int nextIndex()
+        {
+            return cursor;
+        }
+
+        public int previousIndex()
+        {
+            return cursor - 1;
+        }
+
+        public void remove()
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        public void set(E e)
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        public void add(E e)
+        {
+            throw new UnsupportedOperationException();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/felix/framework/util/ImmutableMap.java b/src/main/java/org/apache/felix/framework/util/ImmutableMap.java
new file mode 100644
index 0000000..1ee3140
--- /dev/null
+++ b/src/main/java/org/apache/felix/framework/util/ImmutableMap.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.util;
+
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+public class ImmutableMap<K, V> extends AbstractMap<K, V>
+{
+    final Entry<K, V>[] entries;
+
+    public static <K, V> ImmutableMap<K, V> newInstance(Entry<K, V>... entries)
+    {
+        return new ImmutableMap<K, V>(entries);
+    }
+
+    public static <K, V> ImmutableMap<K, V> newInstance(Map<K, V> entries)
+    {
+        if (entries instanceof ImmutableMap)
+        {
+            return (ImmutableMap<K, V>) entries;
+        }
+        else
+        {
+            return new ImmutableMap<K, V>(entries);
+        }
+    }
+
+    protected ImmutableMap(Entry<K, V>[] entries)
+    {
+        this.entries = entries.clone();
+    }
+
+    protected ImmutableMap(Map<K, V> map)
+    {
+        this.entries = map.entrySet().toArray(new Entry[map.size()]);
+    }
+
+    @Override
+    public V get(Object key)
+    {
+        if (key == null)
+        {
+            for (int i = 0; i < entries.length; i++)
+            {
+                if (entries[i].getKey() == null)
+                {
+                    return entries[i].getValue();
+                }
+            }
+        }
+        else
+        {
+            for (int i = 0; i < entries.length; i++)
+            {
+                if (key.equals(entries[i].getKey()))
+                {
+                    return entries[i].getValue();
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Set<Entry<K, V>> entrySet()
+    {
+        return new EntrySet();
+    }
+
+    private class EntrySet extends AbstractSet<Entry<K, V>>
+    {
+        @Override
+        public Iterator<Entry<K, V>> iterator()
+        {
+            return new EntryItr(0);
+        }
+
+        @Override
+        public int size()
+        {
+            return entries.length;
+        }
+    }
+
+    private class EntryItr implements Iterator<Entry<K, V>>
+    {
+        int cursor;
+
+        private EntryItr(int cursor)
+        {
+            this.cursor = cursor;
+        }
+
+        public boolean hasNext()
+        {
+            return cursor != size();
+        }
+
+        public Entry<K, V> next()
+        {
+            return entries[cursor++];
+        }
+
+        public void remove()
+        {
+            throw new UnsupportedOperationException();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/felix/framework/util/SecureAction.java b/src/main/java/org/apache/felix/framework/util/SecureAction.java
index 50d3a13..a6a2584 100644
--- a/src/main/java/org/apache/felix/framework/util/SecureAction.java
+++ b/src/main/java/org/apache/felix/framework/util/SecureAction.java
@@ -27,8 +27,8 @@ import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Map;
 import java.util.zip.ZipFile;
-import org.osgi.framework.Bundle;
 
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
@@ -171,14 +171,14 @@ public class SecureAction
         }
     }
 
-    public Class forName(String name) throws ClassNotFoundException
+    public Class forName(String name, ClassLoader classloader) throws ClassNotFoundException
     {
         if (System.getSecurityManager() != null)
         {
             try
             {
                 Actions actions = (Actions) m_actions.get();
-                actions.set(Actions.FOR_NAME_ACTION, name);
+                actions.set(Actions.FOR_NAME_ACTION, name, classloader);
                 return (Class) AccessController.doPrivileged(actions, m_acc);
             }
             catch (PrivilegedActionException ex)
@@ -190,6 +190,10 @@ public class SecureAction
                 throw (RuntimeException) ex.getException();
             }
         }
+        else if (classloader != null)
+        {
+            return Class.forName(name, true, classloader);
+        }
         else
         {
             return Class.forName(name);
@@ -1052,6 +1056,30 @@ public class SecureAction
         }
     }
 
+    public void invokeBundleCollisionHook(
+        org.osgi.framework.hooks.bundle.CollisionHook ch, int operationType,
+        Bundle targetBundle, Collection<Bundle> collisionCandidates)
+        throws Exception
+    {
+        if (System.getSecurityManager() != null)
+        {
+            Actions actions = (Actions) m_actions.get();
+            actions.set(Actions.INVOKE_BUNDLE_COLLISION_HOOK, ch, operationType, targetBundle, collisionCandidates);
+            try
+            {
+                AccessController.doPrivileged(actions, m_acc);
+            }
+            catch (PrivilegedActionException e)
+            {
+                throw e.getException();
+            }
+        }
+        else
+        {
+            ch.filterCollisions(operationType, targetBundle, collisionCandidates);
+        }
+    }
+
     public void invokeBundleFindHook(
         org.osgi.framework.hooks.bundle.FindHook fh,
         BundleContext bc, Collection<Bundle> bundles)
@@ -1084,7 +1112,7 @@ public class SecureAction
         if (System.getSecurityManager() != null)
         {
             Actions actions = (Actions) m_actions.get();
-            actions.set(Actions.INVOKE_BUNDLE_EVENT_HOOK, eh, contexts);
+            actions.set(Actions.INVOKE_BUNDLE_EVENT_HOOK, eh, event, contexts);
             try
             {
                 AccessController.doPrivileged(actions, m_acc);
@@ -1132,7 +1160,7 @@ public class SecureAction
         if (System.getSecurityManager() != null)
         {
             Actions actions = (Actions) m_actions.get();
-            actions.set(Actions.INVOKE_SERVICE_EVENT_HOOK, eh, contexts);
+            actions.set(Actions.INVOKE_SERVICE_EVENT_HOOK, eh, event, contexts);
             try
             {
                 AccessController.doPrivileged(actions, m_acc);
@@ -1158,7 +1186,7 @@ public class SecureAction
         {
             Actions actions = (Actions) m_actions.get();
             actions.set(
-                Actions.INVOKE_SERVICE_EVENT_HOOK, fh, context, name, filter,
+                Actions.INVOKE_SERVICE_FIND_HOOK, fh, context, name, filter,
                 (allServices) ? Boolean.TRUE : Boolean.FALSE, references);
             try
             {
@@ -1232,7 +1260,7 @@ public class SecureAction
         if (System.getSecurityManager() != null)
         {
             Actions actions = (Actions) m_actions.get();
-            actions.set(Actions.INVOKE_SERVICE_EVENT_LISTENER_HOOK, elh, listeners);
+            actions.set(Actions.INVOKE_SERVICE_EVENT_LISTENER_HOOK, elh, event, listeners);
             try
             {
                 AccessController.doPrivileged(actions, m_acc);
@@ -1424,6 +1452,7 @@ public class SecureAction
         public static final int INVOKE_RESOLVER_HOOK_SINGLETON = 50;
         public static final int INVOKE_RESOLVER_HOOK_MATCHES = 51;
         public static final int INVOKE_RESOLVER_HOOK_END = 52;
+        public static final int INVOKE_BUNDLE_COLLISION_HOOK = 53;
 
         private int m_action = -1;
         private Object m_arg1 = null;
@@ -1543,7 +1572,8 @@ public class SecureAction
                 case FILE_IS_DIRECTORY_ACTION:
                     return ((File) arg1).isDirectory() ? Boolean.TRUE : Boolean.FALSE;
                 case FOR_NAME_ACTION:
-                    return Class.forName((String) arg1);
+                    return (arg2 == null) ? Class.forName((String) arg1) : Class.forName((String) arg1, true,
+                        (ClassLoader) arg2);
                 case GET_ABSOLUTE_PATH_ACTION:
                     return ((File) arg1).getAbsolutePath();
                 case GET_CONSTRUCTOR_ACTION:
@@ -1668,9 +1698,13 @@ public class SecureAction
                 case INVOKE_RESOLVER_HOOK_END:
                     ((org.osgi.framework.hooks.resolver.ResolverHook) arg1).end();
                     return null;
+                case INVOKE_BUNDLE_COLLISION_HOOK:
+                    ((org.osgi.framework.hooks.bundle.CollisionHook) arg1).filterCollisions((Integer) arg2,
+                        (Bundle) arg3, (Collection<Bundle>) arg4);
+                    return null;
             }
 
             return null;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/felix/framework/util/StringMap.java b/src/main/java/org/apache/felix/framework/util/StringMap.java
index 7ad7f78..39c2eb6 100644
--- a/src/main/java/org/apache/felix/framework/util/StringMap.java
+++ b/src/main/java/org/apache/felix/framework/util/StringMap.java
@@ -27,108 +27,191 @@ import java.util.*;
  * map will be converted to a <tt>String</tt> using the
  * <tt>toString()</tt> method, since it is only intended to
  * compare strings.
-**/
-public class StringMap implements Map
+ **/
+public class StringMap extends AbstractMap<String, Object>
 {
-    private TreeMap m_map;
+    private static final CharArrayComparator COMPARATOR = new CharArrayComparator();
 
-    public StringMap()
-    {
-        this(true);
-    }
-
-    public StringMap(boolean caseSensitive)
-    {
-        m_map = new TreeMap(new StringComparator(caseSensitive));
-    }
-
-    public StringMap(Map map, boolean caseSensitive)
-    {
-        this(caseSensitive);
-        putAll(map);
-    }
+    private final TreeMap<char[], KeyValueEntry> m_map = new TreeMap<char[], KeyValueEntry>(COMPARATOR);
 
-    public boolean isCaseSensitive()
+    public StringMap()
     {
-        return ((StringComparator) m_map.comparator()).isCaseSensitive();
     }
 
-    public void setCaseSensitive(boolean b)
+    public StringMap(Map<? extends Object, ? extends Object> map)
     {
-        if (isCaseSensitive() != b)
+        for (Map.Entry<? extends Object, ? extends Object> e : map.entrySet())
         {
-            TreeMap map = new TreeMap(new StringComparator(b));
-            map.putAll(m_map);
-            m_map = map;
+            KeyValueEntry kve = (KeyValueEntry) m_map.put(
+                toUpperCase(e.getKey().toString()),
+                new KeyValueEntry(e.getKey().toString(), e.getValue()));
         }
     }
 
+    @Override
     public int size()
     {
         return m_map.size();
     }
 
+    @Override
     public boolean isEmpty()
     {
         return m_map.isEmpty();
     }
 
+    @Override
     public boolean containsKey(Object arg0)
     {
-        return m_map.containsKey(arg0);
+        return m_map.containsKey(toUpperCase(arg0.toString()));
     }
 
+    @Override
     public boolean containsValue(Object arg0)
     {
         return m_map.containsValue(arg0);
     }
 
+    @Override
     public Object get(Object arg0)
     {
-        return m_map.get(arg0);
+        KeyValueEntry kve = m_map.get(toUpperCase(arg0.toString()));
+        return (kve != null) ? kve.value : null;
     }
 
-    public Object put(Object key, Object value)
+    @Override
+    public Object put(String key, Object value)
     {
-        return m_map.put(key.toString(), value);
+        KeyValueEntry kve = (KeyValueEntry) m_map.put(toUpperCase(key), new KeyValueEntry(key, value));
+        return (kve != null) ? kve.value : null;
     }
 
-    public void putAll(Map map)
+    @Override
+    public void putAll(Map<? extends String, ? extends Object> map)
     {
-        for (Iterator it = map.entrySet().iterator(); it.hasNext(); )
+        for (Map.Entry<? extends String, ? extends Object> e : map.entrySet())
         {
-            Map.Entry entry = (Map.Entry) it.next();
-            put(entry.getKey(), entry.getValue());
+            put(e.getKey().toString(), e.getValue());
         }
     }
 
+    @Override
     public Object remove(Object arg0)
     {
-        return m_map.remove(arg0);
+        KeyValueEntry kve = m_map.remove(toUpperCase(arg0.toString()));
+        return (kve != null) ? kve.value : null;
     }
 
+    @Override
     public void clear()
     {
         m_map.clear();
     }
 
-    public Set keySet()
+    public Set<Entry<String, Object>> entrySet()
     {
-        return m_map.keySet();
+        return new AbstractSet<Entry<String, Object>>()
+        {
+            @Override
+            public Iterator<Entry<String, Object>> iterator()
+            {
+                return new Iterator<Entry<String, Object>>()
+                {
+                    Iterator<Entry<char[], KeyValueEntry>> it = m_map.entrySet().iterator();
+
+                    public boolean hasNext()
+                    {
+                        return it.hasNext();
+                    }
+
+                    public Entry<String, Object> next()
+                    {
+                        return it.next().getValue();
+                    }
+
+                    public void remove()
+                    {
+                        throw new UnsupportedOperationException();
+                    }
+                };
+            }
+
+            @Override
+            public int size()
+            {
+                return m_map.size();
+            }
+        };
+    }
+
+    private static char[] toUpperCase(String str)
+    {
+        char[] ch = str.toCharArray();
+        for (int i = 0; i < ch.length; i++)
+        {
+            char c = ch[i];
+            if (c < 128)
+            {
+                if ('a' <= c && c <= 'z')
+                {
+                    ch[i] = (char)(c - ('a' - 'A'));
+                }
+            }
+            else
+            {
+                ch[i] = Character.toUpperCase(c);
+            }
+        }
+        return ch;
     }
 
-    public Collection values()
+    private static class CharArrayComparator implements Comparator<char[]>
     {
-        return m_map.values();
+        public int compare(char[] v1, char[] v2)
+        {
+            int len1 = v1.length;
+            int len2 = v2.length;
+            int n = Math.min(len1, len2);
+            int k = 0;
+            while (k < n)
+            {
+                char c1 = v1[k];
+                char c2 = v2[k];
+                if (c1 != c2)
+                {
+                    return c1 - c2;
+                }
+                k++;
+            }
+            return len1 - len2;
+        }
     }
 
-    public Set entrySet()
+    private static class KeyValueEntry implements Map.Entry<String, Object>
     {
-        return m_map.entrySet();
-    }
+        private KeyValueEntry(String key, Object value)
+        {
+            this.key = key;
+            this.value = value;
+        }
 
-    public String toString()
-    {
-        return m_map.toString();
+        public String getKey()
+        {
+            return key;
+        }
+
+        public Object getValue()
+        {
+            return value;
+        }
+
+        public Object setValue(Object value)
+        {
+            Object v = this.value;
+            this.value = value;
+            return v;
+        }
+        String key;
+        Object value;
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/felix/framework/util/Util.java b/src/main/java/org/apache/felix/framework/util/Util.java
index 0e843c9..ac9500b 100644
--- a/src/main/java/org/apache/felix/framework/util/Util.java
+++ b/src/main/java/org/apache/felix/framework/util/Util.java
@@ -285,26 +285,6 @@ public class Util
         return allow;
     }
 
-    public static BundleCapability getSatisfyingCapability(
-        BundleRevision br, BundleRequirementImpl req)
-    {
-        List<BundleCapability> caps = (br.getWiring() != null)
-            ? br.getWiring().getCapabilities(null)
-            : br.getDeclaredCapabilities(null);
-        if (caps != null)
-        {
-            for (BundleCapability cap : caps)
-            {
-                if (cap.getNamespace().equals(req.getNamespace())
-                    && CapabilitySet.matches((BundleCapabilityImpl) cap, req.getFilter()))
-                {
-                    return cap;
-                }
-            }
-        }
-        return null;
-    }
-
     /**
      * Returns all the capabilities from a module that has a specified namespace.
      *
@@ -361,8 +341,8 @@ public class Util
                 {
                     if (w.getCapability().getNamespace()
                             .equals(BundleRevision.PACKAGE_NAMESPACE) &&
-                        w.getCapability().getAttributes()
-                            .get(BundleRevision.PACKAGE_NAMESPACE).equals(name))
+                            w.getCapability().getAttributes()
+                                    .get(BundleRevision.PACKAGE_NAMESPACE).equals(name))
                     {
                         return w;
                     }
@@ -372,6 +352,26 @@ public class Util
         return null;
     }
 
+    public static BundleCapability getPackageCapability(BundleRevision br, String name)
+    {
+        if (br.getWiring() != null)
+        {
+            List<BundleCapability> capabilities = br.getWiring().getCapabilities(null);
+            if (capabilities != null)
+            {
+                for (BundleCapability c : capabilities)
+                {
+                    if (c.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
+                        && c.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).equals(name))
+                    {
+                        return c;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
     private static final byte encTab[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
         0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,
         0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64,
diff --git a/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java b/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
index 1c66e33..672fd2f 100644
--- a/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
+++ b/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
@@ -18,25 +18,37 @@
  */
 package org.apache.felix.framework.util.manifestparser;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Map.Entry;
-import org.apache.felix.framework.BundleRevisionImpl;
+import java.util.Set;
 
+import org.apache.felix.framework.BundleRevisionImpl;
 import org.apache.felix.framework.Logger;
 import org.apache.felix.framework.capabilityset.SimpleFilter;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.apache.felix.framework.util.FelixConstants;
 import org.apache.felix.framework.util.VersionRange;
+import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
+import org.osgi.framework.namespace.IdentityNamespace;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleRevision;
 
 public class ManifestParser
 {
+    private static final String BUNDLE_LICENSE_HEADER = "Bundle-License"; // No constant defined by OSGi...
+
     private final Logger m_logger;
     private final Map m_configMap;
     private final Map m_headerMap;
@@ -130,6 +142,11 @@ public class ManifestParser
                         hostAttrs));
                 }
             }
+
+            //
+            // Add the osgi.identity capability.
+            //
+            capList.add(addIdentityCapability(owner, headerMap, bundleCap));
         }
 
         // Verify that bundle symbolic name is specified.
@@ -183,6 +200,12 @@ public class ManifestParser
         List<BundleRequirement> requireReqs = convertRequireCapabilities(importClauses, owner);
 
         //
+        // Parse Bundle-RequiredExecutionEnvironment.
+        //
+        List<BundleRequirement> breeReqs =
+            parseBreeHeader((String) headerMap.get(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT), owner);
+
+        //
         // Parse Export-Package.
         //
 
@@ -229,13 +252,14 @@ public class ManifestParser
 
         // Combine all requirements.
         m_requirements = new ArrayList(
-            importReqs.size() + rbReqs.size() + hostReqs.size()
-            + requireReqs.size() + dynamicReqs.size());
+            hostReqs.size() + importReqs.size() + rbReqs.size()
+            + requireReqs.size() + dynamicReqs.size() + breeReqs.size());
+        m_requirements.addAll(hostReqs);
         m_requirements.addAll(importReqs);
         m_requirements.addAll(rbReqs);
-        m_requirements.addAll(hostReqs);
         m_requirements.addAll(requireReqs);
         m_requirements.addAll(dynamicReqs);
+        m_requirements.addAll(breeReqs);
 
         //
         // Parse Bundle-NativeCode.
@@ -552,6 +576,13 @@ public class ManifestParser
                     : new SimpleFilter(null, null, SimpleFilter.MATCH_ALL);
                 for (String path : clause.m_paths)
                 {
+                    if (path.startsWith("osgi.wiring."))
+                    {
+                        throw new BundleException("Manifest cannot use Require-Capability for '"
+                            + path
+                            + "' namespace.");
+                    }
+
                     // Create requirement and add to requirement list.
                     reqList.add(
                         new BundleRequirementImpl(
@@ -678,12 +709,20 @@ public class ManifestParser
 
     private static List<BundleCapability> convertProvideCapabilities(
         List<ParsedHeaderClause> clauses, BundleRevision owner)
+        throws BundleException
     {
         List<BundleCapability> capList = new ArrayList();
         for (ParsedHeaderClause clause : clauses)
         {
             for (String path : clause.m_paths)
             {
+                if (path.startsWith("osgi.wiring."))
+                {
+                    throw new BundleException("Manifest cannot use Provide-Capability for '"
+                        + path
+                        + "' namespace.");
+                }
+
                 // Create package capability and add to capability list.
                 capList.add(
                     new BundleCapabilityImpl(
@@ -1284,6 +1323,55 @@ public class ManifestParser
         return null;
     }
 
+    private static BundleCapabilityImpl addIdentityCapability(BundleRevision owner,
+        Map headerMap, BundleCapabilityImpl bundleCap)
+    {
+        Map<String, Object> attrs = new HashMap<String, Object>();
+
+        attrs.put(IdentityNamespace.IDENTITY_NAMESPACE,
+            bundleCap.getAttributes().get(BundleNamespace.BUNDLE_NAMESPACE));
+        attrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE,
+            headerMap.get(Constants.FRAGMENT_HOST) == null
+            ? IdentityNamespace.TYPE_BUNDLE
+            : IdentityNamespace.TYPE_FRAGMENT);
+        attrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE,
+            bundleCap.getAttributes().get(Constants.BUNDLE_VERSION_ATTRIBUTE));
+
+        if (headerMap.get(Constants.BUNDLE_COPYRIGHT) != null)
+        {
+            attrs.put(IdentityNamespace.CAPABILITY_COPYRIGHT_ATTRIBUTE,
+                headerMap.get(Constants.BUNDLE_COPYRIGHT));
+        }
+
+        if (headerMap.get(Constants.BUNDLE_DESCRIPTION) != null)
+        {
+            attrs.put(IdentityNamespace.CAPABILITY_DESCRIPTION_ATTRIBUTE,
+                headerMap.get(Constants.BUNDLE_DESCRIPTION));
+        }
+        if (headerMap.get(Constants.BUNDLE_DOCURL) != null)
+        {
+            attrs.put(IdentityNamespace.CAPABILITY_DOCUMENTATION_ATTRIBUTE,
+                headerMap.get(Constants.BUNDLE_DOCURL));
+        }
+        if (headerMap.get(BUNDLE_LICENSE_HEADER) != null)
+        {
+            attrs.put(IdentityNamespace.CAPABILITY_LICENSE_ATTRIBUTE,
+                headerMap.get(BUNDLE_LICENSE_HEADER));
+        }
+
+        Map<String, String> dirs;
+        if (bundleCap.getDirectives().get(Constants.SINGLETON_DIRECTIVE) != null)
+        {
+            dirs = Collections.singletonMap(IdentityNamespace.CAPABILITY_SINGLETON_DIRECTIVE,
+                    bundleCap.getDirectives().get(Constants.SINGLETON_DIRECTIVE));
+        }
+        else
+        {
+            dirs = Collections.emptyMap();
+        }
+        return new BundleCapabilityImpl(owner, IdentityNamespace.IDENTITY_NAMESPACE, dirs, attrs);
+    }
+
     private static List<BundleRequirementImpl> parseFragmentHost(
         Logger logger, BundleRevision owner, Map headerMap)
         throws BundleException
@@ -1363,7 +1451,6 @@ public class ManifestParser
             s = (s == null) ? (String) headerMap.get(Constants.BUNDLE_NAME) : s;
             s = (s == null) ? headerMap.toString() : s;
             logger.log(
-                owner.getBundle(),
                 Logger.LOG_WARNING,
                 "Only R4 bundles can be fragments: " + s);
         }
@@ -1389,6 +1476,126 @@ public class ManifestParser
         return caps;
     }
 
+    private static List<BundleRequirement> parseBreeHeader(String header, BundleRevision owner)
+    {
+        List<String> filters = new ArrayList<String>();
+        for (String entry : parseDelimitedString(header, ","))
+        {
+            List<String> names = parseDelimitedString(entry, "/");
+            List<String> left = parseDelimitedString(names.get(0), "-");
+
+            String lName = left.get(0);
+            Version lVer;
+            try
+            {
+                lVer = Version.parseVersion(left.get(1));
+            }
+            catch (Exception ex)
+            {
+                // Version doesn't parse. Make it part of the name.
+                lName = names.get(0);
+                lVer = null;
+            }
+
+            String rName = null;
+            Version rVer = null;
+            if (names.size() > 1)
+            {
+                List<String> right = parseDelimitedString(names.get(1), "-");
+                rName = right.get(0);
+                try
+                {
+                    rVer = Version.parseVersion(right.get(1));
+                }
+                catch (Exception ex)
+                {
+                    rName = names.get(1);
+                    rVer = null;
+                }
+            }
+
+            String versionClause;
+            if (lVer != null)
+            {
+                if ((rVer != null) && (!rVer.equals(lVer)))
+                {
+                    // Both versions are defined, but different. Make each of them part of the name
+                    lName = names.get(0);
+                    rName = names.get(1);
+                    versionClause = null;
+                }
+                else
+                {
+                    versionClause = getBreeVersionClause(lVer);
+                }
+            }
+            else
+            {
+                versionClause = getBreeVersionClause(rVer);
+            }
+
+            if ("J2SE".equals(lName))
+            {
+                // J2SE is not used in the Capability variant of BREE, use JavaSE here
+                // This can only happen with the lName part...
+                lName = "JavaSE";
+            }
+
+            String nameClause;
+            if (rName != null)
+                nameClause = "(" + ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE + "=" + lName + "/" + rName + ")";
+            else
+                nameClause = "(" + ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE + "=" + lName + ")";
+
+            String filter;
+            if (versionClause != null)
+                filter = "(&" + nameClause + versionClause + ")";
+            else
+                filter = nameClause;
+
+            filters.add(filter);
+        }
+
+        if (filters.size() == 0)
+        {
+            return Collections.emptyList();
+        }
+        else
+        {
+            String reqFilter;
+            if (filters.size() == 1)
+            {
+                reqFilter = filters.get(0);
+            }
+            else
+            {
+                // If there are more BREE filters, we need to or them together
+                StringBuilder sb = new StringBuilder("(|");
+                for (String f : filters)
+                {
+                    sb.append(f);
+                }
+                sb.append(")");
+                reqFilter = sb.toString();
+            }
+
+            SimpleFilter sf = SimpleFilter.parse(reqFilter);
+            return Collections.<BundleRequirement>singletonList(new BundleRequirementImpl(
+                owner,
+                ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE,
+                Collections.singletonMap(ExecutionEnvironmentNamespace.REQUIREMENT_FILTER_DIRECTIVE, reqFilter),
+                Collections.<String, Object>emptyMap(),
+                sf));
+        }
+    }
+
+    private static String getBreeVersionClause(Version ver) {
+        if (ver == null)
+            return null;
+
+        return "(" + ExecutionEnvironmentNamespace.CAPABILITY_VERSION_ATTRIBUTE + "=" + ver + ")";
+    }
+
     private static List<ParsedHeaderClause> normalizeRequireClauses(
         Logger logger, List<ParsedHeaderClause> clauses, String mv)
     {
@@ -1475,25 +1682,24 @@ public class ManifestParser
 
         if (clauses.size() == 1)
         {
-            // See if there is the "extension" directive.
             for (Entry<String, String> entry : clauses.get(0).m_dirs.entrySet())
             {
                 if (Constants.EXTENSION_DIRECTIVE.equals(entry.getKey()))
                 {
-                    // If the extension directive is specified, make sure
-                    // the target is the system bundle.
-                    if (FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(clauses.get(0).m_paths.get(0)) ||
-                        Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(clauses.get(0).m_paths.get(0)))
-                    {
-                        return entry.getValue();
-                    }
-                    else
-                    {
-                        throw new BundleException(
-                            "Only the system bundle can have extension bundles.");
-                    }
+                    result = entry.getValue();
                 }
             }
+
+            if (FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(clauses.get(0).m_paths.get(0)) ||
+                Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(clauses.get(0).m_paths.get(0)))
+            {
+                result = (result == null) ? Constants.EXTENSION_FRAMEWORK : result;
+            }
+            else if (result != null)
+            {
+                throw new BundleException(
+                    "Only the system bundle can have extension bundles.");
+            }
         }
 
         return result;
@@ -1545,7 +1751,7 @@ public class ManifestParser
                     "A header cannot be an empty string.");
             }
             List<ParsedHeaderClause> clauses = parseStandardHeader(header);
-            
+
             for (ParsedHeaderClause clause : clauses)
             {
                 System.out.println("PATHS " + clause.m_paths);
@@ -1553,33 +1759,33 @@ public class ManifestParser
                 System.out.println("    ATTRS " + clause.m_attrs);
                 System.out.println("    TYPES " + clause.m_types);
             }
-            
+
         }
     }
-    
+
     private static final char EOF = (char) -1;
-    
-    private static char charAt(int pos, String headers, int length) 
+
+    private static char charAt(int pos, String headers, int length)
     {
-        if (pos >= length) 
+        if (pos >= length)
         {
             return EOF;
         }
         return headers.charAt(pos);
     }
-    
+
     private static final int CLAUSE_START = 0;
     private static final int PARAMETER_START = 1;
     private static final int KEY = 2;
     private static final int DIRECTIVE_OR_TYPEDATTRIBUTE = 4;
     private static final int ARGUMENT = 8;
     private static final int VALUE = 16;
-    
+
     @SuppressWarnings({ "unchecked", "rawtypes" })
-    private static List<ParsedHeaderClause> parseStandardHeader(String header) 
+    private static List<ParsedHeaderClause> parseStandardHeader(String header)
     {
         List<ParsedHeaderClause> clauses = new ArrayList<ParsedHeaderClause>();
-        if (header == null) 
+        if (header == null)
         {
             return clauses;
         }
@@ -1592,12 +1798,12 @@ public class ManifestParser
         int length = header.length();
         boolean quoted = false;
         boolean escaped = false;
-        
+
         char currentChar = EOF;
-        do  
+        do
         {
             currentChar = charAt(currentPosition, header, length);
-            switch (state) 
+            switch (state)
             {
                 case CLAUSE_START:
                     clause = new ParsedHeaderClause(
@@ -1611,10 +1817,10 @@ public class ManifestParser
                     startPosition = currentPosition;
                     state = KEY;
                 case KEY:
-                    switch (currentChar) 
+                    switch (currentChar)
                     {
                         case ':':
-                        case '=': 
+                        case '=':
                             key = header.substring(startPosition, currentPosition).trim();
                             startPosition = currentPosition + 1;
                             targetMap = clause.m_attrs;
@@ -1632,14 +1838,14 @@ public class ManifestParser
                     currentPosition++;
                     break;
                 case DIRECTIVE_OR_TYPEDATTRIBUTE:
-                    switch(currentChar) 
+                    switch(currentChar)
                     {
                         case '=':
-                            if (startPosition != currentPosition) 
+                            if (startPosition != currentPosition)
                             {
                                 clause.m_types.put(key, header.substring(startPosition, currentPosition).trim());
                             }
-                            else 
+                            else
                             {
                                 targetMap = clause.m_dirs;
                             }
@@ -1652,12 +1858,12 @@ public class ManifestParser
                     currentPosition++;
                     break;
                 case ARGUMENT:
-                    if (currentChar == '\"') 
+                    if (currentChar == '\"')
                     {
                         quoted = true;
                         currentPosition++;
                     }
-                    else 
+                    else
                     {
                         quoted = false;
                     }
@@ -1669,53 +1875,53 @@ public class ManifestParser
                     }
                     break;
                 case VALUE:
-                    if (currentChar == '\\' ) 
+                    if (escaped)
+                    {
+                        escaped = false;
+                    }
+                    else
                     {
-                        if (escaped) 
+                        if (currentChar == '\\' )
                         {
-                            escaped = false;
+                            escaped = true;
                         }
-                        else 
+                        else if (quoted && currentChar == '\"')
                         {
-                            escaped = true;
+                            quoted = false;
                         }
-                    }
-                    if (quoted && !escaped && currentChar == '\"') 
-                    {
-                        quoted = false;
-                    } 
-                    else if (!quoted)
-                    {
-                        String value = null;
-                        switch(currentChar) 
+                        else if (!quoted)
                         {
-                            case EOF:
-                            case ';':
-                            case ',':
-                                value = header.substring(startPosition, currentPosition).trim();
-                                if (value.startsWith("\"") && value.endsWith("\"")) 
-                                {
-                                    value = value.substring(1, value.length() - 1);
-                                }
-                                if (targetMap.put(key, value) != null) 
-                                {
-                                    throw new IllegalArgumentException(
-                                            "Duplicate '" + key + "' in: " + header);
-                                }
-                                state = currentChar == ';' ? PARAMETER_START : CLAUSE_START;
-                                break;
-                            default:
-                                break;
+                            String value = null;
+                            switch(currentChar)
+                            {
+                                case EOF:
+                                case ';':
+                                case ',':
+                                    value = header.substring(startPosition, currentPosition).trim();
+                                    if (value.startsWith("\"") && value.endsWith("\""))
+                                    {
+                                        value = value.substring(1, value.length() - 1);
+                                    }
+                                    if (targetMap.put(key, value) != null)
+                                    {
+                                        throw new IllegalArgumentException(
+                                                "Duplicate '" + key + "' in: " + header);
+                                    }
+                                    state = currentChar == ';' ? PARAMETER_START : CLAUSE_START;
+                                    break;
+                                default:
+                                    break;
+                            }
                         }
                     }
                     currentPosition++;
                     break;
                 default:
                     break;
-            }   
+            }
         } while ( currentChar != EOF);
-        
-        if (state > PARAMETER_START) 
+
+        if (state > PARAMETER_START)
         {
             throw new IllegalArgumentException("Unable to parse header: " + header);
         }
@@ -1761,7 +1967,7 @@ public class ManifestParser
 
             boolean isDelimiter = (delim.indexOf(c) >= 0);
 
-            if (c == '\\')
+            if (!isEscaped && (c == '\\'))
             {
                 isEscaped = true;
                 continue;
@@ -1847,4 +2053,4 @@ public class ManifestParser
 
         return libList;
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/felix/framework/util/manifestparser/R4Library.java b/src/main/java/org/apache/felix/framework/util/manifestparser/R4Library.java
index 2681342..e82c2a1 100644
--- a/src/main/java/org/apache/felix/framework/util/manifestparser/R4Library.java
+++ b/src/main/java/org/apache/felix/framework/util/manifestparser/R4Library.java
@@ -106,6 +106,10 @@ public class R4Library
         {
             exts.add("dylib");
         }
+        if (libname.endsWith(".dylib") && m_libraryFile.endsWith(".jnilib"))
+        {
+            exts.add("jnilib");
+        }
         // Loop until we find a match or not.
         int extIdx = -1;
         while (!matched && (extIdx < exts.size()))
diff --git a/src/main/java/org/apache/felix/framework/util/manifestparser/R4LibraryClause.java b/src/main/java/org/apache/felix/framework/util/manifestparser/R4LibraryClause.java
index 87c8310..0299041 100644
--- a/src/main/java/org/apache/felix/framework/util/manifestparser/R4LibraryClause.java
+++ b/src/main/java/org/apache/felix/framework/util/manifestparser/R4LibraryClause.java
@@ -134,16 +134,7 @@ public class R4LibraryClause
 
     private boolean checkOSNames(String currentOSName, String[] osnames)
     {
-        boolean win32 = currentOSName.startsWith("win") &&
-            (currentOSName.equals("windows95")
-            || currentOSName.equals("windows98")
-            || currentOSName.equals("windowsnt")
-            || currentOSName.equals("windows2000")
-            || currentOSName.equals("windows2003")
-            || currentOSName.equals("windowsxp")
-            || currentOSName.equals("windowsce")
-            || currentOSName.equals("windowsvista")
-            || currentOSName.equals("windows7"));
+        boolean win32 = currentOSName.startsWith("win") && !currentOSName.equals("windowsce");
 
         for (int i = 0; (osnames != null) && (i < osnames.length); i++)
         {
@@ -378,6 +369,14 @@ public class R4LibraryClause
             {
                 os = "windows2003";
             }
+            else if (value.indexOf("2008") >= 0)
+            {
+                os = "windowsserver2008";
+            }
+            else if (value.indexOf("2012") >= 0)
+            {
+                os = "windowsserver2012";
+            }
             else if (value.indexOf("xp") >= 0)
             {
                 os = "windowsxp";
@@ -390,11 +389,18 @@ public class R4LibraryClause
             {
                 os = "windowsvista";
             }
-            // will need better test here if any future Windows version has a 7 in it!
-            else if (value.indexOf("7") >= 0)
+            else if ((value.indexOf(" 7") >= 0) || value.equals("win7"))
             {
                 os = "windows7";
             }
+            else if ((value.indexOf(" 8") >= 0) || value.equals("win8"))
+            {
+                os = "windows8";
+            }
+            else if ((value.indexOf(" 9") >= 0) || value.equals("win9"))
+            {
+                os = "windows9";
+            }
             return os;
         }
         else if (value.startsWith("linux"))
@@ -460,7 +466,7 @@ public class R4LibraryClause
     {
         value = value.toLowerCase();
 
-        if (value.startsWith("x86-64") || value.startsWith("amd64") || 
+        if (value.startsWith("x86-64") || value.startsWith("amd64") ||
             value.startsWith("em64") || value.startsWith("x86_64"))
         {
             return "x86-64";
@@ -520,4 +526,4 @@ public class R4LibraryClause
             return Version.emptyVersion.toString();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/felix/framework/wiring/BundleCapabilityImpl.java b/src/main/java/org/apache/felix/framework/wiring/BundleCapabilityImpl.java
index ba36535..0128568 100644
--- a/src/main/java/org/apache/felix/framework/wiring/BundleCapabilityImpl.java
+++ b/src/main/java/org/apache/felix/framework/wiring/BundleCapabilityImpl.java
@@ -19,18 +19,20 @@
 package org.apache.felix.framework.wiring;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.Collections;
-import java.util.Set;
-import java.util.Map;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.StringTokenizer;
 import org.apache.felix.framework.capabilityset.SimpleFilter;
+import org.apache.felix.framework.util.ImmutableMap;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.manifestparser.ManifestParser;
 import org.osgi.framework.Constants;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.resource.Resource;
 
 public class BundleCapabilityImpl implements BundleCapability
 {
@@ -50,8 +52,8 @@ public class BundleCapabilityImpl implements BundleCapability
     {
         m_namespace = namespace;
         m_revision = revision;
-        m_dirs = Collections.unmodifiableMap(dirs);
-        m_attrs = Collections.unmodifiableMap(attrs);
+        m_dirs = ImmutableMap.newInstance(dirs);
+        m_attrs = ImmutableMap.newInstance(attrs);
 
         // Find all export directives: uses, mandatory, include, and exclude.
 
@@ -125,6 +127,11 @@ public class BundleCapabilityImpl implements BundleCapability
         m_mandatory = mandatory;
     }
 
+    public BundleRevision getResource()
+    {
+        return m_revision;
+    }
+
     public BundleRevision getRevision()
     {
         return m_revision;
@@ -187,6 +194,7 @@ public class BundleCapabilityImpl implements BundleCapability
         return included && !excluded;
     }
 
+    @Override
     public String toString()
     {
         if (m_revision == null)
diff --git a/src/main/java/org/apache/felix/framework/wiring/BundleRequirementImpl.java b/src/main/java/org/apache/felix/framework/wiring/BundleRequirementImpl.java
index eabd5bc..398272e 100644
--- a/src/main/java/org/apache/felix/framework/wiring/BundleRequirementImpl.java
+++ b/src/main/java/org/apache/felix/framework/wiring/BundleRequirementImpl.java
@@ -18,18 +18,16 @@
  */
 package org.apache.felix.framework.wiring;
 
-import java.util.ArrayList;
 import java.util.Collections;
-import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import org.apache.felix.framework.capabilityset.CapabilitySet;
 import org.apache.felix.framework.capabilityset.SimpleFilter;
-import org.apache.felix.framework.util.VersionRange;
+import org.apache.felix.framework.util.ImmutableMap;
 import org.osgi.framework.Constants;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.resource.Resource;
 
 public class BundleRequirementImpl implements BundleRequirement
 {
@@ -46,8 +44,8 @@ public class BundleRequirementImpl implements BundleRequirement
     {
         m_revision = revision;
         m_namespace = namespace;
-        m_dirs = Collections.unmodifiableMap(dirs);
-        m_attrs = Collections.unmodifiableMap(attrs);
+        m_dirs = ImmutableMap.newInstance(dirs);
+        m_attrs = ImmutableMap.newInstance(attrs);
         m_filter = filter;
 
         // Find resolution import directives.
@@ -82,6 +80,11 @@ public class BundleRequirementImpl implements BundleRequirement
         return m_attrs;
     }
 
+    public BundleRevision getResource()
+    {
+        return m_revision;
+    }
+
     public BundleRevision getRevision()
     {
         return m_revision;
@@ -102,6 +105,7 @@ public class BundleRequirementImpl implements BundleRequirement
         return m_filter;
     }
 
+    @Override
     public String toString()
     {
         return "[" + m_revision + "] " + m_namespace + "; " + getFilter().toString();
diff --git a/src/main/java/org/osgi/framework/AdaptPermission.java b/src/main/java/org/osgi/framework/AdaptPermission.java
index f95c1fe..fbe70c1 100644
--- a/src/main/java/org/osgi/framework/AdaptPermission.java
+++ b/src/main/java/org/osgi/framework/AdaptPermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.osgi.framework;
 
 import java.io.IOException;
@@ -40,9 +41,9 @@ import java.util.Map;
  * {@code AdaptPermission} has one action: {@code adapt}.
  * 
  * @ThreadSafe
- * @version $Id: bc4c5d392d2534a7744f6fc00f4665502f82033c $
+ * @version $Id: 3bc095bd294db2d8ea25971a3d71991de1495b1a $
  */
-public class AdaptPermission extends BasicPermission {
+public final class AdaptPermission extends BasicPermission {
 
 	private static final long						serialVersionUID	= 1L;
 
@@ -137,8 +138,7 @@ public class AdaptPermission extends BasicPermission {
 	 *        adapted.
 	 * @param actions {@code adapt}.
 	 */
-	public AdaptPermission(String adaptClass, Bundle adaptableBundle,
-			String actions) {
+	public AdaptPermission(String adaptClass, Bundle adaptableBundle, String actions) {
 		super(adaptClass);
 		setTransients(null, parseActions(actions));
 		this.bundle = adaptableBundle;
@@ -201,9 +201,7 @@ public class AdaptPermission extends BasicPermission {
 			char c;
 
 			// skip whitespace
-			while ((i != -1)
-					&& ((c = a[i]) == ' ' || c == '\r' || c == '\n'
-							|| c == '\f' || c == '\t'))
+			while ((i != -1) && ((c = a[i]) == ' ' || c == '\r' || c == '\n' || c == '\f' || c == '\t'))
 				i--;
 
 			// check for the known strings
@@ -217,11 +215,9 @@ public class AdaptPermission extends BasicPermission {
 				matchlen = 5;
 				mask |= ACTION_ADAPT;
 
-			}
-			else {
+			} else {
 				// parse error
-				throw new IllegalArgumentException("invalid actions: "
-						+ actions);
+				throw new IllegalArgumentException("invalid actions: " + actions);
 			}
 
 			// make sure we didn't just match the tail of a word
@@ -239,8 +235,7 @@ public class AdaptPermission extends BasicPermission {
 					case '\t' :
 						break;
 					default :
-						throw new IllegalArgumentException(
-								"invalid permission: " + actions);
+						throw new IllegalArgumentException("invalid permission: " + actions);
 				}
 				i--;
 			}
@@ -270,10 +265,8 @@ public class AdaptPermission extends BasicPermission {
 		}
 		try {
 			return FrameworkUtil.createFilter(filterString);
-		}
-		catch (InvalidSyntaxException e) {
-			IllegalArgumentException iae = new IllegalArgumentException(
-					"invalid filter");
+		} catch (InvalidSyntaxException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid filter");
 			iae.initCause(e);
 			throw iae;
 		}
@@ -387,10 +380,7 @@ public class AdaptPermission extends BasicPermission {
 
 		AdaptPermission cp = (AdaptPermission) obj;
 
-		return (action_mask == cp.action_mask)
-				&& getName().equals(cp.getName())
-				&& ((bundle == cp.bundle) || ((bundle != null) && bundle
-						.equals(cp.bundle)));
+		return (action_mask == cp.action_mask) && getName().equals(cp.getName()) && ((bundle == cp.bundle) || ((bundle != null) && bundle.equals(cp.bundle)));
 	}
 
 	/**
@@ -412,8 +402,7 @@ public class AdaptPermission extends BasicPermission {
 	 * stream. The actions are serialized, and the superclass takes care of the
 	 * name.
 	 */
-	private synchronized void writeObject(java.io.ObjectOutputStream s)
-			throws IOException {
+	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
 		if (bundle != null) {
 			throw new NotSerializableException("cannot serialize");
 		}
@@ -428,8 +417,7 @@ public class AdaptPermission extends BasicPermission {
 	 * readObject is called to restore the state of this permission from a
 	 * stream.
 	 */
-	private synchronized void readObject(java.io.ObjectInputStream s)
-			throws IOException, ClassNotFoundException {
+	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
 		// Read in the action, then initialize the rest
 		s.defaultReadObject();
 		setTransients(parseFilter(getName()), parseActions(actions));
@@ -516,18 +504,15 @@ final class AdaptPermissionCollection extends PermissionCollection {
 	 */
 	public void add(final Permission permission) {
 		if (!(permission instanceof AdaptPermission)) {
-			throw new IllegalArgumentException("invalid permission: "
-					+ permission);
+			throw new IllegalArgumentException("invalid permission: " + permission);
 		}
 		if (isReadOnly()) {
-			throw new SecurityException("attempt to add a Permission to a "
-					+ "readonly PermissionCollection");
+			throw new SecurityException("attempt to add a Permission to a " + "readonly PermissionCollection");
 		}
 
 		final AdaptPermission ap = (AdaptPermission) permission;
 		if (ap.bundle != null) {
-			throw new IllegalArgumentException("cannot add to collection: "
-					+ ap);
+			throw new IllegalArgumentException("cannot add to collection: " + ap);
 		}
 
 		final String name = ap.getName();
@@ -538,12 +523,10 @@ final class AdaptPermissionCollection extends PermissionCollection {
 				final int oldMask = existing.action_mask;
 				final int newMask = ap.action_mask;
 				if (oldMask != newMask) {
-					pc.put(name, new AdaptPermission(existing.filter, oldMask
-							| newMask));
+					pc.put(name, new AdaptPermission(existing.filter, oldMask | newMask));
 
 				}
-			}
-			else {
+			} else {
 				pc.put(name, ap);
 			}
 
@@ -613,23 +596,18 @@ final class AdaptPermissionCollection extends PermissionCollection {
 	}
 
 	/* serialization logic */
-	private static final ObjectStreamField[]	serialPersistentFields	= {
-			new ObjectStreamField("permissions", HashMap.class),
-			new ObjectStreamField("all_allowed", Boolean.TYPE)			};
+	private static final ObjectStreamField[]	serialPersistentFields	= {new ObjectStreamField("permissions", HashMap.class), new ObjectStreamField("all_allowed", Boolean.TYPE)};
 
-	private synchronized void writeObject(ObjectOutputStream out)
-			throws IOException {
+	private synchronized void writeObject(ObjectOutputStream out) throws IOException {
 		ObjectOutputStream.PutField pfields = out.putFields();
 		pfields.put("permissions", permissions);
 		pfields.put("all_allowed", all_allowed);
 		out.writeFields();
 	}
 
-	private synchronized void readObject(java.io.ObjectInputStream in)
-			throws IOException, ClassNotFoundException {
+	private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
 		ObjectInputStream.GetField gfields = in.readFields();
-		permissions = (HashMap<String, AdaptPermission>) gfields.get(
-				"permissions", null);
+		permissions = (HashMap<String, AdaptPermission>) gfields.get("permissions", null);
 		all_allowed = gfields.get("all_allowed", false);
 	}
 }
diff --git a/src/main/java/org/osgi/framework/AdminPermission.java b/src/main/java/org/osgi/framework/AdminPermission.java
index fc7b1f4..324360c 100644
--- a/src/main/java/org/osgi/framework/AdminPermission.java
+++ b/src/main/java/org/osgi/framework/AdminPermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -41,34 +41,34 @@ import java.util.Map;
  * permission are:
  * 
  * <pre>
- *  Action               Methods
- *  class                Bundle.loadClass
- *  execute              Bundle.start
- *                       Bundle.stop
- *                       BundleStartLevel.setStartLevel
- *  extensionLifecycle   BundleContext.installBundle for extension bundles
- *                       Bundle.update for extension bundles
- *                       Bundle.uninstall for extension bundles
- *  lifecycle            BundleContext.installBundle
- *                       Bundle.update
- *                       Bundle.uninstall
- *  listener             BundleContext.addBundleListener for SynchronousBundleListener
- *                       BundleContext.removeBundleListener for SynchronousBundleListener
- *  metadata             Bundle.getHeaders
- *                       Bundle.getLocation
- *  resolve              FrameworkWiring.refreshBundles
- *                       FrameworkWiring.resolveBundles
- *  resource             Bundle.getResource
- *                       Bundle.getResources
- *                       Bundle.getEntry
- *                       Bundle.getEntryPaths
- *                       Bundle.findEntries
- *                       Bundle resource/entry URL creation
- *  startlevel           FrameworkStartLevel.setStartLevel
- *                       FrameworkStartLevel.setInitialBundleStartLevel 
- *  context              Bundle.getBundleContext
- *  weave                WovenClass.setBytes
- *                       WovenClass.getDynamicImports for modification
+ * Action             Methods
+ * class              Bundle.loadClass
+ * execute            Bundle.start
+ *                    Bundle.stop
+ *                    BundleStartLevel.setStartLevel
+ * extensionLifecycle BundleContext.installBundle for extension bundles
+ *                    Bundle.update for extension bundles
+ *                    Bundle.uninstall for extension bundles
+ * lifecycle          BundleContext.installBundle
+ *                    Bundle.update
+ *                    Bundle.uninstall
+ * listener           BundleContext.addBundleListener for SynchronousBundleListener
+ *                    BundleContext.removeBundleListener for SynchronousBundleListener
+ * metadata           Bundle.getHeaders
+ *                    Bundle.getLocation
+ * resolve            FrameworkWiring.refreshBundles
+ *                    FrameworkWiring.resolveBundles
+ * resource           Bundle.getResource
+ *                    Bundle.getResources
+ *                    Bundle.getEntry
+ *                    Bundle.getEntryPaths
+ *                    Bundle.findEntries
+ *                    Bundle resource/entry URL creation
+ * startlevel         FrameworkStartLevel.setStartLevel
+ *                    FrameworkStartLevel.setInitialBundleStartLevel
+ * context            Bundle.getBundleContext
+ * weave              WovenClass.setBytes
+ *                    WovenClass.getDynamicImports for modification
  * </pre>
  * 
  * <p>
@@ -89,78 +89,77 @@ import java.util.Map;
  * Filter attribute names are processed in a case sensitive manner.
  * 
  * @ThreadSafe
- * @version $Id: 43baf9a6d7ce5e6108507834e841e340fd91c513 $
+ * @version $Id: cd883e81fde210ce8f0cabaebea377378d672818 $
  */
 
 public final class AdminPermission extends BasicPermission {
-	static final long						serialVersionUID			= 307051004521261705L;
+	static final long								serialVersionUID			= 307051004521261705L;
 
 	/**
-	 * The action string {@code class}. The {@code class} action
-	 * implies the {@code resolve} action.
+	 * The action string {@code class}. The {@code class} action implies the
+	 * {@code resolve} action.
 	 * 
 	 * @since 1.3
 	 */
-	public final static String	CLASS						= "class";
+	public final static String						CLASS						= "class";
 	/**
-	 * The action string {@code execute}. The {@code execute} action
-	 * implies the {@code resolve} action.
+	 * The action string {@code execute}. The {@code execute} action implies the
+	 * {@code resolve} action.
 	 * 
 	 * @since 1.3
 	 */
-	public final static String	EXECUTE						= "execute";
+	public final static String						EXECUTE						= "execute";
 	/**
 	 * The action string {@code extensionLifecycle}.
 	 * 
 	 * @since 1.3
 	 */
-	public final static String	EXTENSIONLIFECYCLE			= "extensionLifecycle";
+	public final static String						EXTENSIONLIFECYCLE			= "extensionLifecycle";
 	/**
 	 * The action string {@code lifecycle}.
 	 * 
 	 * @since 1.3
 	 */
-	public final static String	LIFECYCLE					= "lifecycle";
+	public final static String						LIFECYCLE					= "lifecycle";
 	/**
 	 * The action string {@code listener}.
 	 * 
 	 * @since 1.3
 	 */
-	public final static String	LISTENER					= "listener";
+	public final static String						LISTENER					= "listener";
 	/**
 	 * The action string {@code metadata}.
 	 * 
 	 * @since 1.3
 	 */
-	public final static String	METADATA					= "metadata";
+	public final static String						METADATA					= "metadata";
 	/**
-	 * The action string {@code resolve}. The {@code resolve} action
-	 * is implied by the {@code class}, {@code execute} and
-	 * {@code resource} actions.
+	 * The action string {@code resolve}. The {@code resolve} action is implied
+	 * by the {@code class}, {@code execute} and {@code resource} actions.
 	 * 
 	 * @since 1.3
 	 */
-	public final static String	RESOLVE						= "resolve";
+	public final static String						RESOLVE						= "resolve";
 	/**
-	 * The action string {@code resource}. The {@code resource} action
-	 * implies the {@code resolve} action.
+	 * The action string {@code resource}. The {@code resource} action implies
+	 * the {@code resolve} action.
 	 * 
 	 * @since 1.3
 	 */
-	public final static String	RESOURCE					= "resource";
+	public final static String						RESOURCE					= "resource";
 	/**
 	 * The action string {@code startlevel}.
 	 * 
 	 * @since 1.3
 	 */
-	public final static String	STARTLEVEL					= "startlevel";
+	public final static String						STARTLEVEL					= "startlevel";
 
 	/**
 	 * The action string {@code context}.
 	 * 
 	 * @since 1.4
 	 */
-	public final static String	CONTEXT						= "context";
+	public final static String						CONTEXT						= "context";
 
 	/**
 	 * The action string {@code weave}.
@@ -169,52 +168,43 @@ public final class AdminPermission extends BasicPermission {
 	 */
 	public final static String						WEAVE						= "weave";
 
-	private final static int	ACTION_CLASS				= 0x00000001;
-	private final static int	ACTION_EXECUTE				= 0x00000002;
-	private final static int	ACTION_LIFECYCLE			= 0x00000004;
-	private final static int	ACTION_LISTENER				= 0x00000008;
-	private final static int	ACTION_METADATA				= 0x00000010;
-	private final static int	ACTION_RESOLVE				= 0x00000040;
-	private final static int	ACTION_RESOURCE				= 0x00000080;
-	private final static int	ACTION_STARTLEVEL			= 0x00000100;
-	private final static int	ACTION_EXTENSIONLIFECYCLE	= 0x00000200;
-	private final static int	ACTION_CONTEXT				= 0x00000400;
+	private final static int						ACTION_CLASS				= 0x00000001;
+	private final static int						ACTION_EXECUTE				= 0x00000002;
+	private final static int						ACTION_LIFECYCLE			= 0x00000004;
+	private final static int						ACTION_LISTENER				= 0x00000008;
+	private final static int						ACTION_METADATA				= 0x00000010;
+	private final static int						ACTION_RESOLVE				= 0x00000040;
+	private final static int						ACTION_RESOURCE				= 0x00000080;
+	private final static int						ACTION_STARTLEVEL			= 0x00000100;
+	private final static int						ACTION_EXTENSIONLIFECYCLE	= 0x00000200;
+	private final static int						ACTION_CONTEXT				= 0x00000400;
 	private final static int						ACTION_WEAVE				= 0x00000800;
-	private final static int	ACTION_ALL					= ACTION_CLASS
-																	| ACTION_EXECUTE
-																	| ACTION_LIFECYCLE
-																	| ACTION_LISTENER
-																	| ACTION_METADATA
-																	| ACTION_RESOLVE
-																	| ACTION_RESOURCE
-																	| ACTION_STARTLEVEL
-																	| ACTION_EXTENSIONLIFECYCLE
-																						| ACTION_CONTEXT
-																						| ACTION_WEAVE;
-	final static int						ACTION_NONE					= 0;
+	private final static int						ACTION_ALL					= ACTION_CLASS | ACTION_EXECUTE | ACTION_LIFECYCLE | ACTION_LISTENER | ACTION_METADATA | ACTION_RESOLVE
+																						| ACTION_RESOURCE | ACTION_STARTLEVEL | ACTION_EXTENSIONLIFECYCLE | ACTION_CONTEXT | ACTION_WEAVE;
+	final static int								ACTION_NONE					= 0;
 
 	/**
 	 * The actions in canonical form.
 	 * 
 	 * @serial
 	 */
-	private volatile String		actions						= null;
+	private volatile String							actions						= null;
 
 	/**
 	 * The actions mask.
 	 */
-	transient int							action_mask;
+	transient int									action_mask;
 
 	/**
 	 * If this AdminPermission was constructed with a filter, this holds a
 	 * Filter matching object used to evaluate the filter in implies.
 	 */
-	transient Filter						filter;
+	transient Filter								filter;
 
 	/**
 	 * The bundle governed by this AdminPermission - only used if filter == null
 	 */
-	transient final Bundle					bundle;
+	transient final Bundle							bundle;
 
 	/**
 	 * This map holds the properties of the permission, used to match a filter
@@ -227,14 +217,14 @@ public final class AdminPermission extends BasicPermission {
 	 * ThreadLocal used to determine if we have recursively called
 	 * getProperties.
 	 */
-	private static final ThreadLocal<Bundle>	recurse						= new ThreadLocal<Bundle>();
+	private static final ThreadLocal<Bundle>		recurse						= new ThreadLocal<Bundle>();
 
 	/**
-	 * Creates a new {@code AdminPermission} object that matches all
-	 * bundles and has all actions. Equivalent to AdminPermission("*","*");
+	 * Creates a new {@code AdminPermission} object that matches all bundles and
+	 * has all actions. Equivalent to AdminPermission("*","*");
 	 */
 	public AdminPermission() {
-		this(null, ACTION_ALL); 
+		this(null, ACTION_ALL);
 	}
 
 	/**
@@ -346,29 +336,27 @@ public final class AdminPermission extends BasicPermission {
 		if ((actions == null) || actions.equals("*")) {
 			return ACTION_ALL;
 		}
-	
+
 		boolean seencomma = false;
-	
+
 		int mask = ACTION_NONE;
 
 		char[] a = actions.toCharArray();
-	
+
 		int i = a.length - 1;
 		if (i < 0)
 			return mask;
-	
+
 		while (i != -1) {
 			char c;
-	
+
 			// skip whitespace
-			while ((i != -1)
-					&& ((c = a[i]) == ' ' || c == '\r' || c == '\n'
-							|| c == '\f' || c == '\t'))
+			while ((i != -1) && ((c = a[i]) == ' ' || c == '\r' || c == '\n' || c == '\f' || c == '\t'))
 				i--;
-	
+
 			// check for the known strings
 			int matchlen;
-	
+
 			if (i >= 4 && (a[i - 4] == 'c' || a[i - 4] == 'C')
 					&& (a[i - 3] == 'l' || a[i - 3] == 'L')
 					&& (a[i - 2] == 'a' || a[i - 2] == 'A')
@@ -376,9 +364,8 @@ public final class AdminPermission extends BasicPermission {
 					&& (a[i] == 's' || a[i] == 'S')) {
 				matchlen = 5;
 				mask |= ACTION_CLASS | ACTION_RESOLVE;
-	
-			}
-			else
+
+			} else
 				if (i >= 6 && (a[i - 6] == 'e' || a[i - 6] == 'E')
 						&& (a[i - 5] == 'x' || a[i - 5] == 'X')
 						&& (a[i - 4] == 'e' || a[i - 4] == 'E')
@@ -388,9 +375,8 @@ public final class AdminPermission extends BasicPermission {
 						&& (a[i] == 'e' || a[i] == 'E')) {
 					matchlen = 7;
 					mask |= ACTION_EXECUTE | ACTION_RESOLVE;
-	
-				}
-				else
+
+				} else
 					if (i >= 17 && (a[i - 17] == 'e' || a[i - 17] == 'E')
 							&& (a[i - 16] == 'x' || a[i - 16] == 'X')
 							&& (a[i - 15] == 't' || a[i - 15] == 'T')
@@ -411,9 +397,8 @@ public final class AdminPermission extends BasicPermission {
 							&& (a[i] == 'e' || a[i] == 'E')) {
 						matchlen = 18;
 						mask |= ACTION_EXTENSIONLIFECYCLE;
-	
-					}
-					else
+
+					} else
 						if (i >= 8 && (a[i - 8] == 'l' || a[i - 8] == 'L')
 								&& (a[i - 7] == 'i' || a[i - 7] == 'I')
 								&& (a[i - 6] == 'f' || a[i - 6] == 'F')
@@ -425,9 +410,8 @@ public final class AdminPermission extends BasicPermission {
 								&& (a[i] == 'e' || a[i] == 'E')) {
 							matchlen = 9;
 							mask |= ACTION_LIFECYCLE;
-	
-						}
-						else
+
+						} else
 							if (i >= 7 && (a[i - 7] == 'l' || a[i - 7] == 'L')
 									&& (a[i - 6] == 'i' || a[i - 6] == 'I')
 									&& (a[i - 5] == 's' || a[i - 5] == 'S')
@@ -438,9 +422,8 @@ public final class AdminPermission extends BasicPermission {
 									&& (a[i] == 'r' || a[i] == 'R')) {
 								matchlen = 8;
 								mask |= ACTION_LISTENER;
-	
-							}
-							else
+
+							} else
 								if (i >= 7
 										&& (a[i - 7] == 'm' || a[i - 7] == 'M')
 										&& (a[i - 6] == 'e' || a[i - 6] == 'E')
@@ -452,9 +435,8 @@ public final class AdminPermission extends BasicPermission {
 										&& (a[i] == 'a' || a[i] == 'A')) {
 									matchlen = 8;
 									mask |= ACTION_METADATA;
-	
-								}
-								else
+
+								} else
 									if (i >= 6
 											&& (a[i - 6] == 'r' || a[i - 6] == 'R')
 											&& (a[i - 5] == 'e' || a[i - 5] == 'E')
@@ -465,9 +447,8 @@ public final class AdminPermission extends BasicPermission {
 											&& (a[i] == 'e' || a[i] == 'E')) {
 										matchlen = 7;
 										mask |= ACTION_RESOLVE;
-	
-									}
-									else
+
+									} else
 										if (i >= 7
 												&& (a[i - 7] == 'r' || a[i - 7] == 'R')
 												&& (a[i - 6] == 'e' || a[i - 6] == 'E')
@@ -480,9 +461,8 @@ public final class AdminPermission extends BasicPermission {
 											matchlen = 8;
 											mask |= ACTION_RESOURCE
 													| ACTION_RESOLVE;
-	
-										}
-										else
+
+										} else
 											if (i >= 9
 													&& (a[i - 9] == 's' || a[i - 9] == 'S')
 													&& (a[i - 8] == 't' || a[i - 8] == 'T')
@@ -496,9 +476,8 @@ public final class AdminPermission extends BasicPermission {
 													&& (a[i] == 'l' || a[i] == 'L')) {
 												matchlen = 10;
 												mask |= ACTION_STARTLEVEL;
-	
-											}
-											else
+
+											} else
 												if (i >= 6
 														&& (a[i - 6] == 'c' || a[i - 6] == 'C')
 														&& (a[i - 5] == 'o' || a[i - 5] == 'O')
@@ -509,9 +488,8 @@ public final class AdminPermission extends BasicPermission {
 														&& (a[i] == 't' || a[i] == 'T')) {
 													matchlen = 7;
 													mask |= ACTION_CONTEXT;
-	
-												}
-												else
+
+												} else
 													if (i >= 4
 															&& (a[i - 4] == 'w' || a[i - 4] == 'W')
 															&& (a[i - 3] == 'e' || a[i - 3] == 'E')
@@ -521,21 +499,16 @@ public final class AdminPermission extends BasicPermission {
 														matchlen = 5;
 														mask |= ACTION_WEAVE;
 
-													}
-													else
-														if (i >= 0
-																&& (a[i] == '*')) {
+													} else
+														if (i >= 0 && (a[i] == '*')) {
 															matchlen = 1;
 															mask |= ACTION_ALL;
 
-														}
-														else {
+														} else {
 															// parse error
-															throw new IllegalArgumentException(
-																	"invalid permission: "
-																			+ actions);
+															throw new IllegalArgumentException("invalid permission: " + actions);
 														}
-	
+
 			// make sure we didn't just match the tail of a word
 			// like "ackbarfstartlevel". Also, skip to the comma.
 			seencomma = false;
@@ -551,21 +524,19 @@ public final class AdminPermission extends BasicPermission {
 					case '\t' :
 						break;
 					default :
-						throw new IllegalArgumentException(
-								"invalid permission: " + actions); 
+						throw new IllegalArgumentException("invalid permission: " + actions);
 				}
 				i--;
 			}
-	
+
 			// point i at the location of the comma minus one (or -1).
 			i -= matchlen;
 		}
-	
+
 		if (seencomma) {
-			throw new IllegalArgumentException("invalid permission: " + 
-					actions);
+			throw new IllegalArgumentException("invalid permission: " + actions);
 		}
-	
+
 		return mask;
 	}
 
@@ -574,8 +545,8 @@ public final class AdminPermission extends BasicPermission {
 	 * 
 	 * @param filterString The filter string to parse.
 	 * @return a Filter for this bundle. If the specified filterString is
-	 *         {@code null} or equals "*", then {@code null} is
-	 *         returned to indicate a wildcard.
+	 *         {@code null} or equals "*", then {@code null} is returned to
+	 *         indicate a wildcard.
 	 * @throws IllegalArgumentException If the filter syntax is invalid.
 	 */
 	private static Filter parseFilter(String filterString) {
@@ -586,13 +557,11 @@ public final class AdminPermission extends BasicPermission {
 		if (filterString.equals("*")) {
 			return null;
 		}
-		
+
 		try {
 			return FrameworkUtil.createFilter(filterString);
-		}
-		catch (InvalidSyntaxException e) {
-			IllegalArgumentException iae = new IllegalArgumentException(
-					"invalid filter");
+		} catch (InvalidSyntaxException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid filter");
 			iae.initCause(e);
 			throw iae;
 		}
@@ -616,9 +585,9 @@ public final class AdminPermission extends BasicPermission {
 	 * actions.
 	 * <p>
 	 * Special case: if the specified permission was constructed with "*"
-	 * filter, then this method returns {@code true} if this object's
-	 * filter is "*" and this object's actions include all of the specified
-	 * permission's actions
+	 * filter, then this method returns {@code true} if this object's filter is
+	 * "*" and this object's actions include all of the specified permission's
+	 * actions
 	 * 
 	 * @param p The requested permission.
 	 * @return {@code true} if the specified permission is implied by this
@@ -657,7 +626,7 @@ public final class AdminPermission extends BasicPermission {
 		if ((effective & desired) != desired) {
 			return false;
 		}
-	
+
 		/* Get our filter */
 		Filter f = filter;
 		if (f == null) {
@@ -668,8 +637,7 @@ public final class AdminPermission extends BasicPermission {
 		if (requested.bundle == null) {
 			return false;
 		}
-		Map<String, Object> requestedProperties = requested
-				.getProperties();
+		Map<String, Object> requestedProperties = requested.getProperties();
 		if (requestedProperties == null) {
 			/*
 			 * If the requested properties are null, then we have detected a
@@ -699,53 +667,53 @@ public final class AdminPermission extends BasicPermission {
 		String result = actions;
 		if (result == null) {
 			StringBuffer sb = new StringBuffer();
-	
+
 			int mask = action_mask;
 			if ((mask & ACTION_CLASS) == ACTION_CLASS) {
 				sb.append(CLASS);
 				sb.append(',');
 			}
-	
+
 			if ((mask & ACTION_EXECUTE) == ACTION_EXECUTE) {
 				sb.append(EXECUTE);
 				sb.append(',');
 			}
-	
+
 			if ((mask & ACTION_EXTENSIONLIFECYCLE) == ACTION_EXTENSIONLIFECYCLE) {
 				sb.append(EXTENSIONLIFECYCLE);
 				sb.append(',');
 			}
-	
+
 			if ((mask & ACTION_LIFECYCLE) == ACTION_LIFECYCLE) {
 				sb.append(LIFECYCLE);
 				sb.append(',');
 			}
-	
+
 			if ((mask & ACTION_LISTENER) == ACTION_LISTENER) {
 				sb.append(LISTENER);
 				sb.append(',');
 			}
-	
+
 			if ((mask & ACTION_METADATA) == ACTION_METADATA) {
 				sb.append(METADATA);
 				sb.append(',');
 			}
-	
+
 			if ((mask & ACTION_RESOLVE) == ACTION_RESOLVE) {
 				sb.append(RESOLVE);
 				sb.append(',');
 			}
-	
+
 			if ((mask & ACTION_RESOURCE) == ACTION_RESOURCE) {
 				sb.append(RESOURCE);
 				sb.append(',');
 			}
-	
+
 			if ((mask & ACTION_STARTLEVEL) == ACTION_STARTLEVEL) {
 				sb.append(STARTLEVEL);
 				sb.append(',');
 			}
-	
+
 			if ((mask & ACTION_CONTEXT) == ACTION_CONTEXT) {
 				sb.append(CONTEXT);
 				sb.append(',');
@@ -755,20 +723,20 @@ public final class AdminPermission extends BasicPermission {
 				sb.append(WEAVE);
 				sb.append(',');
 			}
-	
+
 			// remove trailing comma
 			if (sb.length() > 0) {
 				sb.setLength(sb.length() - 1);
 			}
-	
+
 			actions = result = sb.toString();
 		}
 		return result;
 	}
 
 	/**
-	 * Returns a new {@code PermissionCollection} object suitable for
-	 * storing {@code AdminPermission}s.
+	 * Returns a new {@code PermissionCollection} object suitable for storing
+	 * {@code AdminPermission}s.
 	 * 
 	 * @return A new {@code PermissionCollection} object.
 	 */
@@ -794,11 +762,7 @@ public final class AdminPermission extends BasicPermission {
 
 		AdminPermission ap = (AdminPermission) obj;
 
-		return (action_mask == ap.action_mask)
-				&& ((bundle == ap.bundle) || ((bundle != null) && bundle
-						.equals(ap.bundle)))
-				&& (filter == null ? ap.filter == null : filter
-						.equals(ap.filter));
+		return (action_mask == ap.action_mask) && ((bundle == ap.bundle) || ((bundle != null) && bundle.equals(ap.bundle))) && (filter == null ? ap.filter == null : filter.equals(ap.filter));
 	}
 
 	/**
@@ -820,8 +784,7 @@ public final class AdminPermission extends BasicPermission {
 	 * stream. The actions are serialized, and the superclass takes care of the
 	 * name.
 	 */
-	private synchronized void writeObject(java.io.ObjectOutputStream s)
-			throws IOException {
+	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
 		if (bundle != null) {
 			throw new NotSerializableException("cannot serialize");
 		}
@@ -836,8 +799,7 @@ public final class AdminPermission extends BasicPermission {
 	 * readObject is called to restore the state of this permission from a
 	 * stream.
 	 */
-	private synchronized void readObject(java.io.ObjectInputStream s)
-			throws IOException, ClassNotFoundException {
+	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
 		// Read in the data, then initialize the transients
 		s.defaultReadObject();
 		setTransients(parseFilter(getName()), parseActions(actions));
@@ -870,8 +832,7 @@ public final class AdminPermission extends BasicPermission {
 		}
 		recurse.set(bundle);
 		try {
-			final Map<String, Object> map = new HashMap<String, Object>(
-					4);
+			final Map<String, Object> map = new HashMap<String, Object>(4);
 			AccessController.doPrivileged(new PrivilegedAction<Object>() {
 				public Object run() {
 					map.put("id", new Long(bundle.getBundleId()));
@@ -888,8 +849,7 @@ public final class AdminPermission extends BasicPermission {
 				}
 			});
 			return properties = map;
-		}
-		finally {
+		} finally {
 			recurse.set(null);
 		}
 	}
@@ -899,7 +859,7 @@ public final class AdminPermission extends BasicPermission {
  * Stores a collection of {@code AdminPermission}s.
  */
 final class AdminPermissionCollection extends PermissionCollection {
-	private static final long	serialVersionUID	= 3906372644575328048L;
+	private static final long						serialVersionUID	= 3906372644575328048L;
 	/**
 	 * Collection of permissions.
 	 * 
@@ -913,7 +873,7 @@ final class AdminPermissionCollection extends PermissionCollection {
 	 * @serial
 	 * @GuardedBy this
 	 */
-	private boolean				all_allowed;
+	private boolean									all_allowed;
 
 	/**
 	 * Create an empty AdminPermissions object.
@@ -928,24 +888,21 @@ final class AdminPermissionCollection extends PermissionCollection {
 	 * 
 	 * @param permission The {@code AdminPermission} object to add.
 	 * @throws IllegalArgumentException If the specified permission is not an
-	 *         {@code AdminPermission} instance or was constructed with a
-	 *         Bundle object.
+	 *         {@code AdminPermission} instance or was constructed with a Bundle
+	 *         object.
 	 * @throws SecurityException If this {@code AdminPermissionCollection}
 	 *         object has been marked read-only.
 	 */
 	public void add(Permission permission) {
 		if (!(permission instanceof AdminPermission)) {
-			throw new IllegalArgumentException("invalid permission: "
-					+ permission);
+			throw new IllegalArgumentException("invalid permission: " + permission);
 		}
 		if (isReadOnly()) {
-			throw new SecurityException("attempt to add a Permission to a "
-					+ "readonly PermissionCollection"); 
+			throw new SecurityException("attempt to add a Permission to a " + "readonly PermissionCollection");
 		}
 		final AdminPermission ap = (AdminPermission) permission;
 		if (ap.bundle != null) {
-			throw new IllegalArgumentException("cannot add to collection: "
-					+ ap);
+			throw new IllegalArgumentException("cannot add to collection: " + ap);
 		}
 		final String name = ap.getName();
 		synchronized (this) {
@@ -956,11 +913,9 @@ final class AdminPermissionCollection extends PermissionCollection {
 				int newMask = ap.action_mask;
 
 				if (oldMask != newMask) {
-					pc.put(name, new AdminPermission(existing.filter, oldMask
-							| newMask));
+					pc.put(name, new AdminPermission(existing.filter, oldMask | newMask));
 				}
-			}
-			else {
+			} else {
 				pc.put(name, ap);
 			}
 			if (!all_allowed) {
@@ -978,8 +933,8 @@ final class AdminPermissionCollection extends PermissionCollection {
 	 * @param permission The Permission object to compare with the
 	 *        {@code AdminPermission} objects in this collection.
 	 * @return {@code true} if {@code permission} is implied by an
-	 *         {@code AdminPermission} in this collection,
-	 *         {@code false} otherwise.
+	 *         {@code AdminPermission} in this collection, {@code false}
+	 *         otherwise.
 	 */
 	public boolean implies(Permission permission) {
 		if (!(permission instanceof AdminPermission)) {
@@ -1028,28 +983,21 @@ final class AdminPermissionCollection extends PermissionCollection {
 		List<Permission> all = new ArrayList<Permission>(permissions.values());
 		return Collections.enumeration(all);
 	}
-	
+
 	/* serialization logic */
-    private static final ObjectStreamField[]	serialPersistentFields	= {
-			new ObjectStreamField("permissions", Hashtable.class),
-			new ObjectStreamField("all_allowed", Boolean.TYPE)			};
-    
-    private synchronized void writeObject(ObjectOutputStream out)
-			throws IOException {
-		Hashtable<String, AdminPermission> hashtable = new Hashtable<String, AdminPermission>(
-				permissions);
+	private static final ObjectStreamField[]	serialPersistentFields	= {new ObjectStreamField("permissions", Hashtable.class), new ObjectStreamField("all_allowed", Boolean.TYPE)};
+
+	private synchronized void writeObject(ObjectOutputStream out) throws IOException {
+		Hashtable<String, AdminPermission> hashtable = new Hashtable<String, AdminPermission>(permissions);
 		ObjectOutputStream.PutField pfields = out.putFields();
 		pfields.put("permissions", hashtable);
 		pfields.put("all_allowed", all_allowed);
 		out.writeFields();
 	}
-    
-	private synchronized void readObject(java.io.ObjectInputStream in)
-			throws IOException,
-			ClassNotFoundException {
+
+	private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
 		ObjectInputStream.GetField gfields = in.readFields();
-		Hashtable<String, AdminPermission> hashtable = (Hashtable<String, AdminPermission>) gfields
-				.get("permissions", null);
+		Hashtable<String, AdminPermission> hashtable = (Hashtable<String, AdminPermission>) gfields.get("permissions", null);
 		permissions = new HashMap<String, AdminPermission>(hashtable);
 		all_allowed = gfields.get("all_allowed", false);
 	}
diff --git a/src/main/java/org/osgi/framework/AllServiceListener.java b/src/main/java/org/osgi/framework/AllServiceListener.java
index 9874a4b..71e27cd 100644
--- a/src/main/java/org/osgi/framework/AllServiceListener.java
+++ b/src/main/java/org/osgi/framework/AllServiceListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2005, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,45 +17,42 @@
 package org.osgi.framework;
 
 /**
- * A {@code ServiceEvent} listener that does not filter based upon
- * package wiring. {@code AllServiceListener} is a listener interface
- * that may be implemented by a bundle developer. When a
- * {@code ServiceEvent} is fired, it is synchronously delivered to an
- * {@code AllServiceListener}. The Framework may deliver
- * {@code ServiceEvent} objects to an {@code AllServiceListener}
- * out of order and may concurrently call and/or reenter an
+ * A {@code ServiceEvent} listener that does not filter based upon package
+ * wiring. {@code AllServiceListener} is a listener interface that may be
+ * implemented by a bundle developer. When a {@code ServiceEvent} is fired, it
+ * is synchronously delivered to an {@code AllServiceListener}. The Framework
+ * may deliver {@code ServiceEvent} objects to an {@code AllServiceListener} out
+ * of order and may concurrently call and/or reenter an
  * {@code AllServiceListener}.
  * <p>
- * An {@code AllServiceListener} object is registered with the Framework
- * using the {@code BundleContext.addServiceListener} method.
- * {@code AllServiceListener} objects are called with a
- * {@code ServiceEvent} object when a service is registered, modified, or
- * is in the process of unregistering.
+ * An {@code AllServiceListener} object is registered with the Framework using
+ * the {@code BundleContext.addServiceListener} method.
+ * {@code AllServiceListener} objects are called with a {@code ServiceEvent}
+ * object when a service is registered, modified, or is in the process of
+ * unregistering.
  * 
  * <p>
- * {@code ServiceEvent} object delivery to
- * {@code AllServiceListener} objects is filtered by the filter specified
- * when the listener was registered. If the Java Runtime Environment supports
- * permissions, then additional filtering is done. {@code ServiceEvent}
- * objects are only delivered to the listener if the bundle which defines the
- * listener object's class has the appropriate {@code ServicePermission}
- * to get the service using at least one of the named classes under which the
- * service was registered.
+ * {@code ServiceEvent} object delivery to {@code AllServiceListener} objects is
+ * filtered by the filter specified when the listener was registered. If the
+ * Java Runtime Environment supports permissions, then additional filtering is
+ * done. {@code ServiceEvent} objects are only delivered to the listener if the
+ * bundle which defines the listener object's class has the appropriate
+ * {@code ServicePermission} to get the service using at least one of the named
+ * classes under which the service was registered.
  * 
  * <p>
- * Unlike normal {@code ServiceListener} objects,
- * {@code AllServiceListener} objects receive all
- * {@code ServiceEvent} objects regardless of whether the package source
- * of the listening bundle is equal to the package source of the bundle that
- * registered the service. This means that the listener may not be able to cast
- * the service object to any of its corresponding service interfaces if the
- * service object is retrieved.
+ * Unlike normal {@code ServiceListener} objects, {@code AllServiceListener}
+ * objects receive all {@code ServiceEvent} objects regardless of whether the
+ * package source of the listening bundle is equal to the package source of the
+ * bundle that registered the service. This means that the listener may not be
+ * able to cast the service object to any of its corresponding service
+ * interfaces if the service object is retrieved.
  * 
  * @see ServiceEvent
  * @see ServicePermission
  * @ThreadSafe
  * @since 1.3
- * @version $Id: 35cee8a49e89b7b222aa3f85e1af0b4a4b550ce6 $
+ * @version $Id: 7a0c82db414be7064a06e1868eb41a8c8f8d9d6c $
  */
 
 public interface AllServiceListener extends ServiceListener {
diff --git a/src/main/java/org/osgi/framework/Bundle.java b/src/main/java/org/osgi/framework/Bundle.java
index 8f4002c..d814e9a 100644
--- a/src/main/java/org/osgi/framework/Bundle.java
+++ b/src/main/java/org/osgi/framework/Bundle.java
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
- * 
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
@@ -25,7 +25,6 @@ import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.List;
 import java.util.Map;
-
 import org.osgi.framework.wiring.FrameworkWiring;
 
 /**
@@ -59,9 +58,9 @@ import org.osgi.framework.wiring.FrameworkWiring;
  * 
  * <p>
  * A bundle should only have active threads of execution when its state is one
- * of {@code STARTING},{@code ACTIVE}, or {@code STOPPING}. An {@code
- * UNINSTALLED} bundle can not be set to another state; it is a zombie and can
- * only be reached because references are kept somewhere.
+ * of {@code STARTING},{@code ACTIVE}, or {@code STOPPING}. An
+ * {@code UNINSTALLED} bundle can not be set to another state; it is a zombie
+ * and can only be reached because references are kept somewhere.
  * 
  * <p>
  * The Framework is the only entity that is allowed to create {@code Bundle}
@@ -76,7 +75,7 @@ import org.osgi.framework.wiring.FrameworkWiring;
  * 
  * @ThreadSafe
  * @noimplement
- * @version $Id: 239108e8d54ff493587b9cdfe1688bdefc5a714c $
+ * @version $Id: 8a58ab72af389b1999b88348e4944203b7096510 $
  */
 public interface Bundle extends Comparable<Bundle> {
 	/**
@@ -139,9 +138,9 @@ public interface Bundle extends Comparable<Bundle> {
 	 * <p>
 	 * A bundle is in the {@code STARTING} state when its {@link #start(int)
 	 * start} method is active. A bundle must be in this state when the bundle's
-	 * {@link BundleActivator#start} is called. If the {@code
-	 * BundleActivator.start} method completes without exception, then the
-	 * bundle has successfully started and must move to the {@code ACTIVE}
+	 * {@link BundleActivator#start(BundleContext)} is called. If the
+	 * {@code BundleActivator.start} method completes without exception, then
+	 * the bundle has successfully started and must move to the {@code ACTIVE}
 	 * state.
 	 * <p>
 	 * If the bundle has a {@link Constants#ACTIVATION_LAZY lazy activation
@@ -158,9 +157,9 @@ public interface Bundle extends Comparable<Bundle> {
 	 * <p>
 	 * A bundle is in the {@code STOPPING} state when its {@link #stop(int)
 	 * stop} method is active. A bundle must be in this state when the bundle's
-	 * {@link BundleActivator#stop} method is called. When the {@code
-	 * BundleActivator.stop} method completes the bundle is stopped and must
-	 * move to the {@code RESOLVED} state.
+	 * {@link BundleActivator#stop(BundleContext)} method is called. When the
+	 * {@code BundleActivator.stop} method completes the bundle is stopped and
+	 * must move to the {@code RESOLVED} state.
 	 * <p>
 	 * The value of {@code STOPPING} is 0x00000010.
 	 */
@@ -312,8 +311,8 @@ public interface Bundle extends Comparable<Bundle> {
 	 * 
 	 * <li>A bundle event of type {@link BundleEvent#STARTING} is fired.
 	 * 
-	 * <li>The {@link BundleActivator#start} method of this bundle's
-	 * {@code BundleActivator}, if one is specified, is called. If the
+	 * <li>The {@link BundleActivator#start(BundleContext)} method of this
+	 * bundle's {@code BundleActivator}, if one is specified, is called. If the
 	 * {@code BundleActivator} is invalid or throws an exception then:
 	 * <ul>
 	 * <li>This bundle's state is set to {@code STOPPING}.
@@ -425,11 +424,11 @@ public interface Bundle extends Comparable<Bundle> {
 	 * <li>A bundle event of type {@link BundleEvent#STOPPING} is fired.
 	 * 
 	 * <li>If this bundle's state was {@code ACTIVE} prior to setting the state
-	 * to {@code STOPPING}, the {@link BundleActivator#stop} method of this
-	 * bundle's {@code BundleActivator}, if one is specified, is called. If that
-	 * method throws an exception, this method must continue to stop this bundle
-	 * and a {@code BundleException} must be thrown after completion of the
-	 * remaining steps.
+	 * to {@code STOPPING}, the {@link BundleActivator#stop(BundleContext)}
+	 * method of this bundle's {@code BundleActivator}, if one is specified, is
+	 * called. If that method throws an exception, this method must continue to
+	 * stop this bundle and a {@code BundleException} must be thrown after
+	 * completion of the remaining steps.
 	 * 
 	 * <li>Any services registered by this bundle must be unregistered.
 	 * <li>Any services used by this bundle must be released.
@@ -748,10 +747,10 @@ public interface Bundle extends Comparable<Bundle> {
 	 * Returns this bundle's location identifier.
 	 * 
 	 * <p>
-	 * The location identifier is the location passed to {@code
-	 * BundleContext.installBundle} when a bundle is installed. The location
-	 * identifier does not change while this bundle remains installed, even if
-	 * this bundle is updated.
+	 * The location identifier is the location passed to
+	 * {@code BundleContext.installBundle} when a bundle is installed. The
+	 * location identifier does not change while this bundle remains installed,
+	 * even if this bundle is updated.
 	 * 
 	 * <p>
 	 * This method must continue to return this bundle's location identifier
@@ -785,7 +784,7 @@ public interface Bundle extends Comparable<Bundle> {
 	 * @see ServiceReference
 	 * @see ServicePermission
 	 */
-	ServiceReference< ? >[] getRegisteredServices();
+	ServiceReference<?>[] getRegisteredServices();
 
 	/**
 	 * Returns this bundle's {@code ServiceReference} list for all services it
@@ -794,10 +793,11 @@ public interface Bundle extends Comparable<Bundle> {
 	 * for that service is greater than zero.
 	 * 
 	 * <p>
-	 * If the Java Runtime Environment supports permissions, a {@code
-	 * ServiceReference} object to a service is included in the returned list
-	 * only if the caller has the {@code ServicePermission} to get the service
-	 * using at least one of the named classes the service was registered under.
+	 * If the Java Runtime Environment supports permissions, a
+	 * {@code ServiceReference} object to a service is included in the returned
+	 * list only if the caller has the {@code ServicePermission} to get the
+	 * service using at least one of the named classes the service was
+	 * registered under.
 	 * <p>
 	 * The list is valid at the time of the call to this method, however, as the
 	 * Framework is a very dynamic environment, services can be modified or
@@ -808,7 +808,7 @@ public interface Bundle extends Comparable<Bundle> {
 	 * @see ServiceReference
 	 * @see ServicePermission
 	 */
-	ServiceReference< ? >[] getServicesInUse();
+	ServiceReference<?>[] getServicesInUse();
 
 	/**
 	 * Determines if this bundle has the specified permissions.
@@ -832,8 +832,8 @@ public interface Bundle extends Comparable<Bundle> {
 	 * @return {@code true} if this bundle has the specified permission or the
 	 *         permissions possessed by this bundle imply the specified
 	 *         permission; {@code false} if this bundle does not have the
-	 *         specified permission or {@code permission} is not an {@code
-	 *         instanceof} {@code java.security.Permission}.
+	 *         specified permission or {@code permission} is not an
+	 *         {@code instanceof} {@code java.security.Permission}.
 	 * @throws IllegalStateException If this bundle has been uninstalled.
 	 */
 	boolean hasPermission(Object permission);
@@ -857,12 +857,12 @@ public interface Bundle extends Comparable<Bundle> {
 	 *        for a description of the format of a resource name.
 	 * @return A URL to the named resource, or {@code null} if the resource
 	 *         could not be found or if this bundle is a fragment bundle or if
-	 *         the caller does not have the appropriate {@code
-	 *         AdminPermission[this,RESOURCE]}, and the Java Runtime Environment
-	 *         supports permissions.
+	 *         the caller does not have the appropriate
+	 *         {@code AdminPermission[this,RESOURCE]}, and the Java Runtime
+	 *         Environment supports permissions.
 	 * @throws IllegalStateException If this bundle has been uninstalled.
-	 * @see #getEntry
-	 * @see #findEntries
+	 * @see #getEntry(String)
+	 * @see #findEntries(String, String, boolean)
 	 * @since 1.1
 	 */
 	URL getResource(String name);
@@ -926,10 +926,10 @@ public interface Bundle extends Comparable<Bundle> {
 	Dictionary<String, String> getHeaders(String locale);
 
 	/**
-	 * Returns the symbolic name of this bundle as specified by its {@code
-	 * Bundle-SymbolicName} manifest header. The bundle symbolic name should be
-	 * based on the reverse domain name naming convention like that used for
-	 * java packages.
+	 * Returns the symbolic name of this bundle as specified by its
+	 * {@code Bundle-SymbolicName} manifest header. The bundle symbolic name
+	 * should be based on the reverse domain name naming convention like that
+	 * used for java packages.
 	 * 
 	 * <p>
 	 * This method must continue to return this bundle's symbolic name while
@@ -945,8 +945,8 @@ public interface Bundle extends Comparable<Bundle> {
 	 * Loads the specified class using this bundle's class loader.
 	 * 
 	 * <p>
-	 * If this bundle is a fragment bundle then this method must throw a {@code
-	 * ClassNotFoundException}.
+	 * If this bundle is a fragment bundle then this method must throw a
+	 * {@code ClassNotFoundException}.
 	 * 
 	 * <p>
 	 * If this bundle's state is {@code INSTALLED}, this method must attempt to
@@ -954,13 +954,13 @@ public interface Bundle extends Comparable<Bundle> {
 	 * 
 	 * <p>
 	 * If this bundle cannot be resolved, a Framework event of type
-	 * {@link FrameworkEvent#ERROR} is fired containing a {@code
-	 * BundleException} with details of the reason this bundle could not be
-	 * resolved. This method must then throw a {@code ClassNotFoundException}.
+	 * {@link FrameworkEvent#ERROR} is fired containing a
+	 * {@code BundleException} with details of the reason this bundle could not
+	 * be resolved. This method must then throw a {@code ClassNotFoundException}.
 	 * 
 	 * <p>
-	 * If this bundle's state is {@code UNINSTALLED}, then an {@code
-	 * IllegalStateException} is thrown.
+	 * If this bundle's state is {@code UNINSTALLED}, then an
+	 * {@code IllegalStateException} is thrown.
 	 * 
 	 * @param name The name of the class to load.
 	 * @return The Class object for the requested class.
@@ -971,7 +971,7 @@ public interface Bundle extends Comparable<Bundle> {
 	 * @throws IllegalStateException If this bundle has been uninstalled.
 	 * @since 1.3
 	 */
-	Class< ? > loadClass(String name) throws ClassNotFoundException;
+	Class<?> loadClass(String name) throws ClassNotFoundException;
 
 	/**
 	 * Find the specified resources from this bundle's class loader.
@@ -988,14 +988,14 @@ public interface Bundle extends Comparable<Bundle> {
 	 * URLs to directory entries will not be returned if the bundle contents do
 	 * not contain directory entries.
 	 * 
-	 * @param name The name of the resource. See {@code
-	 *        ClassLoader.getResources} for a description of the format of a
-	 *        resource name.
+	 * @param name The name of the resource. See
+	 *        {@code ClassLoader.getResources} for a description of the format
+	 *        of a resource name.
 	 * @return An enumeration of URLs to the named resources, or {@code null} if
 	 *         the resource could not be found or if this bundle is a fragment
-	 *         bundle or if the caller does not have the appropriate {@code
-	 *         AdminPermission[this,RESOURCE]}, and the Java Runtime Environment
-	 *         supports permissions.
+	 *         bundle or if the caller does not have the appropriate
+	 *         {@code AdminPermission[this,RESOURCE]}, and the Java Runtime
+	 *         Environment supports permissions.
 	 * @throws IllegalStateException If this bundle has been uninstalled.
 	 * @throws IOException If there is an I/O error.
 	 * @since 1.3
@@ -1045,9 +1045,9 @@ public interface Bundle extends Comparable<Bundle> {
 	 * 
 	 * @param path The path name of the entry.
 	 * @return A URL to the entry, or {@code null} if no entry could be found or
-	 *         if the caller does not have the appropriate {@code
-	 *         AdminPermission[this,RESOURCE]} and the Java Runtime Environment
-	 *         supports permissions.
+	 *         if the caller does not have the appropriate
+	 *         {@code AdminPermission[this,RESOURCE]} and the Java Runtime
+	 *         Environment supports permissions.
 	 * @throws IllegalStateException If this bundle has been uninstalled.
 	 * @since 1.3
 	 */
@@ -1059,7 +1059,7 @@ public interface Bundle extends Comparable<Bundle> {
 	 * 
 	 * <p>
 	 * The time value is the number of milliseconds since January 1, 1970,
-	 * 00:00:00 GMT.
+	 * 00:00:00 UTC.
 	 * 
 	 * @return The time when this bundle was last modified.
 	 * @since 1.3
@@ -1078,7 +1078,7 @@ public interface Bundle extends Comparable<Bundle> {
 	 * This method is intended to be used to obtain configuration, setup,
 	 * localization and other information from this bundle. This method takes
 	 * into account that the "contents" of this bundle can be extended
-	 * with fragments. This "bundle space" is not a name space with
+	 * with fragments. This "bundle space" is not a namespace with
 	 * unique members; the same entry name can be present multiple times. This
 	 * method therefore returns an enumeration of URL objects. These URLs can
 	 * come from different JARs but have the same path name. This method can
@@ -1096,13 +1096,15 @@ public interface Bundle extends Comparable<Bundle> {
 	 * Enumeration e = b.findEntries("OSGI-INF", "*.xml", true);
 	 * 
 	 * // Find a specific localization file
-	 * Enumeration e = b
-	 * 		.findEntries("OSGI-INF/l10n", "bundle_nl_DU.properties", false);
+	 * Enumeration e = b.findEntries("OSGI-INF/l10n",
+	 *     "bundle_nl_DU.properties", false);
 	 * if (e.hasMoreElements())
-	 * 	return (URL) e.nextElement();
+	 *     return (URL) e.nextElement();
 	 * </pre>
 	 * 
 	 * <p>
+	 * URLs for directory entries must have their path end with "/".
+	 * <p>
 	 * Note: Jar and zip files are not required to include directory entries.
 	 * URLs to directory entries will not be returned if the bundle contents do
 	 * not contain directory entries.
@@ -1121,8 +1123,8 @@ public interface Bundle extends Comparable<Bundle> {
 	 * @param recurse If {@code true}, recurse into subdirectories. Otherwise
 	 *        only return entries from the specified path.
 	 * @return An enumeration of URL objects for each matching entry, or
-	 *         {@code null} if no matching entry could not be found or if the
-	 *         caller does not have the appropriate
+	 *         {@code null} if no matching entry could be found or if the caller
+	 *         does not have the appropriate
 	 *         {@code AdminPermission[this,RESOURCE]}, and the Java Runtime
 	 *         Environment supports permissions. The URLs are sorted such that
 	 *         entries from this bundle are returned first followed by the
@@ -1132,12 +1134,12 @@ public interface Bundle extends Comparable<Bundle> {
 	 * @throws IllegalStateException If this bundle has been uninstalled.
 	 * @since 1.3
 	 */
-	Enumeration<URL> findEntries(String path, String filePattern,
-			boolean recurse);
+	Enumeration<URL> findEntries(String path, String filePattern, boolean recurse);
 
 	/**
-	 * Returns this bundle's {@link BundleContext}. The returned {@code
-	 * BundleContext} can be used by the caller to act on behalf of this bundle.
+	 * Returns this bundle's {@link BundleContext}. The returned
+	 * {@code BundleContext} can be used by the caller to act on behalf of this
+	 * bundle.
 	 * 
 	 * <p>
 	 * If this bundle is not in the {@link #STARTING}, {@link #ACTIVE}, or
@@ -1176,13 +1178,12 @@ public interface Bundle extends Comparable<Bundle> {
 	 *         not {@link #SIGNERS_ALL} or {@link #SIGNERS_TRUSTED}.
 	 * @since 1.5
 	 */
-	Map<X509Certificate, List<X509Certificate>> getSignerCertificates(
-			int signersType);
+	Map<X509Certificate, List<X509Certificate>> getSignerCertificates(int signersType);
 
 	/**
-	 * Returns the version of this bundle as specified by its {@code
-	 * Bundle-Version} manifest header. If this bundle does not have a specified
-	 * version then {@link Version#emptyVersion} is returned.
+	 * Returns the version of this bundle as specified by its
+	 * {@code Bundle-Version} manifest header. If this bundle does not have a
+	 * specified version then {@link Version#emptyVersion} is returned.
 	 * 
 	 * <p>
 	 * This method must continue to return this bundle's version while this
diff --git a/src/main/java/org/osgi/framework/BundleActivator.java b/src/main/java/org/osgi/framework/BundleActivator.java
index aefb036..acdb825 100644
--- a/src/main/java/org/osgi/framework/BundleActivator.java
+++ b/src/main/java/org/osgi/framework/BundleActivator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,20 +19,19 @@ package org.osgi.framework;
 /**
  * Customizes the starting and stopping of a bundle.
  * <p>
- * {@code BundleActivator} is an interface that may be implemented when a
- * bundle is started or stopped. The Framework can create instances of a
- * bundle's {@code BundleActivator} as required. If an instance's
- * {@code BundleActivator.start} method executes successfully, it is
- * guaranteed that the same instance's {@code BundleActivator.stop}
- * method will be called when the bundle is to be stopped. The Framework must
- * not concurrently call a {@code BundleActivator} object.
+ * {@code BundleActivator} is an interface that may be implemented when a bundle
+ * is started or stopped. The Framework can create instances of a bundle's
+ * {@code BundleActivator} as required. If an instance's
+ * {@code BundleActivator.start} method executes successfully, it is guaranteed
+ * that the same instance's {@code BundleActivator.stop} method will be called
+ * when the bundle is to be stopped. The Framework must not concurrently call a
+ * {@code BundleActivator} object.
  * 
  * <p>
- * {@code BundleActivator} is specified through the
- * {@code Bundle-Activator} Manifest header. A bundle can only specify a
- * single {@code BundleActivator} in the Manifest file. Fragment bundles
- * must not have a {@code BundleActivator}. The form of the Manifest
- * header is:
+ * {@code BundleActivator} is specified through the {@code Bundle-Activator}
+ * Manifest header. A bundle can only specify a single {@code BundleActivator}
+ * in the Manifest file. Fragment bundles must not have a
+ * {@code BundleActivator}. The form of the Manifest header is:
  * 
  * <p>
  * {@code Bundle-Activator: <i>class-name</i>}
@@ -40,12 +39,12 @@ package org.osgi.framework;
  * <p>
  * where {@code <i>class-name</i>} is a fully qualified Java classname.
  * <p>
- * The specified {@code BundleActivator} class must have a public
- * constructor that takes no parameters so that a {@code BundleActivator}
- * object can be created by {@code Class.newInstance()}.
+ * The specified {@code BundleActivator} class must have a public constructor
+ * that takes no parameters so that a {@code BundleActivator} object can be
+ * created by {@code Class.newInstance()}.
  * 
  * @NotThreadSafe
- * @version $Id: 1b73057bd270ab07f0a16430dba16e5132eea24f $
+ * @version $Id: f5b2debe0064ab60669102d0a087feaeab13dc0e $
  */
 
 public interface BundleActivator {
@@ -59,29 +58,29 @@ public interface BundleActivator {
 	 * This method must complete and return to its caller in a timely manner.
 	 * 
 	 * @param context The execution context of the bundle being started.
-	 * @throws Exception If this method throws an exception, this
-	 *         bundle is marked as stopped and the Framework will remove this
-	 *         bundle's listeners, unregister all services registered by this
-	 *         bundle, and release all services used by this bundle.
+	 * @throws Exception If this method throws an exception, this bundle is
+	 *         marked as stopped and the Framework will remove this bundle's
+	 *         listeners, unregister all services registered by this bundle, and
+	 *         release all services used by this bundle.
 	 */
 	public void start(BundleContext context) throws Exception;
 
 	/**
 	 * Called when this bundle is stopped so the Framework can perform the
 	 * bundle-specific activities necessary to stop the bundle. In general, this
-	 * method should undo the work that the {@code BundleActivator.start}
-	 * method started. There should be no active threads that were started by
-	 * this bundle when this bundle returns. A stopped bundle must not call any
+	 * method should undo the work that the {@code BundleActivator.start} method
+	 * started. There should be no active threads that were started by this
+	 * bundle when this bundle returns. A stopped bundle must not call any
 	 * Framework objects.
 	 * 
 	 * <p>
 	 * This method must complete and return to its caller in a timely manner.
 	 * 
 	 * @param context The execution context of the bundle being stopped.
-	 * @throws Exception If this method throws an exception, the
-	 *         bundle is still marked as stopped, and the Framework will remove
-	 *         the bundle's listeners, unregister all services registered by the
-	 *         bundle, and release all services used by the bundle.
+	 * @throws Exception If this method throws an exception, the bundle is still
+	 *         marked as stopped, and the Framework will remove the bundle's
+	 *         listeners, unregister all services registered by the bundle, and
+	 *         release all services used by the bundle.
 	 */
 	public void stop(BundleContext context) throws Exception;
 }
diff --git a/src/main/java/org/osgi/framework/BundleContext.java b/src/main/java/org/osgi/framework/BundleContext.java
index c587d03..71c3b92 100644
--- a/src/main/java/org/osgi/framework/BundleContext.java
+++ b/src/main/java/org/osgi/framework/BundleContext.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -47,11 +47,11 @@ import java.util.Dictionary;
  * 
  * <p>
  * The {@code BundleContext} object will be passed to the
- * {@link BundleActivator#start} method during activation of the context bundle.
- * The same {@code BundleContext} object will be passed to the
- * {@link BundleActivator#stop} method when the context bundle is stopped. A
- * {@code BundleContext} object is generally for the private use of its
- * associated bundle and is not meant to be shared with other bundles in the
+ * {@link BundleActivator#start(BundleContext)} method during activation of the
+ * context bundle. The same {@code BundleContext} object will be passed to the
+ * {@link BundleActivator#stop(BundleContext)} method when the context bundle is
+ * stopped. A {@code BundleContext} object is generally for the private use of
+ * its associated bundle and is not meant to be shared with other bundles in the
  * OSGi environment.
  * 
  * <p>
@@ -76,7 +76,7 @@ import java.util.Dictionary;
  * 
  * @ThreadSafe
  * @noimplement
- * @version $Id: 6d4b5967b9fe706b1dfbdd42b3d759028ed9826d $
+ * @version $Id: 4f166fd274f3965e48a7dbc239213d00e062b6d0 $
  */
 
 public interface BundleContext extends BundleReference {
@@ -175,8 +175,7 @@ public interface BundleContext extends BundleReference {
 	 *         Runtime Environment supports permissions.
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 */
-	Bundle installBundle(String location, InputStream input)
-			throws BundleException;
+	Bundle installBundle(String location, InputStream input) throws BundleException;
 
 	/**
 	 * Installs a bundle from the specified {@code location} identifier.
@@ -270,8 +269,7 @@ public interface BundleContext extends BundleReference {
 	 * @see ServiceListener
 	 * @see ServicePermission
 	 */
-	void addServiceListener(ServiceListener listener, String filter)
-			throws InvalidSyntaxException;
+	void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException;
 
 	/**
 	 * Adds the specified {@code ServiceListener} object to the context bundle's
@@ -374,8 +372,11 @@ public interface BundleContext extends BundleReference {
 	 * {@code ServiceRegistration} object is for the private use of the bundle
 	 * registering the service and should not be shared with other bundles. The
 	 * registering bundle is defined to be the context bundle. Other bundles can
-	 * locate the service by using either the {@link #getServiceReferences} or
-	 * {@link #getServiceReference} method.
+	 * locate the service by using one of the
+	 * {@link #getServiceReferences(Class, String)},
+	 * {@link #getServiceReferences(String, String)},
+	 * {@link #getServiceReference(Class)} or
+	 * {@link #getServiceReference(String)} methods.
 	 * 
 	 * <p>
 	 * A bundle can register a service object that implements the
@@ -413,9 +414,9 @@ public interface BundleContext extends BundleReference {
 	 *        {@link Constants} for a list of standard service property keys.
 	 *        Changes should not be made to this object after calling this
 	 *        method. To update the service's properties the
-	 *        {@link ServiceRegistration#setProperties} method must be called.
-	 *        The set of properties may be {@code null} if the service has no
-	 *        properties.
+	 *        {@link ServiceRegistration#setProperties(Dictionary)} method must
+	 *        be called. The set of properties may be {@code null} if the
+	 *        service has no properties.
 	 * @return A {@code ServiceRegistration} object for use by the bundle
 	 *         registering the service to update the service's properties or to
 	 *         unregister the service.
@@ -434,8 +435,7 @@ public interface BundleContext extends BundleReference {
 	 * @see ServiceRegistration
 	 * @see ServiceFactory
 	 */
-	ServiceRegistration< ? > registerService(String[] clazzes, Object service,
-			Dictionary<String, ? > properties);
+	ServiceRegistration<?> registerService(String[] clazzes, Object service, Dictionary<String, ?> properties);
 
 	/**
 	 * Registers the specified service object with the specified properties
@@ -458,34 +458,29 @@ public interface BundleContext extends BundleReference {
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @see #registerService(String[], Object, Dictionary)
 	 */
-	ServiceRegistration< ? > registerService(String clazz, Object service,
-			Dictionary<String, ? > properties);
+	ServiceRegistration<?> registerService(String clazz, Object service, Dictionary<String, ?> properties);
 
 	/**
 	 * Registers the specified service object with the specified properties
-	 * under the specified class name with the Framework.
+	 * under the name of the specified class with the Framework.
 	 * 
 	 * <p>
 	 * This method is otherwise identical to
-	 * {@link #registerService(String[], Object, Dictionary)} and is provided as
-	 * a convenience when {@code service} will only be registered under a single
-	 * class name. Note that even in this case the value of the service's
-	 * {@link Constants#OBJECTCLASS} property will be an array of string, rather
-	 * than just a single string.
+	 * {@link #registerService(String, Object, Dictionary)} and is provided to
+	 * return a type safe {@code ServiceRegistration}.
 	 * 
 	 * @param <S> Type of Service.
-	 * @param clazz The class name under which the service can be located.
+	 * @param clazz The class under whose name the service can be located.
 	 * @param service The service object or a {@code ServiceFactory} object.
 	 * @param properties The properties for this service.
 	 * @return A {@code ServiceRegistration} object for use by the bundle
 	 *         registering the service to update the service's properties or to
 	 *         unregister the service.
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
-	 * @see #registerService(String[], Object, Dictionary)
+	 * @see #registerService(String, Object, Dictionary)
 	 * @since 1.6
 	 */
-	<S> ServiceRegistration<S> registerService(Class<S> clazz, S service,
-			Dictionary<String, ? > properties);
+	<S> ServiceRegistration<S> registerService(Class<S> clazz, S service, Dictionary<String, ?> properties);
 
 	/**
 	 * Returns an array of {@code ServiceReference} objects. The returned array
@@ -539,8 +534,7 @@ public interface BundleContext extends BundleReference {
 	 *         an invalid filter expression that cannot be parsed.
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 */
-	ServiceReference< ? >[] getServiceReferences(String clazz, String filter)
-			throws InvalidSyntaxException;
+	ServiceReference<?>[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException;
 
 	/**
 	 * Returns an array of {@code ServiceReference} objects. The returned array
@@ -589,8 +583,7 @@ public interface BundleContext extends BundleReference {
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @since 1.3
 	 */
-	ServiceReference< ? >[] getAllServiceReferences(String clazz, String filter)
-			throws InvalidSyntaxException;
+	ServiceReference<?>[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException;
 
 	/**
 	 * Returns a {@code ServiceReference} object for a service that implements
@@ -623,11 +616,11 @@ public interface BundleContext extends BundleReference {
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @see #getServiceReferences(String, String)
 	 */
-	ServiceReference< ? > getServiceReference(String clazz);
+	ServiceReference<?> getServiceReference(String clazz);
 
 	/**
 	 * Returns a {@code ServiceReference} object for a service that implements
-	 * and was registered under the specified class.
+	 * and was registered under the name of the specified class.
 	 * 
 	 * <p>
 	 * The returned {@code ServiceReference} object is valid at the time of the
@@ -648,9 +641,10 @@ public interface BundleContext extends BundleReference {
 	 * service that was registered first is returned.
 	 * 
 	 * @param <S> Type of Service.
-	 * @param clazz The class name with which the service was registered.
+	 * @param clazz The class under whose name the service was registered. Must
+	 *        not be {@code null}.
 	 * @return A {@code ServiceReference} object, or {@code null} if no services
-	 *         are registered which implement the named class.
+	 *         are registered which implement the specified class.
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @see #getServiceReferences(Class, String)
 	 * @since 1.6
@@ -660,10 +654,10 @@ public interface BundleContext extends BundleReference {
 	/**
 	 * Returns a collection of {@code ServiceReference} objects. The returned
 	 * collection of {@code ServiceReference} objects contains services that
-	 * were registered under the specified class, match the specified filter
-	 * expression, and the packages for the class names under which the services
-	 * were registered match the context bundle's packages as defined in
-	 * {@link ServiceReference#isAssignableTo(Bundle, String)}.
+	 * were registered under the name of the specified class, match the
+	 * specified filter expression, and the packages for the class names under
+	 * which the services were registered match the context bundle's packages as
+	 * defined in {@link ServiceReference#isAssignableTo(Bundle, String)}.
 	 * 
 	 * <p>
 	 * The collection is valid at the time of the call to this method. However
@@ -684,11 +678,10 @@ public interface BundleContext extends BundleReference {
 	 * The result is a collection of {@code ServiceReference} objects for all
 	 * services that meet all of the following conditions:
 	 * <ul>
-	 * <li>If the specified class name, {@code clazz}, is not {@code null}, the
-	 * service must have been registered with the specified class name. The
-	 * complete list of class names with which a service was registered is
-	 * available from the service's {@link Constants#OBJECTCLASS objectClass}
-	 * property.
+	 * <li>The service must have been registered with the name of the specified
+	 * class. The complete list of class names with which a service was
+	 * registered is available from the service's {@link Constants#OBJECTCLASS
+	 * objectClass} property.
 	 * <li>If the specified {@code filter} is not {@code null}, the filter
 	 * expression must match the service.
 	 * <li>If the Java Runtime Environment supports permissions, the caller must
@@ -701,7 +694,7 @@ public interface BundleContext extends BundleReference {
 	 * </ul>
 	 * 
 	 * @param <S> Type of Service
-	 * @param clazz The class name with which the service was registered. Must
+	 * @param clazz The class under whose name the service was registered. Must
 	 *        not be {@code null}.
 	 * @param filter The filter expression or {@code null} for all services.
 	 * @return A collection of {@code ServiceReference} objects. May be empty if
@@ -711,8 +704,7 @@ public interface BundleContext extends BundleReference {
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @since 1.6
 	 */
-	<S> Collection<ServiceReference<S>> getServiceReferences(Class<S> clazz,
-			String filter) throws InvalidSyntaxException;
+	<S> Collection<ServiceReference<S>> getServiceReferences(Class<S> clazz, String filter) throws InvalidSyntaxException;
 
 	/**
 	 * Returns the service object referenced by the specified
@@ -810,10 +802,10 @@ public interface BundleContext extends BundleReference {
 	 * @throws IllegalArgumentException If the specified
 	 *         {@code ServiceReference} was not created by the same framework
 	 *         instance as this {@code BundleContext}.
-	 * @see #getService
+	 * @see #getService(ServiceReference)
 	 * @see ServiceFactory
 	 */
-	boolean ungetService(ServiceReference< ? > reference);
+	boolean ungetService(ServiceReference<?> reference);
 
 	/**
 	 * Creates a {@code File} object for a file in the persistent storage area
diff --git a/src/main/java/org/osgi/framework/BundleEvent.java b/src/main/java/org/osgi/framework/BundleEvent.java
index 13c68be..04a34a3 100644
--- a/src/main/java/org/osgi/framework/BundleEvent.java
+++ b/src/main/java/org/osgi/framework/BundleEvent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,9 +22,9 @@ import java.util.EventObject;
  * An event from the Framework describing a bundle lifecycle change.
  * <p>
  * {@code BundleEvent} objects are delivered to
- * {@code SynchronousBundleListener}s and {@code BundleListener}s
- * when a change occurs in a bundle's lifecycle. A type code is used to identify
- * the event type for future extendability.
+ * {@code SynchronousBundleListener}s and {@code BundleListener}s when a change
+ * occurs in a bundle's lifecycle. A type code is used to identify the event
+ * type for future extendability.
  * 
  * <p>
  * OSGi Alliance reserves the right to extend the set of types.
@@ -32,7 +32,7 @@ import java.util.EventObject;
  * @Immutable
  * @see BundleListener
  * @see SynchronousBundleListener
- * @version $Id: ed3c40cd707bed45681cadce114a6cc5db27a844 $
+ * @version $Id: 9e2102212eb526b5f11fdde4b0fc5c171a0b39c8 $
  */
 
 public class BundleEvent extends EventObject {
@@ -57,9 +57,9 @@ public class BundleEvent extends EventObject {
 	/**
 	 * The bundle has been started.
 	 * <p>
-	 * The bundle's
-	 * {@link BundleActivator#start(BundleContext) BundleActivator start} method
-	 * has been executed if the bundle has a bundle activator class.
+	 * The bundle's {@link BundleActivator#start(BundleContext) BundleActivator
+	 * start} method has been executed if the bundle has a bundle activator
+	 * class.
 	 * 
 	 * @see Bundle#start()
 	 */
@@ -68,9 +68,9 @@ public class BundleEvent extends EventObject {
 	/**
 	 * The bundle has been stopped.
 	 * <p>
-	 * The bundle's
-	 * {@link BundleActivator#stop(BundleContext) BundleActivator stop} method
-	 * has been executed if the bundle has a bundle activator class.
+	 * The bundle's {@link BundleActivator#stop(BundleContext) BundleActivator
+	 * stop} method has been executed if the bundle has a bundle activator
+	 * class.
 	 * 
 	 * @see Bundle#stop()
 	 */
@@ -86,7 +86,7 @@ public class BundleEvent extends EventObject {
 	/**
 	 * The bundle has been uninstalled.
 	 * 
-	 * @see Bundle#uninstall
+	 * @see Bundle#uninstall()
 	 */
 	public final static int	UNINSTALLED			= 0x00000010;
 
@@ -109,11 +109,10 @@ public class BundleEvent extends EventObject {
 	/**
 	 * The bundle is about to be activated.
 	 * <p>
-	 * The bundle's
-	 * {@link BundleActivator#start(BundleContext) BundleActivator start} method
-	 * is about to be called if the bundle has a bundle activator class. This
-	 * event is only delivered to {@link SynchronousBundleListener}s. It is not
-	 * delivered to {@code BundleListener}s.
+	 * The bundle's {@link BundleActivator#start(BundleContext) BundleActivator
+	 * start} method is about to be called if the bundle has a bundle activator
+	 * class. This event is only delivered to {@link SynchronousBundleListener}
+	 * s. It is not delivered to {@code BundleListener}s.
 	 * 
 	 * @see Bundle#start()
 	 * @since 1.3
@@ -123,11 +122,10 @@ public class BundleEvent extends EventObject {
 	/**
 	 * The bundle is about to deactivated.
 	 * <p>
-	 * The bundle's
-	 * {@link BundleActivator#stop(BundleContext) BundleActivator stop} method
-	 * is about to be called if the bundle has a bundle activator class. This
-	 * event is only delivered to {@link SynchronousBundleListener}s. It is not
-	 * delivered to {@code BundleListener}s.
+	 * The bundle's {@link BundleActivator#stop(BundleContext) BundleActivator
+	 * stop} method is about to be called if the bundle has a bundle activator
+	 * class. This event is only delivered to {@link SynchronousBundleListener}
+	 * s. It is not delivered to {@code BundleListener}s.
 	 * 
 	 * @see Bundle#stop()
 	 * @since 1.3
@@ -138,10 +136,9 @@ public class BundleEvent extends EventObject {
 	 * The bundle will be lazily activated.
 	 * <p>
 	 * The bundle has a {@link Constants#ACTIVATION_LAZY lazy activation policy}
-	 * and is waiting to be activated. It is now in the
-	 * {@link Bundle#STARTING STARTING} state and has a valid
-	 * {@code BundleContext}. This event is only delivered to
-	 * {@link SynchronousBundleListener}s. It is not delivered to
+	 * and is waiting to be activated. It is now in the {@link Bundle#STARTING
+	 * STARTING} state and has a valid {@code BundleContext}. This event is only
+	 * delivered to {@link SynchronousBundleListener}s. It is not delivered to
 	 * {@code BundleListener}s.
 	 * 
 	 * @since 1.4
diff --git a/src/main/java/org/osgi/framework/BundleException.java b/src/main/java/org/osgi/framework/BundleException.java
index 9cae61a..c47eb77 100644
--- a/src/main/java/org/osgi/framework/BundleException.java
+++ b/src/main/java/org/osgi/framework/BundleException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,10 +21,10 @@ package org.osgi.framework;
  * occurred.
  * 
  * <p>
- * A {@code BundleException} object is created by the Framework to denote
- * an exception condition in the lifecycle of a bundle.
- * {@code BundleException}s should not be created by bundle developers.
- * A type code is used to identify the exception type for future extendability.
+ * A {@code BundleException} object is created by the Framework to denote an
+ * exception condition in the lifecycle of a bundle. {@code BundleException}s
+ * should not be created by bundle developers. A type code is used to identify
+ * the exception type for future extendability.
  * 
  * <p>
  * OSGi Alliance reserves the right to extend the set of types.
@@ -32,7 +32,7 @@ package org.osgi.framework;
  * <p>
  * This exception conforms to the general purpose exception chaining mechanism.
  * 
- * @version $Id: 9e117ec9667b040f7752e342aa07d6c7d5bf0275 $
+ * @version $Id: 0c97ed2696b4576d61440020922b1a97545beb1e $
  */
 
 public class BundleException extends Exception {
@@ -51,7 +51,7 @@ public class BundleException extends Exception {
 	 */
 	public static final int	UNSPECIFIED				= 0;
 	/**
-	 * The operation was unsupported. This type can be used anywhere a 
+	 * The operation was unsupported. This type can be used anywhere a
 	 * BundleException can be thrown.
 	 * 
 	 * @since 1.5
@@ -112,8 +112,8 @@ public class BundleException extends Exception {
 	 * @since 1.5
 	 */
 	public static final int	DUPLICATE_BUNDLE_ERROR	= 9;
-	
-    /**
+
+	/**
 	 * The start transient operation failed because the start level of the
 	 * bundle is greater than the current framework start level
 	 * 
@@ -157,8 +157,8 @@ public class BundleException extends Exception {
 	}
 
 	/**
-	 * Creates a {@code BundleException} with the specified message, type
-	 * and exception cause.
+	 * Creates a {@code BundleException} with the specified message, type and
+	 * exception cause.
 	 * 
 	 * @param msg The associated message.
 	 * @param type The type for this exception.
@@ -171,8 +171,7 @@ public class BundleException extends Exception {
 	}
 
 	/**
-	 * Creates a {@code BundleException} with the specified message and
-	 * type.
+	 * Creates a {@code BundleException} with the specified message and type.
 	 * 
 	 * @param msg The message.
 	 * @param type The type for this exception.
@@ -189,8 +188,8 @@ public class BundleException extends Exception {
 	 * 
 	 * <p>
 	 * This method predates the general purpose exception chaining mechanism.
-	 * The {@code getCause()} method is now the preferred means of
-	 * obtaining this information.
+	 * The {@code getCause()} method is now the preferred means of obtaining
+	 * this information.
 	 * 
 	 * @return The result of calling {@code getCause()}.
 	 */
@@ -199,11 +198,9 @@ public class BundleException extends Exception {
 	}
 
 	/**
-	 * Returns the cause of this exception or {@code null} if no cause was
-	 * set.
+	 * Returns the cause of this exception or {@code null} if no cause was set.
 	 * 
-	 * @return The cause of this exception or {@code null} if no cause was
-	 *         set.
+	 * @return The cause of this exception or {@code null} if no cause was set.
 	 * @since 1.3
 	 */
 	public Throwable getCause() {
@@ -226,8 +223,8 @@ public class BundleException extends Exception {
 	}
 
 	/**
-	 * Returns the type for this exception or {@code UNSPECIFIED} if the
-	 * type was unspecified or unknown.
+	 * Returns the type for this exception or {@code UNSPECIFIED} if the type
+	 * was unspecified or unknown.
 	 * 
 	 * @return The type of this exception.
 	 * @since 1.5
diff --git a/src/main/java/org/osgi/framework/BundleListener.java b/src/main/java/org/osgi/framework/BundleListener.java
index d9bb54c..8d86d30 100644
--- a/src/main/java/org/osgi/framework/BundleListener.java
+++ b/src/main/java/org/osgi/framework/BundleListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,22 +19,22 @@ package org.osgi.framework;
 import java.util.EventListener;
 
 /**
- * A {@code BundleEvent} listener. {@code BundleListener} is a
- * listener interface that may be implemented by a bundle developer. When a
+ * A {@code BundleEvent} listener. {@code BundleListener} is a listener
+ * interface that may be implemented by a bundle developer. When a
  * {@code BundleEvent} is fired, it is asynchronously delivered to a
- * {@code BundleListener}. The Framework delivers
- * {@code BundleEvent} objects to a {@code BundleListener} in
- * order and must not concurrently call a {@code BundleListener}.
+ * {@code BundleListener}. The Framework delivers {@code BundleEvent} objects to
+ * a {@code BundleListener} in order and must not concurrently call a
+ * {@code BundleListener}.
  * <p>
- * A {@code BundleListener} object is registered with the Framework using
- * the {@link BundleContext#addBundleListener} method.
- * {@code BundleListener}s are called with a {@code BundleEvent}
- * object when a bundle has been installed, resolved, started, stopped, updated,
- * unresolved, or uninstalled.
+ * A {@code BundleListener} object is registered with the Framework using the
+ * {@link BundleContext#addBundleListener(BundleListener)} method.
+ * {@code BundleListener}s are called with a {@code BundleEvent} object when a
+ * bundle has been installed, resolved, started, stopped, updated, unresolved,
+ * or uninstalled.
  * 
  * @see BundleEvent
  * @NotThreadSafe
- * @version $Id: 77cdaebd3ac97c6798fc3043957abd1bd6d01ccb $
+ * @version $Id: d48b4a8a59c839466a3d749dde23980d236f58c6 $
  */
 
 public interface BundleListener extends EventListener {
diff --git a/src/main/java/org/osgi/framework/BundlePermission.java b/src/main/java/org/osgi/framework/BundlePermission.java
index e6f9356..f9e64ae 100644
--- a/src/main/java/org/osgi/framework/BundlePermission.java
+++ b/src/main/java/org/osgi/framework/BundlePermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -52,13 +52,13 @@ import java.util.Map;
  * </pre>
  * 
  * <p>
- * {@code BundlePermission} has four actions: {@code provide},
- * {@code require},{@code host}, and {@code fragment}. The
- * {@code provide} action implies the {@code require} action.
+ * {@code BundlePermission} has four actions: {@code provide}, {@code require},
+ * {@code host}, and {@code fragment}. The {@code provide} action implies the
+ * {@code require} action.
  * 
  * @since 1.3
  * @ThreadSafe
- * @version $Id: d30c9c987cc13007ed19d3a9fdd11b00739591c0 $
+ * @version $Id: ccba905e3373800dfdb080118e97145abf778da2 $
  */
 
 public final class BundlePermission extends BasicPermission {
@@ -66,14 +66,14 @@ public final class BundlePermission extends BasicPermission {
 	private static final long	serialVersionUID	= 3257846601685873716L;
 
 	/**
-	 * The action string {@code provide}. The {@code provide} action
-	 * implies the {@code require} action.
+	 * The action string {@code provide}. The {@code provide} action implies the
+	 * {@code require} action.
 	 */
 	public final static String	PROVIDE				= "provide";
 
 	/**
-	 * The action string {@code require}. The {@code require} action
-	 * is implied by the {@code provide} action.
+	 * The action string {@code require}. The {@code require} action is implied
+	 * by the {@code provide} action.
 	 */
 	public final static String	REQUIRE				= "require";
 
@@ -91,10 +91,7 @@ public final class BundlePermission extends BasicPermission {
 	private final static int	ACTION_REQUIRE		= 0x00000002;
 	private final static int	ACTION_HOST			= 0x00000004;
 	private final static int	ACTION_FRAGMENT		= 0x00000008;
-	private final static int	ACTION_ALL			= ACTION_PROVIDE
-															| ACTION_REQUIRE
-															| ACTION_HOST
-															| ACTION_FRAGMENT;
+	private final static int	ACTION_ALL			= ACTION_PROVIDE | ACTION_REQUIRE | ACTION_HOST | ACTION_FRAGMENT;
 	final static int			ACTION_NONE			= 0;
 	/**
 	 * The actions mask.
@@ -115,14 +112,14 @@ public final class BundlePermission extends BasicPermission {
 	 * Bundle Permissions are granted over all possible versions of a bundle.
 	 * 
 	 * A bundle that needs to provide a bundle must have the appropriate
-	 * {@code BundlePermission} for the symbolic name; a bundle that
-	 * requires a bundle must have the appropriate {@code BundlePermssion}
-	 * for that symbolic name; a bundle that specifies a fragment host must have
-	 * the appropriate {@code BundlePermission} for that symbolic name.
+	 * {@code BundlePermission} for the symbolic name; a bundle that requires a
+	 * bundle must have the appropriate {@code BundlePermssion} for that
+	 * symbolic name; a bundle that specifies a fragment host must have the
+	 * appropriate {@code BundlePermission} for that symbolic name.
 	 * 
 	 * @param symbolicName The bundle symbolic name.
-	 * @param actions {@code provide},{@code require},
-	 *        {@code host},{@code fragment} (canonical order).
+	 * @param actions {@code provide},{@code require}, {@code host},
+	 *        {@code fragment} (canonical order).
 	 */
 	public BundlePermission(String symbolicName, String actions) {
 		this(symbolicName, parseActions(actions));
@@ -188,9 +185,7 @@ public final class BundlePermission extends BasicPermission {
 			char c;
 
 			// skip whitespace
-			while ((i != -1)
-					&& ((c = a[i]) == ' ' || c == '\r' || c == '\n'
-							|| c == '\f' || c == '\t'))
+			while ((i != -1) && ((c = a[i]) == ' ' || c == '\r' || c == '\n' || c == '\f' || c == '\t'))
 				i--;
 
 			// check for the known strings
@@ -205,8 +200,7 @@ public final class BundlePermission extends BasicPermission {
 					&& (a[i] == 'e' || a[i] == 'E')) {
 				matchlen = 7;
 				mask |= ACTION_PROVIDE | ACTION_REQUIRE;
-			}
-			else
+			} else
 				if (i >= 6 && (a[i - 6] == 'r' || a[i - 6] == 'R')
 						&& (a[i - 5] == 'e' || a[i - 5] == 'E')
 						&& (a[i - 4] == 'q' || a[i - 4] == 'Q')
@@ -216,16 +210,14 @@ public final class BundlePermission extends BasicPermission {
 						&& (a[i] == 'e' || a[i] == 'E')) {
 					matchlen = 7;
 					mask |= ACTION_REQUIRE;
-				}
-				else
+				} else
 					if (i >= 3 && (a[i - 3] == 'h' || a[i - 3] == 'H')
 							&& (a[i - 2] == 'o' || a[i - 2] == 'O')
 							&& (a[i - 1] == 's' || a[i - 1] == 'S')
 							&& (a[i] == 't' || a[i] == 'T')) {
 						matchlen = 4;
 						mask |= ACTION_HOST;
-					}
-					else
+					} else
 						if (i >= 7 && (a[i - 7] == 'f' || a[i - 7] == 'F')
 								&& (a[i - 6] == 'r' || a[i - 6] == 'R')
 								&& (a[i - 5] == 'a' || a[i - 5] == 'A')
@@ -236,11 +228,9 @@ public final class BundlePermission extends BasicPermission {
 								&& (a[i] == 't' || a[i] == 'T')) {
 							matchlen = 8;
 							mask |= ACTION_FRAGMENT;
-						}
-						else {
+						} else {
 							// parse error
-							throw new IllegalArgumentException(
-									"invalid permission: " + actions);
+							throw new IllegalArgumentException("invalid permission: " + actions);
 						}
 
 			// make sure we didn't just match the tail of a word
@@ -258,8 +248,7 @@ public final class BundlePermission extends BasicPermission {
 					case '\t' :
 						break;
 					default :
-						throw new IllegalArgumentException(
-								"invalid permission: " + actions);
+						throw new IllegalArgumentException("invalid permission: " + actions);
 				}
 				i--;
 			}
@@ -295,8 +284,8 @@ public final class BundlePermission extends BasicPermission {
 	 * </pre>
 	 * 
 	 * @param p The requested permission.
-	 * @return {@code true} if the specified {@code BundlePermission}
-	 *         action is implied by this object; {@code false} otherwise.
+	 * @return {@code true} if the specified {@code BundlePermission} action is
+	 *         implied by this object; {@code false} otherwise.
 	 */
 	public boolean implies(Permission p) {
 		if (!(p instanceof BundlePermission)) {
@@ -306,8 +295,7 @@ public final class BundlePermission extends BasicPermission {
 
 		final int effective = getActionsMask();
 		final int desired = requested.getActionsMask();
-		return ((effective & desired) == desired)
-				&& super.implies(requested);
+		return ((effective & desired) == desired) && super.implies(requested);
 	}
 
 	/**
@@ -315,9 +303,8 @@ public final class BundlePermission extends BasicPermission {
 	 * {@code BundlePermission} actions.
 	 * 
 	 * <p>
-	 * Always returns present {@code BundlePermission} actions in the
-	 * following order: {@code provide}, {@code require},
-	 * {@code host}, {@code fragment}.
+	 * Always returns present {@code BundlePermission} actions in the following
+	 * order: {@code provide}, {@code require}, {@code host}, {@code fragment}.
 	 * 
 	 * @return Canonical string representation of the {@code BundlePermission
 	 *         } actions.
@@ -359,8 +346,8 @@ public final class BundlePermission extends BasicPermission {
 	}
 
 	/**
-	 * Returns a new {@code PermissionCollection} object suitable for
-	 * storing {@code BundlePermission} objects.
+	 * Returns a new {@code PermissionCollection} object suitable for storing
+	 * {@code BundlePermission} objects.
 	 * 
 	 * @return A new {@code PermissionCollection} object.
 	 */
@@ -377,10 +364,9 @@ public final class BundlePermission extends BasicPermission {
 	 * 
 	 * @param obj The object to test for equality with this
 	 *        {@code BundlePermission} object.
-	 * @return {@code true} if {@code obj} is a
-	 *         {@code BundlePermission}, and has the same bundle symbolic
-	 *         name and actions as this {@code BundlePermission} object;
-	 *         {@code false} otherwise.
+	 * @return {@code true} if {@code obj} is a {@code BundlePermission}, and
+	 *         has the same bundle symbolic name and actions as this
+	 *         {@code BundlePermission} object; {@code false} otherwise.
 	 */
 	public boolean equals(Object obj) {
 		if (obj == this) {
@@ -393,8 +379,7 @@ public final class BundlePermission extends BasicPermission {
 
 		BundlePermission bp = (BundlePermission) obj;
 
-		return (getActionsMask() == bp.getActionsMask())
-				&& getName().equals(bp.getName());
+		return (getActionsMask() == bp.getActionsMask()) && getName().equals(bp.getName());
 	}
 
 	/**
@@ -409,12 +394,11 @@ public final class BundlePermission extends BasicPermission {
 	}
 
 	/**
-	 * WriteObject is called to save the state of the
-	 * {@code BundlePermission} object to a stream. The actions are
-	 * serialized, and the superclass takes care of the name.
+	 * WriteObject is called to save the state of the {@code BundlePermission}
+	 * object to a stream. The actions are serialized, and the superclass takes
+	 * care of the name.
 	 */
-	private synchronized void writeObject(java.io.ObjectOutputStream s)
-			throws IOException {
+	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
 		// Write out the actions. The superclass takes care of the name
 		// call getActions to make sure actions field is initialized
 		if (actions == null)
@@ -426,8 +410,7 @@ public final class BundlePermission extends BasicPermission {
 	 * readObject is called to restore the state of the BundlePermission from a
 	 * stream.
 	 */
-	private synchronized void readObject(java.io.ObjectInputStream s)
-			throws IOException, ClassNotFoundException {
+	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
 		// Read in the action, then initialize the rest
 		s.defaultReadObject();
 		setTransients(parseActions(actions));
@@ -443,7 +426,7 @@ public final class BundlePermission extends BasicPermission {
  */
 
 final class BundlePermissionCollection extends PermissionCollection {
-	private static final long	serialVersionUID	= 3258407326846433079L;
+	private static final long						serialVersionUID	= 3258407326846433079L;
 
 	/**
 	 * Table of permissions.
@@ -458,7 +441,7 @@ final class BundlePermissionCollection extends PermissionCollection {
 	 * @serial
 	 * @GuardedBy this
 	 */
-	private boolean				all_allowed;
+	private boolean									all_allowed;
 
 	/**
 	 * Create an empty BundlePermissions object.
@@ -480,12 +463,10 @@ final class BundlePermissionCollection extends PermissionCollection {
 	 */
 	public void add(final Permission permission) {
 		if (!(permission instanceof BundlePermission)) {
-			throw new IllegalArgumentException("invalid permission: "
-					+ permission);
+			throw new IllegalArgumentException("invalid permission: " + permission);
 		}
 		if (isReadOnly()) {
-			throw new SecurityException("attempt to add a Permission to a "
-					+ "readonly PermissionCollection");
+			throw new SecurityException("attempt to add a Permission to a " + "readonly PermissionCollection");
 		}
 		final BundlePermission bp = (BundlePermission) permission;
 		final String name = bp.getName();
@@ -496,12 +477,10 @@ final class BundlePermissionCollection extends PermissionCollection {
 				final int oldMask = existing.getActionsMask();
 				final int newMask = bp.getActionsMask();
 				if (oldMask != newMask) {
-					pc.put(name, new BundlePermission(name, oldMask
-							| newMask));
+					pc.put(name, new BundlePermission(name, oldMask | newMask));
 
 				}
-			}
-			else {
+			} else {
 				pc.put(name, bp);
 			}
 
@@ -518,8 +497,8 @@ final class BundlePermissionCollection extends PermissionCollection {
 	 * 
 	 * @param permission The Permission object to compare with this
 	 *        {@code BundlePermission} object.
-	 * @return {@code true} if {@code permission} is a proper subset
-	 *         of a permission in the set; {@code false} otherwise.
+	 * @return {@code true} if {@code permission} is a proper subset of a
+	 *         permission in the set; {@code false} otherwise.
 	 */
 	public boolean implies(final Permission permission) {
 		if (!(permission instanceof BundlePermission)) {
@@ -575,8 +554,8 @@ final class BundlePermissionCollection extends PermissionCollection {
 	}
 
 	/**
-	 * Returns an enumeration of all {@code BundlePermission} objects in
-	 * the container.
+	 * Returns an enumeration of all {@code BundlePermission} objects in the
+	 * container.
 	 * 
 	 * @return Enumeration of all {@code BundlePermission} objects.
 	 */
@@ -584,27 +563,21 @@ final class BundlePermissionCollection extends PermissionCollection {
 		List<Permission> all = new ArrayList<Permission>(permissions.values());
 		return Collections.enumeration(all);
 	}
-	
+
 	/* serialization logic */
-	private static final ObjectStreamField[]	serialPersistentFields	= {
-			new ObjectStreamField("permissions", Hashtable.class),
-			new ObjectStreamField("all_allowed", Boolean.TYPE)			};
-
-	private synchronized void writeObject(ObjectOutputStream out)
-			throws IOException {
-		Hashtable<String, BundlePermission> hashtable = new Hashtable<String, BundlePermission>(
-				permissions);
+	private static final ObjectStreamField[]	serialPersistentFields	= {new ObjectStreamField("permissions", Hashtable.class), new ObjectStreamField("all_allowed", Boolean.TYPE)};
+
+	private synchronized void writeObject(ObjectOutputStream out) throws IOException {
+		Hashtable<String, BundlePermission> hashtable = new Hashtable<String, BundlePermission>(permissions);
 		ObjectOutputStream.PutField pfields = out.putFields();
 		pfields.put("permissions", hashtable);
 		pfields.put("all_allowed", all_allowed);
 		out.writeFields();
 	}
 
-	private synchronized void readObject(java.io.ObjectInputStream in)
-			throws IOException, ClassNotFoundException {
+	private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
 		ObjectInputStream.GetField gfields = in.readFields();
-		Hashtable<String, BundlePermission> hashtable = (Hashtable<String, BundlePermission>) gfields
-				.get("permissions", null);
+		Hashtable<String, BundlePermission> hashtable = (Hashtable<String, BundlePermission>) gfields.get("permissions", null);
 		permissions = new HashMap<String, BundlePermission>(hashtable);
 		all_allowed = gfields.get("all_allowed", false);
 	}
diff --git a/src/main/java/org/osgi/framework/CapabilityPermission.java b/src/main/java/org/osgi/framework/CapabilityPermission.java
index bcac790..c27e1ac 100644
--- a/src/main/java/org/osgi/framework/CapabilityPermission.java
+++ b/src/main/java/org/osgi/framework/CapabilityPermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -47,7 +47,7 @@ import java.util.Set;
  * </ul>
  * 
  * @ThreadSafe
- * @version $Id: bab1ac06b46613f6cff39b291295d8b3e51d58ce $
+ * @version $Id: b17bcaec959f67c3eae4c4c80c39a0a8716b22dc $
  * @since 1.6
  */
 
@@ -64,8 +64,7 @@ public final class CapabilityPermission extends BasicPermission {
 
 	private final static int						ACTION_REQUIRE		= 0x00000001;
 	private final static int						ACTION_PROVIDE		= 0x00000002;
-	private final static int						ACTION_ALL			= ACTION_REQUIRE
-																				| ACTION_PROVIDE;
+	private final static int						ACTION_ALL			= ACTION_REQUIRE | ACTION_PROVIDE;
 	final static int								ACTION_NONE			= 0;
 
 	/**
@@ -133,7 +132,7 @@ public final class CapabilityPermission extends BasicPermission {
 	 * <li>location - The location of the bundle providing the capability.</li>
 	 * <li>id - The bundle ID of the bundle providing the capability.</li>
 	 * <li>name - The symbolic name of the bundle providing the capability.</li>
-	 * <li>capability.namespace - The name space of the required capability.</li>
+	 * <li>capability.namespace - The namespace of the required capability.</li>
 	 * </ul>
 	 * Since the above attribute names may conflict with attribute names of a
 	 * capability, you can prefix an attribute name with '@' in the filter
@@ -146,9 +145,9 @@ public final class CapabilityPermission extends BasicPermission {
 	 * {@code require} permission allows the owner of this permission to require
 	 * a capability matching the attributes. The {@code provide} permission
 	 * allows the bundle to provide a capability in the specified capability
-	 * name space.
+	 * namespace.
 	 * 
-	 * @param name The capability name space or a filter over the attributes.
+	 * @param name The capability namespace or a filter over the attributes.
 	 * @param actions {@code require},{@code provide} (canonical order)
 	 * @throws IllegalArgumentException If the specified name is a filter
 	 *         expression and either the specified action is not {@code require}
@@ -156,10 +155,8 @@ public final class CapabilityPermission extends BasicPermission {
 	 */
 	public CapabilityPermission(String name, String actions) {
 		this(name, parseActions(actions));
-		if ((this.filter != null)
-				&& ((action_mask & ACTION_ALL) != ACTION_REQUIRE)) {
-			throw new IllegalArgumentException(
-					"invalid action string for filter expression");
+		if ((this.filter != null) && ((action_mask & ACTION_ALL) != ACTION_REQUIRE)) {
+			throw new IllegalArgumentException("invalid action string for filter expression");
 		}
 	}
 
@@ -170,7 +167,7 @@ public final class CapabilityPermission extends BasicPermission {
 	 * constructor cannot be added to a {@code CapabilityPermission} permission
 	 * collection.
 	 * 
-	 * @param namespace The requested capability name space.
+	 * @param namespace The requested capability namespace.
 	 * @param attributes The requested capability attributes.
 	 * @param providingBundle The bundle providing the requested capability.
 	 * @param actions The action {@code require}.
@@ -178,8 +175,7 @@ public final class CapabilityPermission extends BasicPermission {
 	 *         {@code require} or attributes or providingBundle are {@code null}
 	 *         .
 	 */
-	public CapabilityPermission(String namespace, Map<String, ? > attributes,
-			Bundle providingBundle, String actions) {
+	public CapabilityPermission(String namespace, Map<String, ?> attributes, Bundle providingBundle, String actions) {
 		super(namespace);
 		setTransients(namespace, parseActions(actions));
 		if (attributes == null) {
@@ -246,9 +242,7 @@ public final class CapabilityPermission extends BasicPermission {
 			char c;
 
 			// skip whitespace
-			while ((i != -1)
-					&& ((c = a[i]) == ' ' || c == '\r' || c == '\n'
-							|| c == '\f' || c == '\t'))
+			while ((i != -1) && ((c = a[i]) == ' ' || c == '\r' || c == '\n' || c == '\f' || c == '\t'))
 				i--;
 
 			// check for the known strings
@@ -263,8 +257,7 @@ public final class CapabilityPermission extends BasicPermission {
 					&& (a[i] == 'e' || a[i] == 'E')) {
 				matchlen = 7;
 				mask |= ACTION_REQUIRE;
-			}
-			else
+			} else
 				if (i >= 6 && (a[i - 6] == 'p' || a[i - 6] == 'P')
 						&& (a[i - 5] == 'r' || a[i - 5] == 'R')
 						&& (a[i - 4] == 'o' || a[i - 4] == 'O')
@@ -274,11 +267,9 @@ public final class CapabilityPermission extends BasicPermission {
 						&& (a[i] == 'e' || a[i] == 'E')) {
 					matchlen = 7;
 					mask |= ACTION_PROVIDE;
-				}
-				else {
+				} else {
 					// parse error
-					throw new IllegalArgumentException("invalid permission: "
-							+ actions);
+					throw new IllegalArgumentException("invalid permission: " + actions);
 				}
 
 			// make sure we didn't just match the tail of a word
@@ -296,8 +287,7 @@ public final class CapabilityPermission extends BasicPermission {
 					case '\t' :
 						break;
 					default :
-						throw new IllegalArgumentException(
-								"invalid permission: " + actions);
+						throw new IllegalArgumentException("invalid permission: " + actions);
 				}
 				i--;
 			}
@@ -329,10 +319,8 @@ public final class CapabilityPermission extends BasicPermission {
 
 		try {
 			return FrameworkUtil.createFilter(filterString);
-		}
-		catch (InvalidSyntaxException e) {
-			IllegalArgumentException iae = new IllegalArgumentException(
-					"invalid filter");
+		} catch (InvalidSyntaxException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid filter");
 			iae.initCause(e);
 			throw iae;
 		}
@@ -451,12 +439,8 @@ public final class CapabilityPermission extends BasicPermission {
 
 		CapabilityPermission cp = (CapabilityPermission) obj;
 
-		return (action_mask == cp.action_mask)
-				&& getName().equals(cp.getName())
-				&& ((attributes == cp.attributes) || ((attributes != null) && (attributes
-						.equals(cp.attributes))))
-				&& ((bundle == cp.bundle) || ((bundle != null) && bundle
-						.equals(cp.bundle)));
+		return (action_mask == cp.action_mask) && getName().equals(cp.getName()) && ((attributes == cp.attributes) || ((attributes != null) && (attributes.equals(cp.attributes))))
+				&& ((bundle == cp.bundle) || ((bundle != null) && bundle.equals(cp.bundle)));
 	}
 
 	/**
@@ -480,8 +464,7 @@ public final class CapabilityPermission extends BasicPermission {
 	 * WriteObject is called to save the state of this permission to a stream.
 	 * The actions are serialized, and the superclass takes care of the name.
 	 */
-	private synchronized void writeObject(java.io.ObjectOutputStream s)
-			throws IOException {
+	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
 		if (bundle != null) {
 			throw new NotSerializableException("cannot serialize");
 		}
@@ -496,8 +479,7 @@ public final class CapabilityPermission extends BasicPermission {
 	 * readObject is called to restore the state of this permission from a
 	 * stream.
 	 */
-	private synchronized void readObject(java.io.ObjectInputStream s)
-			throws IOException, ClassNotFoundException {
+	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
 		// Read in the action, then initialize the rest
 		s.defaultReadObject();
 		setTransients(getName(), parseActions(actions));
@@ -543,8 +525,7 @@ public final class CapabilityPermission extends BasicPermission {
 		private final Map<String, Object>							attributes;
 		private transient volatile Set<Map.Entry<String, Object>>	entries;
 
-		Properties(Map<String, Object> properties,
-				Map<String, Object> attributes) {
+		Properties(Map<String, Object> properties, Map<String, Object> attributes) {
 			this.properties = properties;
 			this.attributes = attributes;
 			entries = null;
@@ -569,8 +550,7 @@ public final class CapabilityPermission extends BasicPermission {
 			if (entries != null) {
 				return entries;
 			}
-			Set<Map.Entry<String, Object>> all = new HashSet<Map.Entry<String, Object>>(
-					attributes.size() + properties.size());
+			Set<Map.Entry<String, Object>> all = new HashSet<Map.Entry<String, Object>>(attributes.size() + properties.size());
 			all.addAll(attributes.entrySet());
 			all.addAll(properties.entrySet());
 			return entries = Collections.unmodifiableSet(all);
@@ -631,18 +611,15 @@ final class CapabilityPermissionCollection extends PermissionCollection {
 	 */
 	public void add(final Permission permission) {
 		if (!(permission instanceof CapabilityPermission)) {
-			throw new IllegalArgumentException("invalid permission: "
-					+ permission);
+			throw new IllegalArgumentException("invalid permission: " + permission);
 		}
 		if (isReadOnly()) {
-			throw new SecurityException("attempt to add a Permission to a "
-					+ "readonly PermissionCollection");
+			throw new SecurityException("attempt to add a Permission to a " + "readonly PermissionCollection");
 		}
 
 		final CapabilityPermission cp = (CapabilityPermission) permission;
 		if (cp.bundle != null) {
-			throw new IllegalArgumentException("cannot add to collection: "
-					+ cp);
+			throw new IllegalArgumentException("cannot add to collection: " + cp);
 		}
 
 		final String name = cp.getName();
@@ -655,8 +632,7 @@ final class CapabilityPermissionCollection extends PermissionCollection {
 				if (pc == null) {
 					filterPermissions = pc = new HashMap<String, CapabilityPermission>();
 				}
-			}
-			else {
+			} else {
 				pc = permissions;
 			}
 			final CapabilityPermission existing = pc.get(name);
@@ -665,11 +641,9 @@ final class CapabilityPermissionCollection extends PermissionCollection {
 				final int oldMask = existing.action_mask;
 				final int newMask = cp.action_mask;
 				if (oldMask != newMask) {
-					pc.put(name, new CapabilityPermission(name, oldMask
-							| newMask));
+					pc.put(name, new CapabilityPermission(name, oldMask | newMask));
 				}
-			}
-			else {
+			} else {
 				pc.put(name, cp);
 			}
 
@@ -779,13 +753,10 @@ final class CapabilityPermissionCollection extends PermissionCollection {
 	}
 
 	/* serialization logic */
-	private static final ObjectStreamField[]	serialPersistentFields	= {
-			new ObjectStreamField("permissions", HashMap.class),
-			new ObjectStreamField("all_allowed", Boolean.TYPE),
+	private static final ObjectStreamField[]	serialPersistentFields	= {new ObjectStreamField("permissions", HashMap.class), new ObjectStreamField("all_allowed", Boolean.TYPE),
 			new ObjectStreamField("filterPermissions", HashMap.class)	};
 
-	private synchronized void writeObject(ObjectOutputStream out)
-			throws IOException {
+	private synchronized void writeObject(ObjectOutputStream out) throws IOException {
 		ObjectOutputStream.PutField pfields = out.putFields();
 		pfields.put("permissions", permissions);
 		pfields.put("all_allowed", all_allowed);
@@ -793,15 +764,12 @@ final class CapabilityPermissionCollection extends PermissionCollection {
 		out.writeFields();
 	}
 
-	private synchronized void readObject(java.io.ObjectInputStream in)
-			throws IOException, ClassNotFoundException {
+	private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
 		ObjectInputStream.GetField gfields = in.readFields();
-		HashMap<String, CapabilityPermission> p = (HashMap<String, CapabilityPermission>) gfields
-				.get("permissions", null);
+		HashMap<String, CapabilityPermission> p = (HashMap<String, CapabilityPermission>) gfields.get("permissions", null);
 		permissions = p;
 		all_allowed = gfields.get("all_allowed", false);
-		HashMap<String, CapabilityPermission> fp = (HashMap<String, CapabilityPermission>) gfields
-				.get("filterPermissions", null);
+		HashMap<String, CapabilityPermission> fp = (HashMap<String, CapabilityPermission>) gfields.get("filterPermissions", null);
 		filterPermissions = fp;
 	}
 }
diff --git a/src/main/java/org/osgi/framework/Configurable.java b/src/main/java/org/osgi/framework/Configurable.java
index d82da9b..5fa08c4 100644
--- a/src/main/java/org/osgi/framework/Configurable.java
+++ b/src/main/java/org/osgi/framework/Configurable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ package org.osgi.framework;
  * {@code instanceof Configurable}.
  * 
  * @deprecated As of 1.2. Please use Configuration Admin service.
- * @version $Id: 29705c0c238aa456cda1b1a13458079bf1542771 $
+ * @version $Id: 1018601ae90d2d16ec34136db4b04dca3ccf8e65 $
  */
 public interface Configurable {
 	/**
@@ -42,9 +42,8 @@ public interface Configurable {
 	 * returning the configuration object.
 	 * 
 	 * @return The configuration object for this service.
-	 * @throws SecurityException If the caller does not have an
-	 *         appropriate permission and the Java Runtime Environment supports
-	 *         permissions.
+	 * @throws SecurityException If the caller does not have an appropriate
+	 *         permission and the Java Runtime Environment supports permissions.
 	 * @deprecated As of 1.2. Please use Configuration Admin service.
 	 */
 	public Object getConfigurationObject();
diff --git a/src/main/java/org/osgi/framework/Constants.java b/src/main/java/org/osgi/framework/Constants.java
index b71a12d..10618a1 100644
--- a/src/main/java/org/osgi/framework/Constants.java
+++ b/src/main/java/org/osgi/framework/Constants.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
 
 package org.osgi.framework;
 
+import org.osgi.framework.hooks.bundle.CollisionHook;
 import org.osgi.framework.launch.Framework;
 
 /**
@@ -28,7 +29,7 @@ import org.osgi.framework.launch.Framework;
  * 
  * @since 1.1
  * @noimplement
- * @version $Id: 517c954ed7d34d2ee762933466f69fa03db7cd37 $
+ * @version $Id: 6d07a4c3e29a5cd93b3daf0f9fcdab5472b357f6 $
  */
 
 public interface Constants {
@@ -1149,8 +1150,9 @@ public interface Constants {
 	/**
 	 * Framework launching property specifying the trust repositories used by
 	 * the framework. The value is a {@code java.io.File.pathSeparator}
-	 * separated list of valid file paths to files that contain key stores of
-	 * type {@code JKS}. The framework will use the key stores as trust
+	 * separated list of valid file paths to files that contain key stores. Key
+	 * stores of type {@code JKS} must be supported and other key store types
+	 * may be supported. The framework will use the key stores as trust
 	 * repositories to authenticate certificates of trusted signers. The key
 	 * stores are only used as read-only trust repositories to access public
 	 * keys. No passwords are required to access the key stores' public keys.
@@ -1276,9 +1278,9 @@ public interface Constants {
 	 * persists across multiple Framework invocations.
 	 * 
 	 * <p>
-	 * By convention, every bundle has its own unique name space, starting with
-	 * the bundle's identifier (see {@link Bundle#getBundleId}) and followed by
-	 * a dot (.). A bundle may use this as the prefix of the persistent
+	 * By convention, every bundle has its own unique namespace, starting with
+	 * the bundle's identifier (see {@link Bundle#getBundleId()}) and followed
+	 * by a dot (.). A bundle may use this as the prefix of the persistent
 	 * identifiers for the services it registers.
 	 */
 	String	SERVICE_PID								= "service.pid";
@@ -1293,9 +1295,10 @@ public interface Constants {
 	 * 
 	 * <p>
 	 * The service ranking is used by the Framework to determine the <i>natural
-	 * order</i> of services, see {@link ServiceReference#compareTo}, and the
-	 * <i>default</i> service to be returned from a call to the
-	 * {@link BundleContext#getServiceReference} method.
+	 * order</i> of services, see {@link ServiceReference#compareTo(Object)},
+	 * and the <i>default</i> service to be returned from a call to the
+	 * {@link BundleContext#getServiceReference(Class)} or
+	 * {@link BundleContext#getServiceReference(String)} method.
 	 * 
 	 * <p>
 	 * The default ranking is zero (0). A service with a ranking of
@@ -1434,11 +1437,11 @@ public interface Constants {
 	 * Service property marking the service for export. It defines the
 	 * interfaces under which this service can be exported. This list must be a
 	 * subset of the types under which the service was registered. The single
-	 * value of an asterisk ("*", \u002A) indicates all the
-	 * interface types under which the service was registered excluding the
-	 * non-interface types. It is strongly recommended to only export interface
-	 * types and not concrete classes due to the complexity of creating proxies
-	 * for some type of concrete classes.
+	 * value of an asterisk ({@code '*'} \u002A) indicates all the interface
+	 * types under which the service was registered excluding the non-interface
+	 * types. It is strongly recommended to only export interface types and not
+	 * concrete classes due to the complexity of creating proxies for some type
+	 * of concrete classes.
 	 * 
 	 * <p>
 	 * This property may be supplied in the {@code properties}
@@ -1645,12 +1648,11 @@ public interface Constants {
 	 * {@link #BUNDLE_VERSION version} may be installed.
 	 * 
 	 * <p>
-	 * Default value is {@link #FRAMEWORK_BSNVERSION_SINGLE single} in this
-	 * release of the specification. This default may change to
-	 * {@link #FRAMEWORK_BSNVERSION_MULTIPLE multiple} in a future specification
-	 * release. Therefore, code must not assume the default behavior is
-	 * {@code single} and should interrogate the value of this property to
-	 * determine the behavior.
+	 * Default value is {@link #FRAMEWORK_BSNVERSION_MANAGED managed} in this
+	 * release of the specification. This default may change in a future
+	 * specification release. Therefore, code must not assume the default
+	 * behavior is {@code managed} and should interrogate the value of this
+	 * property to determine the behavior.
 	 * 
 	 * <p>
 	 * The value of this property may be retrieved by calling the
@@ -1658,6 +1660,7 @@ public interface Constants {
 	 * 
 	 * @see #FRAMEWORK_BSNVERSION_MULTIPLE
 	 * @see #FRAMEWORK_BSNVERSION_SINGLE
+	 * @see #FRAMEWORK_BSNVERSION_MANAGED
 	 * @since 1.6
 	 */
 	String	FRAMEWORK_BSNVERSION					= "org.osgi.framework.bsnversion";
@@ -1679,6 +1682,22 @@ public interface Constants {
 	 * 
 	 * @since 1.6
 	 * @see #FRAMEWORK_BSNVERSION
+	 * @see BundleException#DUPLICATE_BUNDLE_ERROR
 	 */
 	String	FRAMEWORK_BSNVERSION_SINGLE				= "single";
+
+	/**
+	 * Specifies the framework must consult the {@link CollisionHook bundle
+	 * collision hook} services to determine if it will be an error to install a
+	 * bundle or update a bundle to have the same symbolic name and version as
+	 * another installed bundle. If no bundle collision hook services are
+	 * registered, then it will be an error to install a bundle or update a
+	 * bundle to have the same symbolic name and version as another installed
+	 * bundle.
+	 * 
+	 * @since 1.7
+	 * @see #FRAMEWORK_BSNVERSION
+	 * @see BundleException#DUPLICATE_BUNDLE_ERROR
+	 */
+	String	FRAMEWORK_BSNVERSION_MANAGED			= "managed";
 }
diff --git a/src/main/java/org/osgi/framework/Filter.java b/src/main/java/org/osgi/framework/Filter.java
index a9bb6c3..230a6e9 100644
--- a/src/main/java/org/osgi/framework/Filter.java
+++ b/src/main/java/org/osgi/framework/Filter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.osgi.framework;
 
 import java.util.Dictionary;
@@ -21,8 +22,9 @@ import java.util.Map;
 /**
  * An <a href="http://www.ietf.org/rfc/rfc1960.txt">RFC 1960</a>-based Filter.
  * <p>
- * {@code Filter}s can be created by calling {@link BundleContext#createFilter}
- * or {@link FrameworkUtil#createFilter} with a filter string.
+ * {@code Filter}s can be created by calling
+ * {@link BundleContext#createFilter(String)} or
+ * {@link FrameworkUtil#createFilter(String)} with a filter string.
  * <p>
  * A {@code Filter} can be used numerous times to determine if the match
  * argument matches the filter string that was used to create the {@code Filter}.
@@ -40,7 +42,7 @@ import java.util.Map;
  * @see "Core Specification, Filters, for a description of the filter string syntax."
  * @ThreadSafe
  * @noimplement
- * @version $Id: 4d21267f4b85d1912d73f7e2c049cc968c4237f9 $
+ * @version $Id: 807a04ac07c3230b8f4d4e0f9588a35fbdc41e18 $
  */
 public interface Filter {
 	/**
@@ -55,7 +57,7 @@ public interface Filter {
 	 * @return {@code true} if the service's properties match this
 	 *         {@code Filter}; {@code false} otherwise.
 	 */
-	boolean match(ServiceReference< ? > reference);
+	boolean match(ServiceReference<?> reference);
 
 	/**
 	 * Filter using a {@code Dictionary} with case insensitive key lookup. This
@@ -69,7 +71,7 @@ public interface Filter {
 	 * @throws IllegalArgumentException If {@code dictionary} contains case
 	 *         variants of the same key name.
 	 */
-	boolean match(Dictionary<String, ? > dictionary);
+	boolean match(Dictionary<String, ?> dictionary);
 
 	/**
 	 * Returns this {@code Filter}'s filter string.
@@ -89,9 +91,8 @@ public interface Filter {
 	 * {@code this.toString().equals(obj.toString())}.
 	 * 
 	 * @param obj The object to compare against this {@code Filter}.
-	 * @return If the other object is a {@code Filter} object, then returns
-	 *         the result of calling
-	 *         {@code this.toString().equals(obj.toString())};
+	 * @return If the other object is a {@code Filter} object, then returns the
+	 *         result of calling {@code this.toString().equals(obj.toString())};
 	 *         {@code false} otherwise.
 	 */
 	boolean equals(Object obj);
@@ -118,7 +119,7 @@ public interface Filter {
 	 *         filter; {@code false} otherwise.
 	 * @since 1.3
 	 */
-	boolean matchCase(Dictionary<String, ? > dictionary);
+	boolean matchCase(Dictionary<String, ?> dictionary);
 
 	/**
 	 * Filter using a {@code Map}. This {@code Filter} is executed using the
@@ -132,5 +133,5 @@ public interface Filter {
 	 *         {@code false} otherwise.
 	 * @since 1.6
 	 */
-	boolean matches(Map<String, ? > map);
+	boolean matches(Map<String, ?> map);
 }
diff --git a/src/main/java/org/osgi/framework/FrameworkEvent.java b/src/main/java/org/osgi/framework/FrameworkEvent.java
index d309699..59fa92e 100644
--- a/src/main/java/org/osgi/framework/FrameworkEvent.java
+++ b/src/main/java/org/osgi/framework/FrameworkEvent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
 package org.osgi.framework;
 
 import java.util.EventObject;
-
 import org.osgi.framework.startlevel.FrameworkStartLevel;
 import org.osgi.framework.wiring.FrameworkWiring;
 
@@ -25,17 +24,16 @@ import org.osgi.framework.wiring.FrameworkWiring;
  * A general event from the Framework.
  * 
  * <p>
- * {@code FrameworkEvent} objects are delivered to
- * {@code FrameworkListener}s when a general event occurs within the OSGi
- * environment. A type code is used to identify the event type for future
- * extendability.
+ * {@code FrameworkEvent} objects are delivered to {@code FrameworkListener}s
+ * when a general event occurs within the OSGi environment. A type code is used
+ * to identify the event type for future extendability.
  * 
  * <p>
  * OSGi Alliance reserves the right to extend the set of event types.
  * 
  * @Immutable
  * @see FrameworkListener
- * @version $Id: e05c6ffd542fa432835961882bf6b15b0620ffb6 $
+ * @version $Id: f679c7581879a2e6006ecdd317a5dd5f735764e3 $
  */
 
 public class FrameworkEvent extends EventObject {
@@ -191,8 +189,8 @@ public class FrameworkEvent extends EventObject {
 	 * 
 	 * @param type The event type.
 	 * @param bundle The event source.
-	 * @param throwable The related exception. This argument may be
-	 *        {@code null} if there is no related exception.
+	 * @param throwable The related exception. This argument may be {@code null}
+	 *        if there is no related exception.
 	 */
 	public FrameworkEvent(int type, Bundle bundle, Throwable throwable) {
 		super(bundle);
diff --git a/src/main/java/org/osgi/framework/FrameworkListener.java b/src/main/java/org/osgi/framework/FrameworkListener.java
index 5d73fb9..7e1e813 100644
--- a/src/main/java/org/osgi/framework/FrameworkListener.java
+++ b/src/main/java/org/osgi/framework/FrameworkListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,23 +19,22 @@ package org.osgi.framework;
 import java.util.EventListener;
 
 /**
- * A {@code FrameworkEvent} listener. {@code FrameworkListener} is
- * a listener interface that may be implemented by a bundle developer. When a
+ * A {@code FrameworkEvent} listener. {@code FrameworkListener} is a listener
+ * interface that may be implemented by a bundle developer. When a
  * {@code FrameworkEvent} is fired, it is asynchronously delivered to a
- * {@code FrameworkListener}. The Framework delivers
- * {@code FrameworkEvent} objects to a {@code FrameworkListener}
- * in order and must not concurrently call a {@code FrameworkListener}.
+ * {@code FrameworkListener}. The Framework delivers {@code FrameworkEvent}
+ * objects to a {@code FrameworkListener} in order and must not concurrently
+ * call a {@code FrameworkListener}.
  * 
  * <p>
- * A {@code FrameworkListener} object is registered with the Framework
- * using the {@link BundleContext#addFrameworkListener} method.
- * {@code FrameworkListener} objects are called with a
- * {@code FrameworkEvent} objects when the Framework starts and when
- * asynchronous errors occur.
+ * A {@code FrameworkListener} object is registered with the Framework using the
+ * {@link BundleContext#addFrameworkListener(FrameworkListener)} method.
+ * {@code FrameworkListener} objects are called with a {@code FrameworkEvent}
+ * objects when the Framework starts and when asynchronous errors occur.
  * 
  * @see FrameworkEvent
  * @NotThreadSafe
- * @version $Id: a32e7599ea09d3510759d77e824cb8d9eff67f9d $
+ * @version $Id: ad7f563bd13b60e2b8a378f147057ca7f0accae2 $
  */
 
 public interface FrameworkListener extends EventListener {
diff --git a/src/main/java/org/osgi/framework/FrameworkUtil.java b/src/main/java/org/osgi/framework/FrameworkUtil.java
index ec0af1e..c26ba43 100644
--- a/src/main/java/org/osgi/framework/FrameworkUtil.java
+++ b/src/main/java/org/osgi/framework/FrameworkUtil.java
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) OSGi Alliance (2005, 2010). All Rights Reserved.
- * 
+ * Copyright (c) OSGi Alliance (2005, 2012). All Rights Reserved.
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
@@ -14,201 +14,1658 @@
  * limitations under the License.
  */
 
-package org.osgi.framework;
+package org.osgi.framework;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.security.auth.x500.X500Principal;
+
+/**
+ * Framework Utility class.
+ * 
+ * <p>
+ * This class contains utility methods which access Framework functions that may
+ * be useful to bundles.
+ * 
+ * @since 1.3
+ * @ThreadSafe
+ * @version $Id: 1f46ea2bbbe2a1242fdaf0877709fb9c02eefae1 $
+ */
+public class FrameworkUtil {
+	/**
+	 * FrameworkUtil objects may not be constructed.
+	 */
+	private FrameworkUtil() {
+		// private empty constructor to prevent construction
+	}
+
+	/**
+	 * Creates a {@code Filter} object. This {@code Filter} object may be used
+	 * to match a {@code ServiceReference} object or a {@code Dictionary}
+	 * object.
+	 * 
+	 * <p>
+	 * If the filter cannot be parsed, an {@link InvalidSyntaxException} will be
+	 * thrown with a human readable message where the filter became unparsable.
+	 * 
+	 * <p>
+	 * This method returns a Filter implementation which may not perform as well
+	 * as the framework implementation-specific Filter implementation returned
+	 * by {@link BundleContext#createFilter(String)}.
+	 * 
+	 * @param filter The filter string.
+	 * @return A {@code Filter} object encapsulating the filter string.
+	 * @throws InvalidSyntaxException If {@code filter} contains an invalid
+	 *         filter string that cannot be parsed.
+	 * @throws NullPointerException If {@code filter} is null.
+	 * 
+	 * @see Filter
+	 */
+	public static Filter createFilter(String filter) throws InvalidSyntaxException {
+		return FilterImpl.newInstance(filter);
+	}
+
+	/**
+	 * Match a Distinguished Name (DN) chain against a pattern. DNs can be
+	 * matched using wildcards. A wildcard ({@code '*'} \u002A) replaces all
+	 * possible values. Due to the structure of the DN, the comparison is more
+	 * complicated than string-based wildcard matching.
+	 * <p>
+	 * A wildcard can stand for zero or more DNs in a chain, a number of
+	 * relative distinguished names (RDNs) within a DN, or the value of a single
+	 * RDN. The DNs in the chain and the matching pattern are canonicalized
+	 * before processing. This means, among other things, that spaces must be
+	 * ignored, except in values.
+	 * <p>
+	 * The format of a wildcard match pattern is:
+	 * 
+	 * <pre>
+	 * matchPattern ::= dn-match ( ';' dn-match ) *
+	 * dn-match     ::= ( '*' | rdn-match ) ( ',' rdn-match ) * | '-'
+	 * rdn-match    ::= name '=' value-match
+	 * value-match  ::= '*' | value-star
+	 * value-star   ::= < value, requires escaped '*' and '-' >
+	 * </pre>
+	 * <p>
+	 * The most simple case is a single wildcard; it must match any DN. A
+	 * wildcard can also replace the first list of RDNs of a DN. The first RDNs
+	 * are the least significant. Such lists of matched RDNs can be empty.
+	 * <p>
+	 * For example, a match pattern with a wildcard that matches all DNs that
+	 * end with RDNs of o=ACME and c=US would look like this:
+	 * 
+	 * <pre>
+	 * *, o=ACME, c=US
+	 * </pre>
+	 * 
+	 * This match pattern would match the following DNs:
+	 * 
+	 * <pre>
+	 * cn = Bugs Bunny, o = ACME, c = US
+	 * ou = Carrots, cn=Daffy Duck, o=ACME, c=US
+	 * street = 9C\, Avenue St. Drézéry, o=ACME, c=US
+	 * dc=www, dc=acme, dc=com, o=ACME, c=US
+	 * o=ACME, c=US
+	 * </pre>
+	 * 
+	 * The following DNs would not match:
+	 * 
+	 * <pre>
+	 * street = 9C\, Avenue St. Drézéry, o=ACME, c=FR
+	 * dc=www, dc=acme, dc=com, c=US
+	 * </pre>
+	 * 
+	 * If a wildcard is used for a value of an RDN, the value must be exactly *.
+	 * The wildcard must match any value, and no substring matching must be
+	 * done. For example:
+	 * 
+	 * <pre>
+	 * cn=*,o=ACME,c=*
+	 * </pre>
+	 * 
+	 * This match pattern with wildcard must match the following DNs:
+	 * 
+	 * <pre>
+	 * cn=Bugs Bunny,o=ACME,c=US
+	 * cn = Daffy Duck , o = ACME , c = US
+	 * cn=Road Runner, o=ACME, c=NL
+	 * </pre>
+	 * 
+	 * But not:
+	 * 
+	 * <pre>
+	 * o=ACME, c=NL
+	 * dc=acme.com, cn=Bugs Bunny, o=ACME, c=US
+	 * </pre>
+	 * 
+	 * <p>
+	 * A match pattern may contain a chain of DN match patterns. The semicolon(
+	 * {@code ';'} \u003B) must be used to separate DN match patterns in a
+	 * chain. Wildcards can also be used to match against a complete DN within a
+	 * chain.
+	 * <p>
+	 * The following example matches a certificate signed by Tweety Inc. in the
+	 * US.
+	 * </p>
+	 * 
+	 * <pre>
+	 * * ; ou=S & V, o=Tweety Inc., c=US
+	 * </pre>
+	 * <p>
+	 * The wildcard ('*') matches zero or one DN in the chain, however,
+	 * sometimes it is necessary to match a longer chain. The minus sign (
+	 * {@code '-'} \u002D) represents zero or more DNs, whereas the asterisk
+	 * only represents a single DN. For example, to match a DN where the Tweety
+	 * Inc. is in the DN chain, use the following expression:
+	 * </p>
+	 * 
+	 * <pre>
+	 * - ; *, o=Tweety Inc., c=US
+	 * </pre>
+	 * 
+	 * @param matchPattern The pattern against which to match the DN chain.
+	 * @param dnChain The DN chain to match against the specified pattern. Each
+	 *        element of the chain must be of type {@code String} and use the
+	 *        format defined in <a
+	 *        href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>.
+	 * @return {@code true} If the pattern matches the DN chain; otherwise
+	 *         {@code false} is returned.
+	 * @throws IllegalArgumentException If the specified match pattern or DN
+	 *         chain is invalid.
+	 * @since 1.5
+	 */
+	public static boolean matchDistinguishedNameChain(String matchPattern, List<String> dnChain) {
+		return DNChainMatching.match(matchPattern, dnChain);
+	}
+
+	/**
+	 * Return a {@code Bundle} for the specified bundle class. The returned
+	 * {@code Bundle} is the bundle associated with the bundle class loader
+	 * which defined the specified class.
+	 * 
+	 * @param classFromBundle A class defined by a bundle class loader.
+	 * @return A {@code Bundle} for the specified bundle class or {@code null}
+	 *         if the specified class was not defined by a bundle class loader.
+	 * @since 1.5
+	 */
+	public static Bundle getBundle(final Class<?> classFromBundle) {
+		// We use doPriv since the caller may not have permission
+		// to call getClassLoader.
+		Object cl = AccessController.doPrivileged(new PrivilegedAction<Object>() {
+			public Object run() {
+				return classFromBundle.getClassLoader();
+			}
+		});
+
+		if (cl instanceof BundleReference) {
+			return ((BundleReference) cl).getBundle();
+		}
+		return null;
+	}
+
+	/**
+	 * RFC 1960-based Filter. Filter objects can be created by calling the
+	 * constructor with the desired filter string. A Filter object can be called
+	 * numerous times to determine if the match argument matches the filter
+	 * string that was used to create the Filter object.
+	 * 
+	 * <p>
+	 * The syntax of a filter string is the string representation of LDAP search
+	 * filters as defined in RFC 1960: <i>A String Representation of LDAP Search
+	 * Filters</i> (available at http://www.ietf.org/rfc/rfc1960.txt). It should
+	 * be noted that RFC 2254: <i>A String Representation of LDAP Search
+	 * Filters</i> (available at http://www.ietf.org/rfc/rfc2254.txt) supersedes
+	 * RFC 1960 but only adds extensible matching and is not applicable for this
+	 * API.
+	 * 
+	 * <p>
+	 * The string representation of an LDAP search filter is defined by the
+	 * following grammar. It uses a prefix format.
+	 * 
+	 * <pre>
+	 *   <filter> ::= '(' <filtercomp> ')'
+	 *   <filtercomp> ::= <and> | <or> | <not> | <item>
+	 *   <and> ::= '&' <filterlist>
+	 *   <or> ::= '|' <filterlist>
+	 *   <not> ::= '!' <filter>
+	 *   <filterlist> ::= <filter> | <filter> <filterlist>
+	 *   <item> ::= <simple> | <present> | <substring>
+	 *   <simple> ::= <attr> <filtertype> <value>
+	 *   <filtertype> ::= <equal> | <approx> | <greater> | <less>
+	 *   <equal> ::= '='
+	 *   <approx> ::= '˜='
+	 *   <greater> ::= '>='
+	 *   <less> ::= '<='
+	 *   <present> ::= <attr> '=*'
+	 *   <substring> ::= <attr> '=' <initial> <any> <final>
+	 *   <initial> ::= NULL | <value>
+	 *   <any> ::= '*' <starval>
+	 *   <starval> ::= NULL | <value> '*' <starval>
+	 *   <final> ::= NULL | <value>
+	 * </pre>
+	 * 
+	 * {@code <attr>} is a string representing an attribute, or key, in
+	 * the properties objects of the registered services. Attribute names are
+	 * not case sensitive; that is cn and CN both refer to the same attribute.
+	 * {@code <value>} is a string representing the value, or part of one,
+	 * of a key in the properties objects of the registered services. If a
+	 * {@code <value>} must contain one of the characters ' {@code *}' or
+	 * '{@code (}' or '{@code )}', these characters should be escaped by
+	 * preceding them with the backslash '{@code \}' character. Note that
+	 * although both the {@code <substring>} and {@code <present>}
+	 * productions can produce the {@code 'attr=*'} construct, this construct is
+	 * used only to denote a presence filter.
+	 * 
+	 * <p>
+	 * Examples of LDAP filters are:
+	 * 
+	 * <pre>
+	 *   "(cn=Babs Jensen)"
+	 *   "(!(cn=Tim Howes))"
+	 *   "(&(" + Constants.OBJECTCLASS + "=Person)(|(sn=Jensen)(cn=Babs J*)))"
+	 *   "(o=univ*of*mich*)"
+	 * </pre>
+	 * 
+	 * <p>
+	 * The approximate match ({@code ~=}) is implementation specific but should
+	 * at least ignore case and white space differences. Optional are codes like
+	 * soundex or other smart "closeness" comparisons.
+	 * 
+	 * <p>
+	 * Comparison of values is not straightforward. Strings are compared
+	 * differently than numbers and it is possible for a key to have multiple
+	 * values. Note that that keys in the match argument must always be strings.
+	 * The comparison is defined by the object type of the key's value. The
+	 * following rules apply for comparison:
+	 * 
+	 * <blockquote>
+	 * <TABLE BORDER=0>
+	 * <TR>
+	 * <TD><b>Property Value Type </b></TD>
+	 * <TD><b>Comparison Type</b></TD>
+	 * </TR>
+	 * <TR>
+	 * <TD>String</TD>
+	 * <TD>String comparison</TD>
+	 * </TR>
+	 * <TR valign=top>
+	 * <TD>Integer, Long, Float, Double, Byte, Short, BigInteger, BigDecimal</TD>
+	 * <TD>numerical comparison</TD>
+	 * </TR>
+	 * <TR>
+	 * <TD>Character</TD>
+	 * <TD>character comparison</TD>
+	 * </TR>
+	 * <TR>
+	 * <TD>Boolean</TD>
+	 * <TD>equality comparisons only</TD>
+	 * </TR>
+	 * <TR>
+	 * <TD>[] (array)</TD>
+	 * <TD>recursively applied to values</TD>
+	 * </TR>
+	 * <TR>
+	 * <TD>Collection</TD>
+	 * <TD>recursively applied to values</TD>
+	 * </TR>
+	 * </TABLE>
+	 * Note: arrays of primitives are also supported. </blockquote>
+	 * 
+	 * A filter matches a key that has multiple values if it matches at least
+	 * one of those values. For example,
+	 * 
+	 * <pre>
+	 * Dictionary d = new Hashtable();
+	 * d.put("cn", new String[] {"a", "b", "c"});
+	 * </pre>
+	 * 
+	 * d will match {@code (cn=a)} and also {@code (cn=b)}
+	 * 
+	 * <p>
+	 * A filter component that references a key having an unrecognizable data
+	 * type will evaluate to {@code false} .
+	 */
+	static private final class FilterImpl implements Filter {
+		/* filter operators */
+		private static final int	EQUAL		= 1;
+		private static final int	APPROX		= 2;
+		private static final int	GREATER		= 3;
+		private static final int	LESS		= 4;
+		private static final int	PRESENT		= 5;
+		private static final int	SUBSTRING	= 6;
+		private static final int	AND			= 7;
+		private static final int	OR			= 8;
+		private static final int	NOT			= 9;
+
+		/** filter operation */
+		private final int			op;
+		/** filter attribute or null if operation AND, OR or NOT */
+		private final String		attr;
+		/** filter operands */
+		private final Object		value;
+
+		/* normalized filter string for Filter object */
+		private transient String	filterString;
+
+		/**
+		 * Constructs a {@link FilterImpl} object. This filter object may be
+		 * used to match a {@link ServiceReference} or a Dictionary.
+		 * 
+		 * <p>
+		 * If the filter cannot be parsed, an {@link InvalidSyntaxException}
+		 * will be thrown with a human readable message where the filter became
+		 * unparsable.
+		 * 
+		 * @param filterString the filter string.
+		 * @throws InvalidSyntaxException If the filter parameter contains an
+		 *         invalid filter string that cannot be parsed.
+		 */
+		static FilterImpl newInstance(String filterString) throws InvalidSyntaxException {
+			return new Parser(filterString).parse();
+		}
+
+		FilterImpl(int operation, String attr, Object value) {
+			this.op = operation;
+			this.attr = attr;
+			this.value = value;
+			filterString = null;
+		}
+
+		/**
+		 * Filter using a service's properties.
+		 * <p>
+		 * This {@code Filter} is executed using the keys and values of the
+		 * referenced service's properties. The keys are looked up in a case
+		 * insensitive manner.
+		 * 
+		 * @param reference The reference to the service whose properties are
+		 *        used in the match.
+		 * @return {@code true} if the service's properties match this
+		 *         {@code Filter}; {@code false} otherwise.
+		 */
+		public boolean match(ServiceReference<?> reference) {
+			return matches(new ServiceReferenceMap(reference));
+		}
+
+		/**
+		 * Filter using a {@code Dictionary} with case insensitive key lookup.
+		 * This {@code Filter} is executed using the specified
+		 * {@code Dictionary}'s keys and values. The keys are looked up in a
+		 * case insensitive manner.
+		 * 
+		 * @param dictionary The {@code Dictionary} whose key/value pairs are
+		 *        used in the match.
+		 * @return {@code true} if the {@code Dictionary}'s values match this
+		 *         filter; {@code false} otherwise.
+		 * @throws IllegalArgumentException If {@code dictionary} contains case
+		 *         variants of the same key name.
+		 */
+		public boolean match(Dictionary<String, ?> dictionary) {
+			return matches(new CaseInsensitiveMap(dictionary));
+		}
+
+		/**
+		 * Filter using a {@code Dictionary}. This {@code Filter} is executed
+		 * using the specified {@code Dictionary}'s keys and values. The keys
+		 * are looked up in a normal manner respecting case.
+		 * 
+		 * @param dictionary The {@code Dictionary} whose key/value pairs are
+		 *        used in the match.
+		 * @return {@code true} if the {@code Dictionary}'s values match this
+		 *         filter; {@code false} otherwise.
+		 * @since 1.3
+		 */
+		public boolean matchCase(Dictionary<String, ?> dictionary) {
+			switch (op) {
+				case AND : {
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						if (!f.matchCase(dictionary)) {
+							return false;
+						}
+					}
+					return true;
+				}
+
+				case OR : {
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						if (f.matchCase(dictionary)) {
+							return true;
+						}
+					}
+					return false;
+				}
+
+				case NOT : {
+					FilterImpl filter = (FilterImpl) value;
+					return !filter.matchCase(dictionary);
+				}
+
+				case SUBSTRING :
+				case EQUAL :
+				case GREATER :
+				case LESS :
+				case APPROX : {
+					Object prop = (dictionary == null) ? null : dictionary.get(attr);
+					return compare(op, prop, value);
+				}
+
+				case PRESENT : {
+					Object prop = (dictionary == null) ? null : dictionary.get(attr);
+					return prop != null;
+				}
+			}
+
+			return false;
+		}
+
+		/**
+		 * Filter using a {@code Map}. This {@code Filter} is executed using the
+		 * specified {@code Map}'s keys and values. The keys are looked up in a
+		 * normal manner respecting case.
+		 * 
+		 * @param map The {@code Map} whose key/value pairs are used in the
+		 *        match. Maps with {@code null} key or values are not supported.
+		 *        A {@code null} value is considered not present to the filter.
+		 * @return {@code true} if the {@code Map}'s values match this filter;
+		 *         {@code false} otherwise.
+		 * @since 1.6
+		 */
+		public boolean matches(Map<String, ?> map) {
+			switch (op) {
+				case AND : {
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						if (!f.matches(map)) {
+							return false;
+						}
+					}
+					return true;
+				}
+
+				case OR : {
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						if (f.matches(map)) {
+							return true;
+						}
+					}
+					return false;
+				}
+
+				case NOT : {
+					FilterImpl filter = (FilterImpl) value;
+					return !filter.matches(map);
+				}
+
+				case SUBSTRING :
+				case EQUAL :
+				case GREATER :
+				case LESS :
+				case APPROX : {
+					Object prop = (map == null) ? null : map.get(attr);
+					return compare(op, prop, value);
+				}
+
+				case PRESENT : {
+					Object prop = (map == null) ? null : map.get(attr);
+					return prop != null;
+				}
+			}
+
+			return false;
+		}
+
+		/**
+		 * Returns this {@code Filter}'s filter string.
+		 * <p>
+		 * The filter string is normalized by removing whitespace which does not
+		 * affect the meaning of the filter.
+		 * 
+		 * @return This {@code Filter}'s filter string.
+		 */
+		public String toString() {
+			String result = filterString;
+			if (result == null) {
+				filterString = result = normalize().toString();
+			}
+			return result;
+		}
+
+		/**
+		 * Returns this {@code Filter}'s normalized filter string.
+		 * <p>
+		 * The filter string is normalized by removing whitespace which does not
+		 * affect the meaning of the filter.
+		 * 
+		 * @return This {@code Filter}'s filter string.
+		 */
+		private StringBuffer normalize() {
+			StringBuffer sb = new StringBuffer();
+			sb.append('(');
+
+			switch (op) {
+				case AND : {
+					sb.append('&');
+
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						sb.append(f.normalize());
+					}
+
+					break;
+				}
+
+				case OR : {
+					sb.append('|');
+
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						sb.append(f.normalize());
+					}
+
+					break;
+				}
+
+				case NOT : {
+					sb.append('!');
+					FilterImpl filter = (FilterImpl) value;
+					sb.append(filter.normalize());
+
+					break;
+				}
+
+				case SUBSTRING : {
+					sb.append(attr);
+					sb.append('=');
+
+					String[] substrings = (String[]) value;
+
+					for (String substr : substrings) {
+						if (substr == null) /* * */{
+							sb.append('*');
+						} else /* xxx */{
+							sb.append(encodeValue(substr));
+						}
+					}
+
+					break;
+				}
+				case EQUAL : {
+					sb.append(attr);
+					sb.append('=');
+					sb.append(encodeValue((String) value));
+
+					break;
+				}
+				case GREATER : {
+					sb.append(attr);
+					sb.append(">=");
+					sb.append(encodeValue((String) value));
+
+					break;
+				}
+				case LESS : {
+					sb.append(attr);
+					sb.append("<=");
+					sb.append(encodeValue((String) value));
+
+					break;
+				}
+				case APPROX : {
+					sb.append(attr);
+					sb.append("~=");
+					sb.append(encodeValue(approxString((String) value)));
+
+					break;
+				}
+
+				case PRESENT : {
+					sb.append(attr);
+					sb.append("=*");
+
+					break;
+				}
+			}
+
+			sb.append(')');
+
+			return sb;
+		}
+
+		/**
+		 * Compares this {@code Filter} to another {@code Filter}.
+		 * 
+		 * <p>
+		 * This implementation returns the result of calling
+		 * {@code this.toString().equals(obj.toString()}.
+		 * 
+		 * @param obj The object to compare against this {@code Filter}.
+		 * @return If the other object is a {@code Filter} object, then returns
+		 *         the result of calling
+		 *         {@code this.toString().equals(obj.toString()}; {@code false}
+		 *         otherwise.
+		 */
+		public boolean equals(Object obj) {
+			if (obj == this) {
+				return true;
+			}
+
+			if (!(obj instanceof Filter)) {
+				return false;
+			}
+
+			return this.toString().equals(obj.toString());
+		}
+
+		/**
+		 * Returns the hashCode for this {@code Filter}.
+		 * 
+		 * <p>
+		 * This implementation returns the result of calling
+		 * {@code this.toString().hashCode()}.
+		 * 
+		 * @return The hashCode of this {@code Filter}.
+		 */
+		public int hashCode() {
+			return this.toString().hashCode();
+		}
+
+		/**
+		 * Encode the value string such that '(', '*', ')' and '\' are escaped.
+		 * 
+		 * @param value unencoded value string.
+		 * @return encoded value string.
+		 */
+		private static String encodeValue(String value) {
+			boolean encoded = false;
+			int inlen = value.length();
+			int outlen = inlen << 1; /* inlen 2 */
+
+			char[] output = new char[outlen];
+			value.getChars(0, inlen, output, inlen);
+
+			int cursor = 0;
+			for (int i = inlen; i < outlen; i++) {
+				char c = output[i];
+
+				switch (c) {
+					case '(' :
+					case '*' :
+					case ')' :
+					case '\\' : {
+						output[cursor] = '\\';
+						cursor++;
+						encoded = true;
+
+						break;
+					}
+				}
+
+				output[cursor] = c;
+				cursor++;
+			}
+
+			return encoded ? new String(output, 0, cursor) : value;
+		}
+
+		private boolean compare(int operation, Object value1, Object value2) {
+			if (value1 == null) {
+				return false;
+			}
+			if (value1 instanceof String) {
+				return compare_String(operation, (String) value1, value2);
+			}
+
+			Class<?> clazz = value1.getClass();
+			if (clazz.isArray()) {
+				Class<?> type = clazz.getComponentType();
+				if (type.isPrimitive()) {
+					return compare_PrimitiveArray(operation, type, value1, value2);
+				}
+				return compare_ObjectArray(operation, (Object[]) value1, value2);
+			}
+			if (value1 instanceof Collection<?>) {
+				return compare_Collection(operation, (Collection<?>) value1, value2);
+			}
+			if (value1 instanceof Integer) {
+				return compare_Integer(operation, ((Integer) value1).intValue(), value2);
+			}
+			if (value1 instanceof Long) {
+				return compare_Long(operation, ((Long) value1).longValue(), value2);
+			}
+			if (value1 instanceof Byte) {
+				return compare_Byte(operation, ((Byte) value1).byteValue(), value2);
+			}
+			if (value1 instanceof Short) {
+				return compare_Short(operation, ((Short) value1).shortValue(), value2);
+			}
+			if (value1 instanceof Character) {
+				return compare_Character(operation, ((Character) value1).charValue(), value2);
+			}
+			if (value1 instanceof Float) {
+				return compare_Float(operation, ((Float) value1).floatValue(), value2);
+			}
+			if (value1 instanceof Double) {
+				return compare_Double(operation, ((Double) value1).doubleValue(), value2);
+			}
+			if (value1 instanceof Boolean) {
+				return compare_Boolean(operation, ((Boolean) value1).booleanValue(), value2);
+			}
+			if (value1 instanceof Comparable<?>) {
+				Comparable<Object> comparable = (Comparable<Object>) value1;
+				return compare_Comparable(operation, comparable, value2);
+			}
+			return compare_Unknown(operation, value1, value2);
+		}
+
+		private boolean compare_Collection(int operation, Collection<?> collection, Object value2) {
+			for (Object value1 : collection) {
+				if (compare(operation, value1, value2)) {
+					return true;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_ObjectArray(int operation, Object[] array, Object value2) {
+			for (Object value1 : array) {
+				if (compare(operation, value1, value2)) {
+					return true;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_PrimitiveArray(int operation, Class<?> type, Object primarray, Object value2) {
+			if (Integer.TYPE.isAssignableFrom(type)) {
+				int[] array = (int[]) primarray;
+				for (int value1 : array) {
+					if (compare_Integer(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Long.TYPE.isAssignableFrom(type)) {
+				long[] array = (long[]) primarray;
+				for (long value1 : array) {
+					if (compare_Long(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Byte.TYPE.isAssignableFrom(type)) {
+				byte[] array = (byte[]) primarray;
+				for (byte value1 : array) {
+					if (compare_Byte(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Short.TYPE.isAssignableFrom(type)) {
+				short[] array = (short[]) primarray;
+				for (short value1 : array) {
+					if (compare_Short(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Character.TYPE.isAssignableFrom(type)) {
+				char[] array = (char[]) primarray;
+				for (char value1 : array) {
+					if (compare_Character(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Float.TYPE.isAssignableFrom(type)) {
+				float[] array = (float[]) primarray;
+				for (float value1 : array) {
+					if (compare_Float(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Double.TYPE.isAssignableFrom(type)) {
+				double[] array = (double[]) primarray;
+				for (double value1 : array) {
+					if (compare_Double(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Boolean.TYPE.isAssignableFrom(type)) {
+				boolean[] array = (boolean[]) primarray;
+				for (boolean value1 : array) {
+					if (compare_Boolean(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			return false;
+		}
+
+		private boolean compare_String(int operation, String string, Object value2) {
+			switch (operation) {
+				case SUBSTRING : {
+					String[] substrings = (String[]) value2;
+					int pos = 0;
+					for (int i = 0, size = substrings.length; i < size; i++) {
+						String substr = substrings[i];
+
+						if (i + 1 < size) /* if this is not that last substr */{
+							if (substr == null) /* * */{
+								String substr2 = substrings[i + 1];
+
+								if (substr2 == null) /* ** */
+									continue; /* ignore first star */
+								/* xxx */
+								int index = string.indexOf(substr2, pos);
+								if (index == -1) {
+									return false;
+								}
+
+								pos = index + substr2.length();
+								if (i + 2 < size) // if there are more
+									// substrings, increment
+									// over the string we just
+									// matched; otherwise need
+									// to do the last substr
+									// check
+									i++;
+							} else /* xxx */{
+								int len = substr.length();
+								if (string.regionMatches(pos, substr, 0, len)) {
+									pos += len;
+								} else {
+									return false;
+								}
+							}
+						} else /* last substr */{
+							if (substr == null) /* * */{
+								return true;
+							}
+							/* xxx */
+							return string.endsWith(substr);
+						}
+					}
+
+					return true;
+				}
+				case EQUAL : {
+					return string.equals(value2);
+				}
+				case APPROX : {
+					string = approxString(string);
+					String string2 = approxString((String) value2);
+
+					return string.equalsIgnoreCase(string2);
+				}
+				case GREATER : {
+					return string.compareTo((String) value2) >= 0;
+				}
+				case LESS : {
+					return string.compareTo((String) value2) <= 0;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Integer(int operation, int intval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			int intval2;
+			try {
+				intval2 = Integer.parseInt(((String) value2).trim());
+			} catch (IllegalArgumentException e) {
+				return false;
+			}
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return intval == intval2;
+				}
+				case GREATER : {
+					return intval >= intval2;
+				}
+				case LESS : {
+					return intval <= intval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Long(int operation, long longval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			long longval2;
+			try {
+				longval2 = Long.parseLong(((String) value2).trim());
+			} catch (IllegalArgumentException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return longval == longval2;
+				}
+				case GREATER : {
+					return longval >= longval2;
+				}
+				case LESS : {
+					return longval <= longval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Byte(int operation, byte byteval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			byte byteval2;
+			try {
+				byteval2 = Byte.parseByte(((String) value2).trim());
+			} catch (IllegalArgumentException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return byteval == byteval2;
+				}
+				case GREATER : {
+					return byteval >= byteval2;
+				}
+				case LESS : {
+					return byteval <= byteval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Short(int operation, short shortval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			short shortval2;
+			try {
+				shortval2 = Short.parseShort(((String) value2).trim());
+			} catch (IllegalArgumentException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return shortval == shortval2;
+				}
+				case GREATER : {
+					return shortval >= shortval2;
+				}
+				case LESS : {
+					return shortval <= shortval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Character(int operation, char charval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			char charval2;
+			try {
+				charval2 = ((String) value2).charAt(0);
+			} catch (IndexOutOfBoundsException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case EQUAL : {
+					return charval == charval2;
+				}
+				case APPROX : {
+					return (charval == charval2) || (Character.toUpperCase(charval) == Character.toUpperCase(charval2)) || (Character.toLowerCase(charval) == Character.toLowerCase(charval2));
+				}
+				case GREATER : {
+					return charval >= charval2;
+				}
+				case LESS : {
+					return charval <= charval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Boolean(int operation, boolean boolval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			boolean boolval2 = Boolean.valueOf(((String) value2).trim()).booleanValue();
+			switch (operation) {
+				case APPROX :
+				case EQUAL :
+				case GREATER :
+				case LESS : {
+					return boolval == boolval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Float(int operation, float floatval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			float floatval2;
+			try {
+				floatval2 = Float.parseFloat(((String) value2).trim());
+			} catch (IllegalArgumentException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return Float.compare(floatval, floatval2) == 0;
+				}
+				case GREATER : {
+					return Float.compare(floatval, floatval2) >= 0;
+				}
+				case LESS : {
+					return Float.compare(floatval, floatval2) <= 0;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Double(int operation, double doubleval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			double doubleval2;
+			try {
+				doubleval2 = Double.parseDouble(((String) value2).trim());
+			} catch (IllegalArgumentException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return Double.compare(doubleval, doubleval2) == 0;
+				}
+				case GREATER : {
+					return Double.compare(doubleval, doubleval2) >= 0;
+				}
+				case LESS : {
+					return Double.compare(doubleval, doubleval2) <= 0;
+				}
+			}
+			return false;
+		}
+
+		private static Object valueOf(Class<?> target, String value2) {
+			do {
+				Method method;
+				try {
+					method = target.getMethod("valueOf", String.class);
+				} catch (NoSuchMethodException e) {
+					break;
+				}
+				if (Modifier.isStatic(method.getModifiers()) && target.isAssignableFrom(method.getReturnType())) {
+					setAccessible(method);
+					try {
+						return method.invoke(null, value2.trim());
+					} catch (IllegalAccessException e) {
+						return null;
+					} catch (InvocationTargetException e) {
+						return null;
+					}
+				}
+			} while (false);
+
+			do {
+				Constructor<?> constructor;
+				try {
+					constructor = target.getConstructor(String.class);
+				} catch (NoSuchMethodException e) {
+					break;
+				}
+				setAccessible(constructor);
+				try {
+					return constructor.newInstance(value2.trim());
+				} catch (IllegalAccessException e) {
+					return null;
+				} catch (InvocationTargetException e) {
+					return null;
+				} catch (InstantiationException e) {
+					return null;
+				}
+			} while (false);
+
+			return null;
+		}
+
+		private static void setAccessible(AccessibleObject accessible) {
+			if (!accessible.isAccessible()) {
+				AccessController.doPrivileged(new SetAccessibleAction(accessible));
+			}
+		}
+
+		private boolean compare_Comparable(int operation, Comparable<Object> value1, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			value2 = valueOf(value1.getClass(), (String) value2);
+			if (value2 == null) {
+				return false;
+			}
+			try {
+				switch (operation) {
+					case APPROX :
+					case EQUAL : {
+						return value1.compareTo(value2) == 0;
+					}
+					case GREATER : {
+						return value1.compareTo(value2) >= 0;
+					}
+					case LESS : {
+						return value1.compareTo(value2) <= 0;
+					}
+				}
+			} catch (Exception e) {
+				// if the compareTo method throws an exception; return false
+				return false;
+			}
+			return false;
+		}
+
+		private boolean compare_Unknown(int operation, Object value1, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			value2 = valueOf(value1.getClass(), (String) value2);
+			if (value2 == null) {
+				return false;
+			}
+			try {
+				switch (operation) {
+					case APPROX :
+					case EQUAL :
+					case GREATER :
+					case LESS : {
+						return value1.equals(value2);
+					}
+				}
+			} catch (Exception e) {
+				// if the equals method throws an exception; return false
+				return false;
+			}
+			return false;
+		}
+
+		/**
+		 * Map a string for an APPROX (~=) comparison.
+		 * 
+		 * This implementation removes white spaces. This is the minimum
+		 * implementation allowed by the OSGi spec.
+		 * 
+		 * @param input Input string.
+		 * @return String ready for APPROX comparison.
+		 */
+		private static String approxString(String input) {
+			boolean changed = false;
+			char[] output = input.toCharArray();
+			int cursor = 0;
+			for (char c : output) {
+				if (Character.isWhitespace(c)) {
+					changed = true;
+					continue;
+				}
+
+				output[cursor] = c;
+				cursor++;
+			}
+
+			return changed ? new String(output, 0, cursor) : input;
+		}
+
+		/**
+		 * Parser class for OSGi filter strings. This class parses the complete
+		 * filter string and builds a tree of Filter objects rooted at the
+		 * parent.
+		 */
+		static private final class Parser {
+			private final String	filterstring;
+			private final char[]	filterChars;
+			private int				pos;
+
+			Parser(String filterstring) {
+				this.filterstring = filterstring;
+				filterChars = filterstring.toCharArray();
+				pos = 0;
+			}
+
+			FilterImpl parse() throws InvalidSyntaxException {
+				FilterImpl filter;
+				try {
+					filter = parse_filter();
+				} catch (ArrayIndexOutOfBoundsException e) {
+					throw new InvalidSyntaxException("Filter ended abruptly", filterstring, e);
+				}
+
+				if (pos != filterChars.length) {
+					throw new InvalidSyntaxException("Extraneous trailing characters: " + filterstring.substring(pos), filterstring);
+				}
+				return filter;
+			}
+
+			private FilterImpl parse_filter() throws InvalidSyntaxException {
+				FilterImpl filter;
+				skipWhiteSpace();
+
+				if (filterChars[pos] != '(') {
+					throw new InvalidSyntaxException("Missing '(': " + filterstring.substring(pos), filterstring);
+				}
+
+				pos++;
+
+				filter = parse_filtercomp();
+
+				skipWhiteSpace();
+
+				if (filterChars[pos] != ')') {
+					throw new InvalidSyntaxException("Missing ')': " + filterstring.substring(pos), filterstring);
+				}
+
+				pos++;
+
+				skipWhiteSpace();
+
+				return filter;
+			}
+
+			private FilterImpl parse_filtercomp() throws InvalidSyntaxException {
+				skipWhiteSpace();
+
+				char c = filterChars[pos];
+
+				switch (c) {
+					case '&' : {
+						pos++;
+						return parse_and();
+					}
+					case '|' : {
+						pos++;
+						return parse_or();
+					}
+					case '!' : {
+						pos++;
+						return parse_not();
+					}
+				}
+				return parse_item();
+			}
+
+			private FilterImpl parse_and() throws InvalidSyntaxException {
+				int lookahead = pos;
+				skipWhiteSpace();
+
+				if (filterChars[pos] != '(') {
+					pos = lookahead - 1;
+					return parse_item();
+				}
+
+				List<FilterImpl> operands = new ArrayList<FilterImpl>(10);
+
+				while (filterChars[pos] == '(') {
+					FilterImpl child = parse_filter();
+					operands.add(child);
+				}
+
+				return new FilterImpl(FilterImpl.AND, null, operands.toArray(new FilterImpl[operands.size()]));
+			}
+
+			private FilterImpl parse_or() throws InvalidSyntaxException {
+				int lookahead = pos;
+				skipWhiteSpace();
+
+				if (filterChars[pos] != '(') {
+					pos = lookahead - 1;
+					return parse_item();
+				}
+
+				List<FilterImpl> operands = new ArrayList<FilterImpl>(10);
+
+				while (filterChars[pos] == '(') {
+					FilterImpl child = parse_filter();
+					operands.add(child);
+				}
+
+				return new FilterImpl(FilterImpl.OR, null, operands.toArray(new FilterImpl[operands.size()]));
+			}
+
+			private FilterImpl parse_not() throws InvalidSyntaxException {
+				int lookahead = pos;
+				skipWhiteSpace();
+
+				if (filterChars[pos] != '(') {
+					pos = lookahead - 1;
+					return parse_item();
+				}
+
+				FilterImpl child = parse_filter();
+
+				return new FilterImpl(FilterImpl.NOT, null, child);
+			}
+
+			private FilterImpl parse_item() throws InvalidSyntaxException {
+				String attr = parse_attr();
+
+				skipWhiteSpace();
+
+				switch (filterChars[pos]) {
+					case '~' : {
+						if (filterChars[pos + 1] == '=') {
+							pos += 2;
+							return new FilterImpl(FilterImpl.APPROX, attr, parse_value());
+						}
+						break;
+					}
+					case '>' : {
+						if (filterChars[pos + 1] == '=') {
+							pos += 2;
+							return new FilterImpl(FilterImpl.GREATER, attr, parse_value());
+						}
+						break;
+					}
+					case '<' : {
+						if (filterChars[pos + 1] == '=') {
+							pos += 2;
+							return new FilterImpl(FilterImpl.LESS, attr, parse_value());
+						}
+						break;
+					}
+					case '=' : {
+						if (filterChars[pos + 1] == '*') {
+							int oldpos = pos;
+							pos += 2;
+							skipWhiteSpace();
+							if (filterChars[pos] == ')') {
+								return new FilterImpl(FilterImpl.PRESENT, attr, null);
+							}
+							pos = oldpos;
+						}
+
+						pos++;
+						Object string = parse_substring();
+
+						if (string instanceof String) {
+							return new FilterImpl(FilterImpl.EQUAL, attr, string);
+						}
+						return new FilterImpl(FilterImpl.SUBSTRING, attr, string);
+					}
+				}
+
+				throw new InvalidSyntaxException("Invalid operator: " + filterstring.substring(pos), filterstring);
+			}
 
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
+			private String parse_attr() throws InvalidSyntaxException {
+				skipWhiteSpace();
 
-import javax.security.auth.x500.X500Principal;
+				int begin = pos;
+				int end = pos;
 
-/**
- * Framework Utility class.
- * 
- * <p>
- * This class contains utility methods which access Framework functions that may
- * be useful to bundles.
- * 
- * @since 1.3
- * @ThreadSafe
- * @version $Id: a902bc156ea997ed244831c7fab0f290a08ac0c1 $
- */
-public class FrameworkUtil {
-	/**
-	 * FrameworkUtil objects may not be constructed.
-	 */
-	private FrameworkUtil() {
-		// private empty constructor to prevent construction
-	}
+				char c = filterChars[pos];
 
-	/**
-	 * Creates a {@code Filter} object. This {@code Filter} object may
-	 * be used to match a {@code ServiceReference} object or a
-	 * {@code Dictionary} object.
-	 * 
-	 * <p>
-	 * If the filter cannot be parsed, an {@link InvalidSyntaxException} will be
-	 * thrown with a human readable message where the filter became unparsable.
-	 * 
-	 * <p>
-	 * This method returns a Filter implementation which may not perform as well
-	 * as the framework implementation-specific Filter implementation returned
-	 * by {@link BundleContext#createFilter(String)}.
-	 * 
-	 * @param filter The filter string.
-	 * @return A {@code Filter} object encapsulating the filter string.
-	 * @throws InvalidSyntaxException If {@code filter} contains an invalid
-	 *         filter string that cannot be parsed.
-	 * @throws NullPointerException If {@code filter} is null.
-	 * 
-	 * @see Filter
-	 */
-	public static Filter createFilter(String filter)
-			throws InvalidSyntaxException {
-		return new org.apache.felix.framework.FilterImpl(filter);
+				while (c != '~' && c != '<' && c != '>' && c != '=' && c != '(' && c != ')') {
+					pos++;
+
+					if (!Character.isWhitespace(c)) {
+						end = pos;
+					}
+
+					c = filterChars[pos];
+				}
+
+				int length = end - begin;
+
+				if (length == 0) {
+					throw new InvalidSyntaxException("Missing attr: " + filterstring.substring(pos), filterstring);
+				}
+
+				return new String(filterChars, begin, length);
+			}
+
+			private String parse_value() throws InvalidSyntaxException {
+				StringBuffer sb = new StringBuffer(filterChars.length - pos);
+
+				parseloop: while (true) {
+					char c = filterChars[pos];
+
+					switch (c) {
+						case ')' : {
+							break parseloop;
+						}
+
+						case '(' : {
+							throw new InvalidSyntaxException("Invalid value: " + filterstring.substring(pos), filterstring);
+						}
+
+						case '\\' : {
+							pos++;
+							c = filterChars[pos];
+							/* fall through into default */
+						}
+
+						default : {
+							sb.append(c);
+							pos++;
+							break;
+						}
+					}
+				}
+
+				if (sb.length() == 0) {
+					throw new InvalidSyntaxException("Missing value: " + filterstring.substring(pos), filterstring);
+				}
+
+				return sb.toString();
+			}
+
+			private Object parse_substring() throws InvalidSyntaxException {
+				StringBuffer sb = new StringBuffer(filterChars.length - pos);
+
+				List<String> operands = new ArrayList<String>(10);
+
+				parseloop: while (true) {
+					char c = filterChars[pos];
+
+					switch (c) {
+						case ')' : {
+							if (sb.length() > 0) {
+								operands.add(sb.toString());
+							}
+
+							break parseloop;
+						}
+
+						case '(' : {
+							throw new InvalidSyntaxException("Invalid value: " + filterstring.substring(pos), filterstring);
+						}
+
+						case '*' : {
+							if (sb.length() > 0) {
+								operands.add(sb.toString());
+							}
+
+							sb.setLength(0);
+
+							operands.add(null);
+							pos++;
+
+							break;
+						}
+
+						case '\\' : {
+							pos++;
+							c = filterChars[pos];
+							/* fall through into default */
+						}
+
+						default : {
+							sb.append(c);
+							pos++;
+							break;
+						}
+					}
+				}
+
+				int size = operands.size();
+
+				if (size == 0) {
+					return "";
+				}
+
+				if (size == 1) {
+					Object single = operands.get(0);
+
+					if (single != null) {
+						return single;
+					}
+				}
+
+				return operands.toArray(new String[size]);
+			}
+
+			private void skipWhiteSpace() {
+				for (int length = filterChars.length; (pos < length) && Character.isWhitespace(filterChars[pos]);) {
+					pos++;
+				}
+			}
+		}
 	}
 
 	/**
-	 * Match a Distinguished Name (DN) chain against a pattern. DNs can be
-	 * matched using wildcards. A wildcard ('*' \u002A) replaces all
-	 * possible values. Due to the structure of the DN, the comparison is more
-	 * complicated than string-based wildcard matching.
-	 * <p>
-	 * A wildcard can stand for zero or more DNs in a chain, a number of
-	 * relative distinguished names (RDNs) within a DN, or the value of a single
-	 * RDN. The DNs in the chain and the matching pattern are canonicalized
-	 * before processing. This means, among other things, that spaces must be
-	 * ignored, except in values.
-	 * <p>
-	 * The format of a wildcard match pattern is:
-	 * 
-	 * <pre>
-	 * matchPattern	::= dn-match ( ';' dn-match ) *
-	 * dn-match 	::= ( '*' | rdn-match ) ( ',' rdn-match ) * | '-'
-	 * rdn-match 	::= name '=' value-match
-	 * value-match 	::= '*' | value-star
-	 * value-star 	::= < value, requires escaped '*' and '-' >
-	 * </pre>
-	 * <p>
-	 * The most simple case is a single wildcard; it must match any DN. A
-	 * wildcard can also replace the first list of RDNs of a DN. The first RDNs
-	 * are the least significant. Such lists of matched RDNs can be empty.
-	 * <p>
-	 * For example, a match pattern with a wildcard that matches all DNs that
-	 * end with RDNs of o=ACME and c=US would look like this:
-	 * 
-	 * <pre>
-	 * *, o=ACME, c=US
-	 * </pre>
-	 * 
-	 * This match pattern would match the following DNs:
-	 * 
-	 * <pre>
-	 * cn = Bugs Bunny, o = ACME, c = US
-	 * ou = Carrots, cn=Daffy Duck, o=ACME, c=US
-	 * street = 9C\, Avenue St. Drézéry, o=ACME, c=US
-	 * dc=www, dc=acme, dc=com, o=ACME, c=US
-	 * o=ACME, c=US
-	 * </pre>
-	 * 
-	 * The following DNs would not match:
-	 * 
-	 * <pre>
-	 * street = 9C\, Avenue St. Drézéry, o=ACME, c=FR
-	 * dc=www, dc=acme, dc=com, c=US
-	 * </pre>
-	 * 
-	 * If a wildcard is used for a value of an RDN, the value must be exactly *.
-	 * The wildcard must match any value, and no substring matching must be
-	 * done. For example:
-	 * 
-	 * <pre>
-	 * cn=*,o=ACME,c=*
-	 * </pre>
-	 * 
-	 * This match pattern with wildcard must match the following DNs:
-	 * 
-	 * <pre>
-	 * cn=Bugs Bunny,o=ACME,c=US
-	 * cn = Daffy Duck , o = ACME , c = US
-	 * cn=Road Runner, o=ACME, c=NL
-	 * </pre>
-	 * 
-	 * But not:
-	 * 
-	 * <pre>
-	 * o=ACME, c=NL
-	 * dc=acme.com, cn=Bugs Bunny, o=ACME, c=US
-	 * </pre>
-	 * 
-	 * <p>
-	 * A match pattern may contain a chain of DN match patterns. The
-	 * semicolon(';' \u003B) must be used to separate DN match patterns in a
-	 * chain. Wildcards can also be used to match against a complete DN within a
-	 * chain.
-	 * <p>
-	 * The following example matches a certificate signed by Tweety Inc. in the
-	 * US.
-	 * </p>
-	 * 
-	 * <pre>
-	 * * ; ou=S & V, o=Tweety Inc., c=US
-	 * </pre>
-	 * <p>
-	 * The wildcard ('*') matches zero or one DN in the chain, however,
-	 * sometimes it is necessary to match a longer chain. The minus sign ('-'
-	 * \u002D) represents zero or more DNs, whereas the asterisk only
-	 * represents a single DN. For example, to match a DN where the Tweety Inc.
-	 * is in the DN chain, use the following expression:
-	 * </p>
-	 * 
-	 * <pre>
-	 * - ; *, o=Tweety Inc., c=US
-	 * </pre>
-	 * 
-	 * @param matchPattern The pattern against which to match the DN chain.
-	 * @param dnChain The DN chain to match against the specified pattern. Each
-	 *        element of the chain must be of type {@code String} and use the
-	 *        format defined in <a
-	 *        href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>.
-	 * @return {@code true} If the pattern matches the DN chain; otherwise
-	 *         {@code false} is returned.
-	 * @throws IllegalArgumentException If the specified match pattern or DN
-	 *         chain is invalid.
-	 * @since 1.5
+	 * This Map is used for case-insensitive key lookup during filter
+	 * evaluation. This Map implementation only supports the get operation using
+	 * a String key as no other operations are used by the Filter
+	 * implementation.
 	 */
-	public static boolean matchDistinguishedNameChain(String matchPattern,
-			List<String> dnChain) {
-		return DNChainMatching.match(matchPattern, dnChain);
+	static private final class CaseInsensitiveMap extends AbstractMap<String, Object> implements Map<String, Object> {
+		private final Dictionary<String, ?>	dictionary;
+		private final String[]				keys;
+
+		/**
+		 * Create a case insensitive map from the specified dictionary.
+		 * 
+		 * @param dictionary
+		 * @throws IllegalArgumentException If {@code dictionary} contains case
+		 *         variants of the same key name.
+		 */
+		CaseInsensitiveMap(Dictionary<String, ?> dictionary) {
+			if (dictionary == null) {
+				this.dictionary = null;
+				this.keys = new String[0];
+				return;
+			}
+			this.dictionary = dictionary;
+			List<String> keyList = new ArrayList<String>(dictionary.size());
+			for (Enumeration<?> e = dictionary.keys(); e.hasMoreElements();) {
+				Object k = e.nextElement();
+				if (k instanceof String) {
+					String key = (String) k;
+					for (String i : keyList) {
+						if (key.equalsIgnoreCase(i)) {
+							throw new IllegalArgumentException();
+						}
+					}
+					keyList.add(key);
+				}
+			}
+			this.keys = keyList.toArray(new String[keyList.size()]);
+		}
+
+		public Object get(Object o) {
+			String k = (String) o;
+			for (String key : keys) {
+				if (key.equalsIgnoreCase(k)) {
+					return dictionary.get(key);
+				}
+			}
+			return null;
+		}
+
+		public Set<java.util.Map.Entry<String, Object>> entrySet() {
+			throw new UnsupportedOperationException();
+		}
 	}
 
 	/**
-	 * Return a {@code Bundle} for the specified bundle class. The returned
-	 * {@code Bundle} is the bundle associated with the bundle class loader
-	 * which defined the specified class.
-	 * 
-	 * @param classFromBundle A class defined by a bundle class loader.
-	 * @return A {@code Bundle} for the specified bundle class or
-	 *         {@code null} if the specified class was not defined by a
-	 *         bundle class loader.
-	 * @since 1.5
+	 * This Map is used for key lookup from a ServiceReference during filter
+	 * evaluation. This Map implementation only supports the get operation using
+	 * a String key as no other operations are used by the Filter
+	 * implementation.
 	 */
-	public static Bundle getBundle(final Class< ? > classFromBundle) {
-		// We use doPriv since the caller may not have permission
-		// to call getClassLoader.
-		Object cl = AccessController
-				.doPrivileged(new PrivilegedAction<Object>() {
-			public Object run() {
-				return classFromBundle.getClassLoader();
+	static private final class ServiceReferenceMap extends AbstractMap<String, Object> implements Map<String, Object> {
+		private final ServiceReference<?>	reference;
+
+		ServiceReferenceMap(ServiceReference<?> reference) {
+			this.reference = reference;
+		}
+
+		public Object get(Object key) {
+			if (reference == null) {
+				return null;
 			}
-		});
+			return reference.getProperty((String) key);
+		}
 
-		if (cl instanceof BundleReference) {
-			return ((BundleReference) cl).getBundle();
+		public Set<java.util.Map.Entry<String, Object>> entrySet() {
+			throw new UnsupportedOperationException();
+		}
+	}
+
+	static private final class SetAccessibleAction implements PrivilegedAction<Object> {
+		private final AccessibleObject	accessible;
+
+		SetAccessibleAction(AccessibleObject accessible) {
+			this.accessible = accessible;
+		}
+
+		public Object run() {
+			accessible.setAccessible(true);
+			return null;
 		}
-		return null;
 	}
 
 	/**
@@ -225,12 +1682,11 @@ public class FrameworkUtil {
 	 *   cn=ben+ou=research,o=ACME,c=us;ou=Super CA,c=CA
 	 * </pre>
 	 * 
-	 * is made up of two DNs: "{@code cn=ben+ou=research,o=ACME,c=us}
-	 * " and " {@code ou=Super CA,c=CA}
-	 * ". The first DN is made of of three RDNs: "
-	 * {@code cn=ben+ou=research}" and "{@code o=ACME}" and "
-	 * {@code c=us}". The first RDN has two name value pairs: "
-	 * {@code cn=ben}" and "{@code ou=research}".
+	 * is made up of two DNs: "{@code cn=ben+ou=research,o=ACME,c=us} " and "
+	 * {@code ou=Super CA,c=CA} ". The first DN is made of of three RDNs: "
+	 * {@code cn=ben+ou=research}" and "{@code o=ACME}" and " {@code c=us}
+	 * ". The first RDN has two name value pairs: " {@code cn=ben}" and "
+	 * {@code ou=research}".
 	 * <p>
 	 * A chain pattern makes use of wildcards ('*' or '-') to match against DNs,
 	 * and wildcards ('*') to match againts DN prefixes, and value. If a DN in a
@@ -253,7 +1709,7 @@ public class FrameworkUtil {
 		 * @param rdnPattern List of name value pattern pairs.
 		 * @return true if the list of name value pairs match the pattern.
 		 */
-		private static boolean rdnmatch(List< ? > rdn, List< ? > rdnPattern) {
+		private static boolean rdnmatch(List<?> rdn, List<?> rdnPattern) {
 			if (rdn.size() != rdnPattern.size()) {
 				return false;
 			}
@@ -262,22 +1718,19 @@ public class FrameworkUtil {
 				String patNameValue = (String) rdnPattern.get(i);
 				int rdnNameEnd = rdnNameValue.indexOf('=');
 				int patNameEnd = patNameValue.indexOf('=');
-				if (rdnNameEnd != patNameEnd
-						|| !rdnNameValue.regionMatches(0, patNameValue, 0,
-								rdnNameEnd)) {
+				if (rdnNameEnd != patNameEnd || !rdnNameValue.regionMatches(0, patNameValue, 0, rdnNameEnd)) {
 					return false;
 				}
 				String patValue = patNameValue.substring(patNameEnd);
 				String rdnValue = rdnNameValue.substring(rdnNameEnd);
-				if (!rdnValue.equals(patValue) && !patValue.equals("=*")
-						&& !patValue.equals("=#16012a")) {
+				if (!rdnValue.equals(patValue) && !patValue.equals("=*") && !patValue.equals("=#16012a")) {
 					return false;
 				}
 			}
 			return true;
 		}
 
-		private static boolean dnmatch(List< ? > dn, List< ? > dnPattern) {
+		private static boolean dnmatch(List<?> dn, List<?> dnPattern) {
 			int dnStart = 0;
 			int patStart = 0;
 			int patLen = dnPattern.size();
@@ -290,8 +1743,7 @@ public class FrameworkUtil {
 			}
 			if (dn.size() < patLen) {
 				return false;
-			}
-			else {
+			} else {
 				if (dn.size() > patLen) {
 					if (!dnPattern.get(0).equals(STAR_WILDCARD)) {
 						// If the number of rdns do not match we must have a
@@ -304,9 +1756,7 @@ public class FrameworkUtil {
 				}
 			}
 			for (int i = 0; i < patLen; i++) {
-				if (!rdnmatch((List< ? >) dn.get(i + dnStart),
-						(List< ? >) dnPattern
-						.get(i + patStart))) {
+				if (!rdnmatch((List<?>) dn.get(i + dnStart), (List<?>) dnPattern.get(i + patStart))) {
 					return false;
 				}
 			}
@@ -328,8 +1778,7 @@ public class FrameworkUtil {
 		 */
 		private static List<Object> parseDNchainPattern(String dnChain) {
 			if (dnChain == null) {
-				throw new IllegalArgumentException(
-						"The DN chain must not be null.");
+				throw new IllegalArgumentException("The DN chain must not be null.");
 			}
 			List<Object> parsed = new ArrayList<Object>();
 			int startIndex = 0;
@@ -370,14 +1819,11 @@ public class FrameworkUtil {
 				List<Object> rdns = new ArrayList<Object>();
 				if (dn.charAt(0) == '*') {
 					if (dn.charAt(1) != ',') {
-						throw new IllegalArgumentException(
-								"invalid wildcard prefix");
+						throw new IllegalArgumentException("invalid wildcard prefix");
 					}
 					rdns.add(STAR_WILDCARD);
-					dn = new X500Principal(dn.substring(2))
-							.getName(X500Principal.CANONICAL);
-				}
-				else {
+					dn = new X500Principal(dn.substring(2)).getName(X500Principal.CANONICAL);
+				} else {
 					dn = new X500Principal(dn).getName(X500Principal.CANONICAL);
 				}
 				// Now dn is a nice CANONICAL DN
@@ -415,8 +1861,7 @@ public class FrameworkUtil {
 		 * the index of a non-space character.
 		 */
 		private static int skipSpaces(String dnChain, int startIndex) {
-			while (startIndex < dnChain.length()
-					&& dnChain.charAt(startIndex) == ' ') {
+			while (startIndex < dnChain.length() && dnChain.charAt(startIndex) == ' ') {
 				startIndex++;
 			}
 			return startIndex;
@@ -446,24 +1891,21 @@ public class FrameworkUtil {
 					}
 				}
 				if (endIndex > dn.length()) {
-					throw new IllegalArgumentException("unterminated escape "
-							+ dn);
+					throw new IllegalArgumentException("unterminated escape " + dn);
 				}
 				nameValues.add(dn.substring(startIndex, endIndex));
 				if (c != '+') {
 					rdn.add(nameValues);
 					if (endIndex != dn.length()) {
 						nameValues = new ArrayList<String>();
-					}
-					else {
+					} else {
 						nameValues = null;
 					}
 				}
 				startIndex = endIndex + 1;
 			}
 			if (nameValues != null) {
-				throw new IllegalArgumentException("improperly terminated DN "
-						+ dn);
+				throw new IllegalArgumentException("improperly terminated DN " + dn);
 			}
 		}
 
@@ -471,28 +1913,22 @@ public class FrameworkUtil {
 		 * This method will return an 'index' which points to a non-wildcard DN
 		 * or the end-of-list.
 		 */
-		private static int skipWildCards(List<Object> dnChainPattern,
-				int dnChainPatternIndex) {
+		private static int skipWildCards(List<Object> dnChainPattern, int dnChainPatternIndex) {
 			int i;
 			for (i = dnChainPatternIndex; i < dnChainPattern.size(); i++) {
 				Object dnPattern = dnChainPattern.get(i);
 				if (dnPattern instanceof String) {
-					if (!dnPattern.equals(STAR_WILDCARD)
-							&& !dnPattern.equals(MINUS_WILDCARD)) {
-						throw new IllegalArgumentException(
-								"expected wildcard in DN pattern");
+					if (!dnPattern.equals(STAR_WILDCARD) && !dnPattern.equals(MINUS_WILDCARD)) {
+						throw new IllegalArgumentException("expected wildcard in DN pattern");
 					}
 					// otherwise continue skipping over wild cards
-				}
-				else {
-					if (dnPattern instanceof List< ? >) {
+				} else {
+					if (dnPattern instanceof List<?>) {
 						// if its a list then we have our 'non-wildcard' DN
 						break;
-					}
-					else {
+					} else {
 						// unknown member of the DNChainPattern
-						throw new IllegalArgumentException(
-								"expected String or List in DN Pattern");
+						throw new IllegalArgumentException("expected String or List in DN Pattern");
 					}
 				}
 			}
@@ -506,10 +1942,7 @@ public class FrameworkUtil {
 		 * where DNChain is of the format: "DN;DN;DN;" and DNChainPattern is of
 		 * the format: "DNPattern;*;DNPattern" (or combinations of this)
 		 */
-		private static boolean dnChainMatch(List<Object> dnChain,
-				int dnChainIndex, List<Object> dnChainPattern,
-				int dnChainPatternIndex)
-				throws IllegalArgumentException {
+		private static boolean dnChainMatch(List<Object> dnChain, int dnChainIndex, List<Object> dnChainPattern, int dnChainPatternIndex) throws IllegalArgumentException {
 			if (dnChainIndex >= dnChain.size()) {
 				return false;
 			}
@@ -519,25 +1952,20 @@ public class FrameworkUtil {
 			// check to see what the pattern starts with
 			Object dnPattern = dnChainPattern.get(dnChainPatternIndex);
 			if (dnPattern instanceof String) {
-				if (!dnPattern.equals(STAR_WILDCARD)
-						&& !dnPattern.equals(MINUS_WILDCARD)) {
-					throw new IllegalArgumentException(
-							"expected wildcard in DN pattern");
+				if (!dnPattern.equals(STAR_WILDCARD) && !dnPattern.equals(MINUS_WILDCARD)) {
+					throw new IllegalArgumentException("expected wildcard in DN pattern");
 				}
 				// here we are processing a wild card as the first DN
 				// skip all wildcard DN's
 				if (dnPattern.equals(MINUS_WILDCARD)) {
-					dnChainPatternIndex = skipWildCards(dnChainPattern,
-							dnChainPatternIndex);
-				}
-				else {
+					dnChainPatternIndex = skipWildCards(dnChainPattern, dnChainPatternIndex);
+				} else {
 					dnChainPatternIndex++; // only skip the '*' wildcard
 				}
 				if (dnChainPatternIndex >= dnChainPattern.size()) {
 					// return true iff the wild card is '-' or if we are at the
 					// end of the chain
-					return dnPattern.equals(MINUS_WILDCARD) ? true : dnChain
-							.size() - 1 == dnChainIndex;
+					return dnPattern.equals(MINUS_WILDCARD) ? true : dnChain.size() - 1 == dnChainIndex;
 				}
 				//
 				// we will now recursively call to see if the rest of the
@@ -546,45 +1974,36 @@ public class FrameworkUtil {
 				//
 				if (dnPattern.equals(STAR_WILDCARD)) {
 					// '*' option: only wildcard on 0 or 1
-					return dnChainMatch(dnChain, dnChainIndex, dnChainPattern,
-							dnChainPatternIndex)
-							|| dnChainMatch(dnChain, dnChainIndex + 1,
-									dnChainPattern, dnChainPatternIndex);
+					return dnChainMatch(dnChain, dnChainIndex, dnChainPattern, dnChainPatternIndex) || dnChainMatch(dnChain, dnChainIndex + 1, dnChainPattern, dnChainPatternIndex);
 				}
 				for (int i = dnChainIndex; i < dnChain.size(); i++) {
 					// '-' option: wildcard 0 or more
-					if (dnChainMatch(dnChain, i, dnChainPattern,
-							dnChainPatternIndex)) {
+					if (dnChainMatch(dnChain, i, dnChainPattern, dnChainPatternIndex)) {
 						return true;
 					}
 				}
 				// if we are here, then we didn't find a match.. fall through to
 				// failure
-			}
-			else {
-				if (dnPattern instanceof List< ? >) {
+			} else {
+				if (dnPattern instanceof List<?>) {
 					// here we have to do a deeper check for each DN in the
 					// pattern until we hit a wild card
 					do {
-						if (!dnmatch((List< ? >) dnChain.get(dnChainIndex),
-								(List< ? >) dnPattern)) {
+						if (!dnmatch((List<?>) dnChain.get(dnChainIndex), (List<?>) dnPattern)) {
 							return false;
 						}
 						// go to the next set of DN's in both chains
 						dnChainIndex++;
 						dnChainPatternIndex++;
 						// if we finished the pattern then it all matched
-						if ((dnChainIndex >= dnChain.size())
-								&& (dnChainPatternIndex >= dnChainPattern
-										.size())) {
+						if ((dnChainIndex >= dnChain.size()) && (dnChainPatternIndex >= dnChainPattern.size())) {
 							return true;
 						}
 						// if the DN Chain is finished, but the pattern isn't
 						// finished then if the rest of the pattern is not
 						// wildcard then we are done
 						if (dnChainIndex >= dnChain.size()) {
-							dnChainPatternIndex = skipWildCards(dnChainPattern,
-									dnChainPatternIndex);
+							dnChainPatternIndex = skipWildCards(dnChainPattern, dnChainPatternIndex);
 							// return TRUE iff the pattern index moved past the
 							// list-size (implying that the rest of the pattern
 							// is all wildcards)
@@ -598,20 +2017,15 @@ public class FrameworkUtil {
 						// get the next DN Pattern
 						dnPattern = dnChainPattern.get(dnChainPatternIndex);
 						if (dnPattern instanceof String) {
-							if (!dnPattern.equals(STAR_WILDCARD)
-									&& !dnPattern.equals(MINUS_WILDCARD)) {
-								throw new IllegalArgumentException(
-										"expected wildcard in DN pattern");
+							if (!dnPattern.equals(STAR_WILDCARD) && !dnPattern.equals(MINUS_WILDCARD)) {
+								throw new IllegalArgumentException("expected wildcard in DN pattern");
 							}
 							// if the next DN is a 'wildcard', then we will
 							// recurse
-							return dnChainMatch(dnChain, dnChainIndex,
-									dnChainPattern, dnChainPatternIndex);
-						}
-						else {
-							if (!(dnPattern instanceof List< ? >)) {
-								throw new IllegalArgumentException(
-										"expected String or List in DN Pattern");
+							return dnChainMatch(dnChain, dnChainIndex, dnChainPattern, dnChainPatternIndex);
+						} else {
+							if (!(dnPattern instanceof List<?>)) {
+								throw new IllegalArgumentException("expected String or List in DN Pattern");
 							}
 						}
 						// if we are here, then we will just continue to the
@@ -619,10 +2033,8 @@ public class FrameworkUtil {
 						// DNChainPattern since both are lists
 					} while (true);
 					// should never reach here?
-				}
-				else {
-					throw new IllegalArgumentException(
-							"expected String or List in DN Pattern");
+				} else {
+					throw new IllegalArgumentException("expected String or List in DN Pattern");
 				}
 			}
 			// if we get here, the the default return is 'mis-match'
@@ -667,31 +2079,27 @@ public class FrameworkUtil {
 			List<Object> parsedDNPattern;
 			try {
 				parsedDNChain = parseDNchain(dnChain);
-			}
-			catch (RuntimeException e) {
-				IllegalArgumentException iae = new IllegalArgumentException(
-						"Invalid DN chain: " + toString(dnChain));
+			} catch (RuntimeException e) {
+				IllegalArgumentException iae = new IllegalArgumentException("Invalid DN chain: " + toString(dnChain));
 				iae.initCause(e);
 				throw iae;
 			}
 			try {
 				parsedDNPattern = parseDNchainPattern(pattern);
-			}
-			catch (RuntimeException e) {
-				IllegalArgumentException iae = new IllegalArgumentException(
-						"Invalid match pattern: " + pattern);
+			} catch (RuntimeException e) {
+				IllegalArgumentException iae = new IllegalArgumentException("Invalid match pattern: " + pattern);
 				iae.initCause(e);
 				throw iae;
 			}
 			return dnChainMatch(parsedDNChain, 0, parsedDNPattern, 0);
 		}
 
-		private static String toString(List< ? > dnChain) {
+		private static String toString(List<?> dnChain) {
 			if (dnChain == null) {
 				return null;
 			}
 			StringBuffer sb = new StringBuffer();
-			for (Iterator< ? > iChain = dnChain.iterator(); iChain.hasNext();) {
+			for (Iterator<?> iChain = dnChain.iterator(); iChain.hasNext();) {
 				sb.append(iChain.next());
 				if (iChain.hasNext()) {
 					sb.append("; ");
diff --git a/src/main/java/org/osgi/framework/InvalidSyntaxException.java b/src/main/java/org/osgi/framework/InvalidSyntaxException.java
index 46d6d20..e2296c0 100644
--- a/src/main/java/org/osgi/framework/InvalidSyntaxException.java
+++ b/src/main/java/org/osgi/framework/InvalidSyntaxException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,14 +21,14 @@ package org.osgi.framework;
  * syntax.
  * 
  * <p>
- * An {@code InvalidSyntaxException} object indicates that a filter
- * string parameter has an invalid syntax and cannot be parsed. See
- * {@link Filter} for a description of the filter string syntax.
+ * An {@code InvalidSyntaxException} object indicates that a filter string
+ * parameter has an invalid syntax and cannot be parsed. See {@link Filter} for
+ * a description of the filter string syntax.
  * 
  * <p>
  * This exception conforms to the general purpose exception chaining mechanism.
  * 
- * @version $Id: adb84e3bc0b82b842e4da84542057fdf53e2ca6a $
+ * @version $Id: 8820ca2db85b557cef8da09ee861249dfb5ee914 $
  */
 
 public class InvalidSyntaxException extends Exception {
@@ -42,15 +42,14 @@ public class InvalidSyntaxException extends Exception {
 	 * Creates an exception of type {@code InvalidSyntaxException}.
 	 * 
 	 * <p>
-	 * This method creates an {@code InvalidSyntaxException} object with
-	 * the specified message and the filter string which generated the
-	 * exception.
+	 * This method creates an {@code InvalidSyntaxException} object with the
+	 * specified message and the filter string which generated the exception.
 	 * 
 	 * @param msg The message.
 	 * @param filter The invalid filter string.
 	 */
 	public InvalidSyntaxException(String msg, String filter) {
-		super(msg);
+		super(message(msg, filter));
 		this.filter = filter;
 	}
 
@@ -58,9 +57,8 @@ public class InvalidSyntaxException extends Exception {
 	 * Creates an exception of type {@code InvalidSyntaxException}.
 	 * 
 	 * <p>
-	 * This method creates an {@code InvalidSyntaxException} object with
-	 * the specified message and the filter string which generated the
-	 * exception.
+	 * This method creates an {@code InvalidSyntaxException} object with the
+	 * specified message and the filter string which generated the exception.
 	 * 
 	 * @param msg The message.
 	 * @param filter The invalid filter string.
@@ -68,16 +66,27 @@ public class InvalidSyntaxException extends Exception {
 	 * @since 1.3
 	 */
 	public InvalidSyntaxException(String msg, String filter, Throwable cause) {
-		super(msg, cause);
+		super(message(msg, filter), cause);
 		this.filter = filter;
 	}
 
 	/**
+	 * Return message string for super constructor.
+	 */
+	private static String message(String msg, String filter) {
+		if ((msg == null) || (filter == null) || msg.indexOf(filter) >= 0) {
+			return msg;
+		}
+		return msg + ": " + filter;
+	}
+
+	/**
 	 * Returns the filter string that generated the
 	 * {@code InvalidSyntaxException} object.
 	 * 
 	 * @return The invalid filter string.
-	 * @see BundleContext#getServiceReferences
+	 * @see BundleContext#getServiceReferences(Class, String)
+	 * @see BundleContext#getServiceReferences(String, String)
 	 * @see BundleContext#addServiceListener(ServiceListener,String)
 	 */
 	public String getFilter() {
@@ -85,11 +94,9 @@ public class InvalidSyntaxException extends Exception {
 	}
 
 	/**
-	 * Returns the cause of this exception or {@code null} if no cause was
-	 * set.
+	 * Returns the cause of this exception or {@code null} if no cause was set.
 	 * 
-	 * @return The cause of this exception or {@code null} if no cause was
-	 *         set.
+	 * @return The cause of this exception or {@code null} if no cause was set.
 	 * @since 1.3
 	 */
 	public Throwable getCause() {
diff --git a/src/main/java/org/osgi/framework/PackagePermission.java b/src/main/java/org/osgi/framework/PackagePermission.java
index b6697a5..62d0d8d 100644
--- a/src/main/java/org/osgi/framework/PackagePermission.java
+++ b/src/main/java/org/osgi/framework/PackagePermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -50,65 +50,64 @@ import java.util.Map;
  * 
  * <p>
  * {@code PackagePermission} has three actions: {@code exportonly},
- * {@code import} and {@code export}. The {@code export} action,
- * which is deprecated, implies the {@code import} action.
+ * {@code import} and {@code export}. The {@code export} action, which is
+ * deprecated, implies the {@code import} action.
  * 
  * @ThreadSafe
- * @version $Id: a286af94405e583f8bedc2ff5d7c818198f8caaf $
+ * @version $Id: e993fbc36b6bff84182a8594af5af3cad8c4e2a3 $
  */
 
 public final class PackagePermission extends BasicPermission {
-	static final long						serialVersionUID	= -5107705877071099135L;
+	static final long								serialVersionUID	= -5107705877071099135L;
 
 	/**
-	 * The action string {@code export}. The {@code export} action
-	 * implies the {@code import} action.
+	 * The action string {@code export}. The {@code export} action implies the
+	 * {@code import} action.
 	 * 
 	 * @deprecated Since 1.5. Use {@code exportonly} instead.
 	 */
-	public final static String				EXPORT				= "export";
+	public final static String						EXPORT				= "export";
 
 	/**
-	 * The action string {@code exportonly}. The {@code exportonly}
-	 * action does not imply the {@code import} action.
+	 * The action string {@code exportonly}. The {@code exportonly} action does
+	 * not imply the {@code import} action.
 	 * 
 	 * @since 1.5
 	 */
-	public final static String				EXPORTONLY			= "exportonly";
+	public final static String						EXPORTONLY			= "exportonly";
 
 	/**
 	 * The action string {@code import}.
 	 */
-	public final static String				IMPORT				= "import";
+	public final static String						IMPORT				= "import";
 
-	private final static int				ACTION_EXPORT		= 0x00000001;
-	private final static int				ACTION_IMPORT		= 0x00000002;
-	private final static int				ACTION_ALL			= ACTION_EXPORT
-																		| ACTION_IMPORT;
-	final static int						ACTION_NONE			= 0;
+	private final static int						ACTION_EXPORT		= 0x00000001;
+	private final static int						ACTION_IMPORT		= 0x00000002;
+	private final static int						ACTION_ALL			= ACTION_EXPORT | ACTION_IMPORT;
+	final static int								ACTION_NONE			= 0;
 
 	/**
 	 * The actions mask.
 	 */
-	transient int							action_mask;
+	transient int									action_mask;
 
 	/**
 	 * The actions in canonical form.
 	 * 
 	 * @serial
 	 */
-	private volatile String					actions				= null;
+	private volatile String							actions				= null;
 
 	/**
 	 * The bundle used by this PackagePermission.
 	 */
-	transient final Bundle					bundle;
+	transient final Bundle							bundle;
 
 	/**
 	 * If this PackagePermission was constructed with a filter, this holds a
 	 * Filter matching object used to evaluate the filter in implies.
 	 */
-	transient Filter						filter;
+	transient Filter								filter;
 
 	/**
 	 * This map holds the properties of the permission, used to match a filter
@@ -136,8 +135,8 @@ public final class PackagePermission extends BasicPermission {
 	 * *
 	 * </pre>
 	 * 
-	 * For the {@code import} action, the name can also be a filter
-	 * expression. The filter gives access to the following attributes:
+	 * For the {@code import} action, the name can also be a filter expression.
+	 * The filter gives access to the following attributes:
 	 * <ul>
 	 * <li>signer - A Distinguished Name chain used to sign the exporting
 	 * bundle. Wildcards in a DN are not matched according to the filter string
@@ -161,27 +160,23 @@ public final class PackagePermission extends BasicPermission {
 	 * 
 	 * @param name Package name or filter expression. A filter expression can
 	 *        only be specified if the specified action is {@code import}.
-	 * @param actions {@code exportonly},{@code import} (canonical
-	 *        order).
+	 * @param actions {@code exportonly},{@code import} (canonical order).
 	 * @throws IllegalArgumentException If the specified name is a filter
-	 *         expression and either the specified action is not
-	 *         {@code import} or the filter has an invalid syntax.
+	 *         expression and either the specified action is not {@code import}
+	 *         or the filter has an invalid syntax.
 	 */
 	public PackagePermission(String name, String actions) {
 		this(name, parseActions(actions));
-		if ((filter != null)
-				&& ((action_mask & ACTION_ALL) != ACTION_IMPORT)) {
-			throw new IllegalArgumentException(
-					"invalid action string for filter expression");
+		if ((filter != null) && ((action_mask & ACTION_ALL) != ACTION_IMPORT)) {
+			throw new IllegalArgumentException("invalid action string for filter expression");
 		}
 	}
 
 	/**
-	 * Creates a new requested {@code PackagePermission} object to be used
-	 * by code that must perform {@code checkPermission} for the
-	 * {@code import} action. {@code PackagePermission} objects
-	 * created with this constructor cannot be added to a
-	 * {@code PackagePermission} permission collection.
+	 * Creates a new requested {@code PackagePermission} object to be used by
+	 * code that must perform {@code checkPermission} for the {@code import}
+	 * action. {@code PackagePermission} objects created with this constructor
+	 * cannot be added to a {@code PackagePermission} permission collection.
 	 * 
 	 * @param name The name of the requested package to import.
 	 * @param exportingBundle The bundle exporting the requested package.
@@ -255,9 +250,7 @@ public final class PackagePermission extends BasicPermission {
 			char c;
 
 			// skip whitespace
-			while ((i != -1)
-					&& ((c = a[i]) == ' ' || c == '\r' || c == '\n'
-							|| c == '\f' || c == '\t'))
+			while ((i != -1) && ((c = a[i]) == ' ' || c == '\r' || c == '\n' || c == '\f' || c == '\t'))
 				i--;
 
 			// check for the known strings
@@ -272,8 +265,7 @@ public final class PackagePermission extends BasicPermission {
 				matchlen = 6;
 				mask |= ACTION_IMPORT;
 
-			}
-			else
+			} else
 				if (i >= 5 && (a[i - 5] == 'e' || a[i - 5] == 'E')
 						&& (a[i - 4] == 'x' || a[i - 4] == 'X')
 						&& (a[i - 3] == 'p' || a[i - 3] == 'P')
@@ -283,8 +275,7 @@ public final class PackagePermission extends BasicPermission {
 					matchlen = 6;
 					mask |= ACTION_EXPORT | ACTION_IMPORT;
 
-				}
-				else {
+				} else {
 					if (i >= 9 && (a[i - 9] == 'e' || a[i - 9] == 'E')
 							&& (a[i - 8] == 'x' || a[i - 8] == 'X')
 							&& (a[i - 7] == 'p' || a[i - 7] == 'P')
@@ -298,11 +289,9 @@ public final class PackagePermission extends BasicPermission {
 						matchlen = 10;
 						mask |= ACTION_EXPORT;
 
-					}
-					else {
+					} else {
 						// parse error
-						throw new IllegalArgumentException(
-								"invalid permission: " + actions);
+						throw new IllegalArgumentException("invalid permission: " + actions);
 					}
 				}
 
@@ -321,8 +310,7 @@ public final class PackagePermission extends BasicPermission {
 					case '\t' :
 						break;
 					default :
-						throw new IllegalArgumentException(
-								"invalid permission: " + actions);
+						throw new IllegalArgumentException("invalid permission: " + actions);
 				}
 				i--;
 			}
@@ -354,10 +342,8 @@ public final class PackagePermission extends BasicPermission {
 
 		try {
 			return FrameworkUtil.createFilter(filterString);
-		}
-		catch (InvalidSyntaxException e) {
-			IllegalArgumentException iae = new IllegalArgumentException(
-					"invalid filter");
+		} catch (InvalidSyntaxException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid filter");
 			iae.initCause(e);
 			throw iae;
 		}
@@ -432,11 +418,11 @@ public final class PackagePermission extends BasicPermission {
 	 * {@code PackagePermission} actions.
 	 * 
 	 * <p>
-	 * Always returns present {@code PackagePermission} actions in the
-	 * following order: {@code EXPORTONLY},{@code IMPORT}.
+	 * Always returns present {@code PackagePermission} actions in the following
+	 * order: {@code EXPORTONLY},{@code IMPORT}.
 	 * 
-	 * @return Canonical string representation of the
-	 *         {@code PackagePermission} actions.
+	 * @return Canonical string representation of the {@code PackagePermission}
+	 *         actions.
 	 */
 	public String getActions() {
 		String result = actions;
@@ -462,8 +448,8 @@ public final class PackagePermission extends BasicPermission {
 	}
 
 	/**
-	 * Returns a new {@code PermissionCollection} object suitable for
-	 * storing {@code PackagePermission} objects.
+	 * Returns a new {@code PermissionCollection} object suitable for storing
+	 * {@code PackagePermission} objects.
 	 * 
 	 * @return A new {@code PermissionCollection} object.
 	 */
@@ -475,15 +461,14 @@ public final class PackagePermission extends BasicPermission {
 	 * Determines the equality of two {@code PackagePermission} objects.
 	 * 
 	 * This method checks that specified package has the same package name and
-	 * {@code PackagePermission} actions as this
-	 * {@code PackagePermission} object.
+	 * {@code PackagePermission} actions as this {@code PackagePermission}
+	 * object.
 	 * 
 	 * @param obj The object to test for equality with this
 	 *        {@code PackagePermission} object.
-	 * @return {@code true} if {@code obj} is a
-	 *         {@code PackagePermission}, and has the same package name and
-	 *         actions as this {@code PackagePermission} object;
-	 *         {@code false} otherwise.
+	 * @return {@code true} if {@code obj} is a {@code PackagePermission}, and
+	 *         has the same package name and actions as this
+	 *         {@code PackagePermission} object; {@code false} otherwise.
 	 */
 	public boolean equals(Object obj) {
 		if (obj == this) {
@@ -496,10 +481,7 @@ public final class PackagePermission extends BasicPermission {
 
 		PackagePermission pp = (PackagePermission) obj;
 
-		return (action_mask == pp.action_mask)
-				&& getName().equals(pp.getName())
-				&& ((bundle == pp.bundle) || ((bundle != null) && bundle
-						.equals(pp.bundle)));
+		return (action_mask == pp.action_mask) && getName().equals(pp.getName()) && ((bundle == pp.bundle) || ((bundle != null) && bundle.equals(pp.bundle)));
 	}
 
 	/**
@@ -521,8 +503,7 @@ public final class PackagePermission extends BasicPermission {
 	 * stream. The actions are serialized, and the superclass takes care of the
 	 * name.
 	 */
-	private synchronized void writeObject(java.io.ObjectOutputStream s)
-			throws IOException {
+	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
 		if (bundle != null) {
 			throw new NotSerializableException("cannot serialize");
 		}
@@ -537,8 +518,7 @@ public final class PackagePermission extends BasicPermission {
 	 * readObject is called to restore the state of this permission from a
 	 * stream.
 	 */
-	private synchronized void readObject(java.io.ObjectInputStream s)
-			throws IOException, ClassNotFoundException {
+	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
 		// Read in the action, then initialize the rest
 		s.defaultReadObject();
 		setTransients(getName(), parseActions(actions));
@@ -588,7 +568,7 @@ public final class PackagePermission extends BasicPermission {
  */
 
 final class PackagePermissionCollection extends PermissionCollection {
-	static final long		serialVersionUID	= -3350758995234427603L;
+	static final long									serialVersionUID	= -3350758995234427603L;
 	/**
 	 * Table of permissions with names.
 	 * 
@@ -602,7 +582,7 @@ final class PackagePermissionCollection extends PermissionCollection {
 	 * @serial
 	 * @GuardedBy this
 	 */
-	private boolean			all_allowed;
+	private boolean										all_allowed;
 
 	/**
 	 * Table of permissions with filter expressions.
@@ -627,24 +607,20 @@ final class PackagePermissionCollection extends PermissionCollection {
 	 * @throws IllegalArgumentException If the specified permission is not a
 	 *         {@code PackagePermission} instance or was constructed with a
 	 *         Bundle object.
-	 * @throws SecurityException If this
-	 *         {@code PackagePermissionCollection} object has been marked
-	 *         read-only.
+	 * @throws SecurityException If this {@code PackagePermissionCollection}
+	 *         object has been marked read-only.
 	 */
 	public void add(final Permission permission) {
 		if (!(permission instanceof PackagePermission)) {
-			throw new IllegalArgumentException("invalid permission: "
-					+ permission);
+			throw new IllegalArgumentException("invalid permission: " + permission);
 		}
 		if (isReadOnly()) {
-			throw new SecurityException("attempt to add a Permission to a "
-					+ "readonly PermissionCollection");
+			throw new SecurityException("attempt to add a Permission to a " + "readonly PermissionCollection");
 		}
 
 		final PackagePermission pp = (PackagePermission) permission;
 		if (pp.bundle != null) {
-			throw new IllegalArgumentException("cannot add to collection: "
-					+ pp);
+			throw new IllegalArgumentException("cannot add to collection: " + pp);
 		}
 
 		final String name = pp.getName();
@@ -657,23 +633,19 @@ final class PackagePermissionCollection extends PermissionCollection {
 				if (pc == null) {
 					filterPermissions = pc = new HashMap<String, PackagePermission>();
 				}
-			}
-			else {
+			} else {
 				pc = permissions;
 			}
-			
+
 			final PackagePermission existing = pc.get(name);
 			if (existing != null) {
 				final int oldMask = existing.action_mask;
 				final int newMask = pp.action_mask;
 				if (oldMask != newMask) {
-					pc
-							.put(name, new PackagePermission(name, oldMask
-									| newMask));
+					pc.put(name, new PackagePermission(name, oldMask | newMask));
 
 				}
-			}
-			else {
+			} else {
 				pc.put(name, pp);
 			}
 
@@ -691,8 +663,8 @@ final class PackagePermissionCollection extends PermissionCollection {
 	 * 
 	 * @param permission The Permission object to compare with this
 	 *        {@code PackagePermission} object.
-	 * @return {@code true} if {@code permission} is a proper subset
-	 *         of a permission in the set; {@code false} otherwise.
+	 * @return {@code true} if {@code permission} is a proper subset of a
+	 *         permission in the set; {@code false} otherwise.
 	 */
 	public boolean implies(final Permission permission) {
 		if (!(permission instanceof PackagePermission)) {
@@ -767,8 +739,8 @@ final class PackagePermissionCollection extends PermissionCollection {
 	}
 
 	/**
-	 * Returns an enumeration of all {@code PackagePermission} objects in
-	 * the container.
+	 * Returns an enumeration of all {@code PackagePermission} objects in the
+	 * container.
 	 * 
 	 * @return Enumeration of all {@code PackagePermission} objects.
 	 */
@@ -782,15 +754,11 @@ final class PackagePermissionCollection extends PermissionCollection {
 	}
 
 	/* serialization logic */
-	private static final ObjectStreamField[]	serialPersistentFields	= {
-			new ObjectStreamField("permissions", Hashtable.class),
-			new ObjectStreamField("all_allowed", Boolean.TYPE),
+	private static final ObjectStreamField[]	serialPersistentFields	= {new ObjectStreamField("permissions", Hashtable.class), new ObjectStreamField("all_allowed", Boolean.TYPE),
 			new ObjectStreamField("filterPermissions", HashMap.class)	};
 
-	private synchronized void writeObject(ObjectOutputStream out)
-			throws IOException {
-		Hashtable<String, PackagePermission> hashtable = new Hashtable<String, PackagePermission>(
-				permissions);
+	private synchronized void writeObject(ObjectOutputStream out) throws IOException {
+		Hashtable<String, PackagePermission> hashtable = new Hashtable<String, PackagePermission>(permissions);
 		ObjectOutputStream.PutField pfields = out.putFields();
 		pfields.put("permissions", hashtable);
 		pfields.put("all_allowed", all_allowed);
@@ -798,15 +766,12 @@ final class PackagePermissionCollection extends PermissionCollection {
 		out.writeFields();
 	}
 
-	private synchronized void readObject(java.io.ObjectInputStream in)
-			throws IOException, ClassNotFoundException {
+	private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
 		ObjectInputStream.GetField gfields = in.readFields();
-		Hashtable<String, PackagePermission> hashtable = (Hashtable<String, PackagePermission>) gfields
-				.get("permissions", null);
+		Hashtable<String, PackagePermission> hashtable = (Hashtable<String, PackagePermission>) gfields.get("permissions", null);
 		permissions = new HashMap<String, PackagePermission>(hashtable);
 		all_allowed = gfields.get("all_allowed", false);
-		HashMap<String, PackagePermission> fp = (HashMap<String, PackagePermission>) gfields
-				.get("filterPermissions", null);
+		HashMap<String, PackagePermission> fp = (HashMap<String, PackagePermission>) gfields.get("filterPermissions", null);
 		filterPermissions = fp;
 	}
 }
diff --git a/src/main/java/org/osgi/framework/ServiceEvent.java b/src/main/java/org/osgi/framework/ServiceEvent.java
index 82ec899..2a59fe8 100644
--- a/src/main/java/org/osgi/framework/ServiceEvent.java
+++ b/src/main/java/org/osgi/framework/ServiceEvent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,10 +22,9 @@ import java.util.EventObject;
 /**
  * An event from the Framework describing a service lifecycle change.
  * <p>
- * {@code ServiceEvent} objects are delivered to
- * {@code ServiceListener}s and {@code AllServiceListener}s when a
- * change occurs in this service's lifecycle. A type code is used to identify
- * the event type for future extendability.
+ * {@code ServiceEvent} objects are delivered to {@code ServiceListener}s and
+ * {@code AllServiceListener}s when a change occurs in this service's lifecycle.
+ * A type code is used to identify the event type for future extendability.
  * 
  * <p>
  * OSGi Alliance reserves the right to extend the set of types.
@@ -33,20 +32,20 @@ import java.util.EventObject;
  * @Immutable
  * @see ServiceListener
  * @see AllServiceListener
- * @version $Id: 2b9458d90004411b6ca0cb4b361bc282b04c85eb $
+ * @version $Id: 49e34e0ad5564d6f4ca0ab0053b272c22b9fb917 $
  */
 
 public class ServiceEvent extends EventObject {
-	static final long				serialVersionUID	= 8792901483909409299L;
+	static final long					serialVersionUID	= 8792901483909409299L;
 	/**
 	 * Reference to the service that had a change occur in its lifecycle.
 	 */
-	private final ServiceReference< ? >	reference;
+	private final ServiceReference<?>	reference;
 
 	/**
 	 * Type of service lifecycle change.
 	 */
-	private final int				type;
+	private final int					type;
 
 	/**
 	 * This service has been registered.
@@ -56,7 +55,7 @@ public class ServiceEvent extends EventObject {
 	 * 
 	 * @see BundleContext#registerService(String[],Object,Dictionary)
 	 */
-	public final static int			REGISTERED			= 0x00000001;
+	public final static int				REGISTERED			= 0x00000001;
 
 	/**
 	 * The properties of a registered service have been modified.
@@ -64,9 +63,9 @@ public class ServiceEvent extends EventObject {
 	 * This event is synchronously delivered <strong>after</strong> the service
 	 * properties have been modified.
 	 * 
-	 * @see ServiceRegistration#setProperties
+	 * @see ServiceRegistration#setProperties(Dictionary)
 	 */
-	public final static int			MODIFIED			= 0x00000002;
+	public final static int				MODIFIED			= 0x00000002;
 
 	/**
 	 * This service is in the process of being unregistered.
@@ -75,16 +74,16 @@ public class ServiceEvent extends EventObject {
 	 * has completed unregistering.
 	 * 
 	 * <p>
-	 * If a bundle is using a service that is {@code UNREGISTERING}, the
-	 * bundle should release its use of the service when it receives this event.
-	 * If the bundle does not release its use of the service when it receives
-	 * this event, the Framework will automatically release the bundle's use of
-	 * the service while completing the service unregistration operation.
+	 * If a bundle is using a service that is {@code UNREGISTERING}, the bundle
+	 * should release its use of the service when it receives this event. If the
+	 * bundle does not release its use of the service when it receives this
+	 * event, the Framework will automatically release the bundle's use of the
+	 * service while completing the service unregistration operation.
 	 * 
-	 * @see ServiceRegistration#unregister
-	 * @see BundleContext#ungetService
+	 * @see ServiceRegistration#unregister()
+	 * @see BundleContext#ungetService(ServiceReference)
 	 */
-	public final static int			UNREGISTERING		= 0x00000004;
+	public final static int				UNREGISTERING		= 0x00000004;
 
 	/**
 	 * The properties of a registered service have been modified and the new
@@ -92,23 +91,23 @@ public class ServiceEvent extends EventObject {
 	 * <p>
 	 * This event is synchronously delivered <strong>after</strong> the service
 	 * properties have been modified. This event is only delivered to listeners
-	 * which were added with a non-{@code null} filter where the filter
-	 * matched the service properties prior to the modification but the filter
-	 * does not match the modified service properties.
+	 * which were added with a non-{@code null} filter where the filter matched
+	 * the service properties prior to the modification but the filter does not
+	 * match the modified service properties.
 	 * 
-	 * @see ServiceRegistration#setProperties
+	 * @see ServiceRegistration#setProperties(Dictionary)
 	 * @since 1.5
 	 */
-	public final static int			MODIFIED_ENDMATCH	= 0x00000008;
+	public final static int				MODIFIED_ENDMATCH	= 0x00000008;
 
 	/**
 	 * Creates a new service event object.
 	 * 
 	 * @param type The event type.
-	 * @param reference A {@code ServiceReference} object to the service
-	 * 	that had a lifecycle change.
+	 * @param reference A {@code ServiceReference} object to the service that
+	 *        had a lifecycle change.
 	 */
-	public ServiceEvent(int type, ServiceReference< ? > reference) {
+	public ServiceEvent(int type, ServiceReference<?> reference) {
 		super(reference);
 		this.reference = reference;
 		this.type = type;
@@ -122,17 +121,17 @@ public class ServiceEvent extends EventObject {
 	 * 
 	 * @return Reference to the service that had a lifecycle change.
 	 */
-	public ServiceReference< ? > getServiceReference() {
+	public ServiceReference<?> getServiceReference() {
 		return reference;
 	}
 
 	/**
 	 * Returns the type of event. The event type values are:
 	 * <ul>
-	 * <li>{@link #REGISTERED} </li> 
-	 * <li>{@link #MODIFIED} </li> 
-	 * <li>{@link #MODIFIED_ENDMATCH} </li> 
-	 * <li>{@link #UNREGISTERING} </li>
+	 * <li>{@link #REGISTERED}</li>
+	 * <li>{@link #MODIFIED}</li>
+	 * <li>{@link #MODIFIED_ENDMATCH}</li>
+	 * <li>{@link #UNREGISTERING}</li>
 	 * </ul>
 	 * 
 	 * @return Type of service lifecycle change.
diff --git a/src/main/java/org/osgi/framework/ServiceException.java b/src/main/java/org/osgi/framework/ServiceException.java
index d8ed3bd..de90784 100644
--- a/src/main/java/org/osgi/framework/ServiceException.java
+++ b/src/main/java/org/osgi/framework/ServiceException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2007, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2007, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,18 +20,17 @@ package org.osgi.framework;
  * A service exception used to indicate that a service problem occurred.
  * 
  * <p>
- * A {@code ServiceException} object is created by the Framework or
- * service implementation to denote an exception condition in the service. A
- * type code is used to identify the exception type for future extendability.
- * Service implementations may also create subclasses of
- * {@code ServiceException}. When subclassing, the subclass should set
- * the type to {@link #SUBCLASSED} to indicate that
- * {@code ServiceException} has been subclassed.
+ * A {@code ServiceException} object is created by the Framework or service
+ * implementation to denote an exception condition in the service. A type code
+ * is used to identify the exception type for future extendability. Service
+ * implementations may also create subclasses of {@code ServiceException}. When
+ * subclassing, the subclass should set the type to {@link #SUBCLASSED} to
+ * indicate that {@code ServiceException} has been subclassed.
  * 
  * <p>
  * This exception conforms to the general purpose exception chaining mechanism.
  * 
- * @version $Id: 453b6021eed4543f754e20696b9f8b33a7e121ee $
+ * @version $Id: 9f763412635f59585bb615cbc449fc7ab72b7103 $
  * @since 1.5
  */
 
@@ -67,7 +66,7 @@ public class ServiceException extends RuntimeException {
 	/**
 	 * An error occurred invoking a remote service.
 	 */
-	public static final int REMOTE 				= 5;
+	public static final int	REMOTE				= 5;
 	/**
 	 * The service factory resulted in a recursive call to itself for the
 	 * requesting bundle.
@@ -97,8 +96,8 @@ public class ServiceException extends RuntimeException {
 	}
 
 	/**
-	 * Creates a {@code ServiceException} with the specified message,
-	 * type and exception cause.
+	 * Creates a {@code ServiceException} with the specified message, type and
+	 * exception cause.
 	 * 
 	 * @param msg The associated message.
 	 * @param type The type for this exception.
@@ -110,8 +109,7 @@ public class ServiceException extends RuntimeException {
 	}
 
 	/**
-	 * Creates a {@code ServiceException} with the specified message and
-	 * type.
+	 * Creates a {@code ServiceException} with the specified message and type.
 	 * 
 	 * @param msg The message.
 	 * @param type The type for this exception.
@@ -122,8 +120,8 @@ public class ServiceException extends RuntimeException {
 	}
 
 	/**
-	 * Returns the type for this exception or {@code UNSPECIFIED} if the
-	 * type was unspecified or unknown.
+	 * Returns the type for this exception or {@code UNSPECIFIED} if the type
+	 * was unspecified or unknown.
 	 * 
 	 * @return The type of this exception.
 	 */
diff --git a/src/main/java/org/osgi/framework/ServiceFactory.java b/src/main/java/org/osgi/framework/ServiceFactory.java
index 6383b22..4b52fee 100644
--- a/src/main/java/org/osgi/framework/ServiceFactory.java
+++ b/src/main/java/org/osgi/framework/ServiceFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -43,9 +43,9 @@ package org.osgi.framework;
  * concurrently call a {@code ServiceFactory}.
  * 
  * @param <S> Type of Service
- * @see BundleContext#getService
+ * @see BundleContext#getService(ServiceReference)
  * @ThreadSafe
- * @version $Id: 94cd1a0127aaad9beb484f557342a8fbd0be2322 $
+ * @version $Id: 535776e702ec5ace54f577218ff8f7920741558b $
  */
 
 public interface ServiceFactory<S> {
@@ -85,7 +85,7 @@ public interface ServiceFactory<S> {
 	 *        requested service.
 	 * @return A service object that <strong>must</strong> be an instance of all
 	 *         the classes named when the service was registered.
-	 * @see BundleContext#getService
+	 * @see BundleContext#getService(ServiceReference)
 	 */
 	public S getService(Bundle bundle, ServiceRegistration<S> registration);
 
@@ -108,8 +108,7 @@ public interface ServiceFactory<S> {
 	 * @param service The service object returned by a previous call to the
 	 *        {@link #getService(Bundle, ServiceRegistration) getService}
 	 *        method.
-	 * @see BundleContext#ungetService
+	 * @see BundleContext#ungetService(ServiceReference)
 	 */
-	public void ungetService(Bundle bundle, ServiceRegistration<S> registration,
-			S service);
+	public void ungetService(Bundle bundle, ServiceRegistration<S> registration, S service);
 }
diff --git a/src/main/java/org/osgi/framework/ServiceListener.java b/src/main/java/org/osgi/framework/ServiceListener.java
index dc6a159..839c1bc 100644
--- a/src/main/java/org/osgi/framework/ServiceListener.java
+++ b/src/main/java/org/osgi/framework/ServiceListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,39 +19,37 @@ package org.osgi.framework;
 import java.util.EventListener;
 
 /**
- * A {@code ServiceEvent} listener. {@code ServiceListener} is a
- * listener interface that may be implemented by a bundle developer. When a
+ * A {@code ServiceEvent} listener. {@code ServiceListener} is a listener
+ * interface that may be implemented by a bundle developer. When a
  * {@code ServiceEvent} is fired, it is synchronously delivered to a
- * {@code ServiceListener}. The Framework may deliver
- * {@code ServiceEvent} objects to a {@code ServiceListener} out
- * of order and may concurrently call and/or reenter a
- * {@code ServiceListener}.
+ * {@code ServiceListener}. The Framework may deliver {@code ServiceEvent}
+ * objects to a {@code ServiceListener} out of order and may concurrently call
+ * and/or reenter a {@code ServiceListener}.
  * 
  * <p>
- * A {@code ServiceListener} object is registered with the Framework
- * using the {@code BundleContext.addServiceListener} method.
- * {@code ServiceListener} objects are called with a
- * {@code ServiceEvent} object when a service is registered, modified, or
- * is in the process of unregistering.
+ * A {@code ServiceListener} object is registered with the Framework using the
+ * {@code BundleContext.addServiceListener} method. {@code ServiceListener}
+ * objects are called with a {@code ServiceEvent} object when a service is
+ * registered, modified, or is in the process of unregistering.
  * 
  * <p>
- * {@code ServiceEvent} object delivery to {@code ServiceListener}
- * objects is filtered by the filter specified when the listener was registered.
- * If the Java Runtime Environment supports permissions, then additional
- * filtering is done. {@code ServiceEvent} objects are only delivered to
- * the listener if the bundle which defines the listener object's class has the
- * appropriate {@code ServicePermission} to get the service using at
- * least one of the named classes under which the service was registered.
+ * {@code ServiceEvent} object delivery to {@code ServiceListener} objects is
+ * filtered by the filter specified when the listener was registered. If the
+ * Java Runtime Environment supports permissions, then additional filtering is
+ * done. {@code ServiceEvent} objects are only delivered to the listener if the
+ * bundle which defines the listener object's class has the appropriate
+ * {@code ServicePermission} to get the service using at least one of the named
+ * classes under which the service was registered.
  * 
  * <p>
- * {@code ServiceEvent} object delivery to {@code ServiceListener}
- * objects is further filtered according to package sources as defined in
+ * {@code ServiceEvent} object delivery to {@code ServiceListener} objects is
+ * further filtered according to package sources as defined in
  * {@link ServiceReference#isAssignableTo(Bundle, String)}.
  * 
  * @see ServiceEvent
  * @see ServicePermission
  * @ThreadSafe
- * @version $Id: d73f8e9b4babc8b53b5d1cbe7b17b732f54bb2a3 $
+ * @version $Id: 601dfda6183ab7f18cd3916958a39734ea141c25 $
  */
 
 public interface ServiceListener extends EventListener {
diff --git a/src/main/java/org/osgi/framework/ServicePermission.java b/src/main/java/org/osgi/framework/ServicePermission.java
index b7a9956..23ecfba 100644
--- a/src/main/java/org/osgi/framework/ServicePermission.java
+++ b/src/main/java/org/osgi/framework/ServicePermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -41,66 +41,64 @@ import java.util.Set;
 /**
  * A bundle's authority to register or get a service.
  * <ul>
- * <li>The {@code register} action allows a bundle to register a service on
- * the specified names.
- * <li>The {@code get} action allows a bundle to detect a service and get
- * it.
+ * <li>The {@code register} action allows a bundle to register a service on the
+ * specified names.
+ * <li>The {@code get} action allows a bundle to detect a service and get it.
  * </ul>
  * Permission to get a service is required in order to detect events regarding
  * the service. Untrusted bundles should not be able to detect the presence of
- * certain services unless they have the appropriate
- * {@code ServicePermission} to get the specific service.
+ * certain services unless they have the appropriate {@code ServicePermission}
+ * to get the specific service.
  * 
  * @ThreadSafe
- * @version $Id: 1b6ee9543f4cbc16add8dc8c40dfa9a6dfee7aa2 $
+ * @version $Id: 96438ad164d7f0f4273787226298bf8208cf0034 $
  */
 
 public final class ServicePermission extends BasicPermission {
-	static final long			serialVersionUID	= -7662148639076511574L;
+	static final long								serialVersionUID	= -7662148639076511574L;
 	/**
 	 * The action string {@code get}.
 	 */
-	public final static String	GET					= "get";
+	public final static String						GET					= "get";
 	/**
 	 * The action string {@code register}.
 	 */
-	public final static String	REGISTER			= "register";
+	public final static String						REGISTER			= "register";
 
-	private final static int	ACTION_GET			= 0x00000001;
-	private final static int	ACTION_REGISTER		= 0x00000002;
-	private final static int	ACTION_ALL			= ACTION_GET
-															| ACTION_REGISTER;
-	final static int						ACTION_NONE			= 0;
+	private final static int						ACTION_GET			= 0x00000001;
+	private final static int						ACTION_REGISTER		= 0x00000002;
+	private final static int						ACTION_ALL			= ACTION_GET | ACTION_REGISTER;
+	final static int								ACTION_NONE			= 0;
 
 	/**
 	 * The actions mask.
 	 */
-	transient int							action_mask;
+	transient int									action_mask;
 
 	/**
 	 * The actions in canonical form.
 	 * 
 	 * @serial
 	 */
-	private volatile String		actions				= null;
+	private volatile String							actions				= null;
 
 	/**
 	 * The service used by this ServicePermission. Must be null if not
 	 * constructed with a service.
 	 */
-	transient final ServiceReference< ? >					service;
+	transient final ServiceReference<?>				service;
 
 	/**
 	 * The object classes for this ServicePermission. Must be null if not
 	 * constructed with a service.
 	 */
-	transient final String[]				objectClass;
+	transient final String[]						objectClass;
 
 	/**
 	 * If this ServicePermission was constructed with a filter, this holds a
 	 * Filter matching object used to evaluate the filter in implies.
 	 */
-	transient Filter						filter;
+	transient Filter								filter;
 
 	/**
 	 * This map holds the properties of the permission, used to match a filter
@@ -112,13 +110,13 @@ public final class ServicePermission extends BasicPermission {
 	/**
 	 * True if constructed with a name and the name is "*" or ends with ".*".
 	 */
-	private transient boolean				wildcard;
+	private transient boolean						wildcard;
 
 	/**
 	 * If constructed with a name and the name ends with ".*", this contains the
 	 * name without the final "*".
 	 */
-	private transient String				prefix;
+	private transient String						prefix;
 
 	/**
 	 * Create a new ServicePermission.
@@ -139,9 +137,9 @@ public final class ServicePermission extends BasicPermission {
 	 * *
 	 * </pre>
 	 * 
-	 * For the {@code get} action, the name can also be a filter
-	 * expression. The filter gives access to the service properties as well as
-	 * the following attributes:
+	 * For the {@code get} action, the name can also be a filter expression. The
+	 * filter gives access to the service properties as well as the following
+	 * attributes:
 	 * <ul>
 	 * <li>signer - A Distinguished Name chain used to sign the bundle
 	 * publishing the service. Wildcards in a DN are not matched according to
@@ -159,33 +157,29 @@ public final class ServicePermission extends BasicPermission {
 	 * Service properties names are case insensitive.
 	 * 
 	 * <p>
-	 * There are two possible actions: {@code get} and
-	 * {@code register}. The {@code get} permission allows the owner
-	 * of this permission to obtain a service with this name. The
-	 * {@code register} permission allows the bundle to register a service
-	 * under that name.
+	 * There are two possible actions: {@code get} and {@code register}. The
+	 * {@code get} permission allows the owner of this permission to obtain a
+	 * service with this name. The {@code register} permission allows the bundle
+	 * to register a service under that name.
 	 * 
 	 * @param name The service class name
 	 * @param actions {@code get},{@code register} (canonical order)
 	 * @throws IllegalArgumentException If the specified name is a filter
-	 *         expression and either the specified action is not
-	 *         {@code get} or the filter has an invalid syntax.
+	 *         expression and either the specified action is not {@code get} or
+	 *         the filter has an invalid syntax.
 	 */
 	public ServicePermission(String name, String actions) {
 		this(name, parseActions(actions));
-		if ((filter != null)
-				&& ((action_mask & ACTION_ALL) != ACTION_GET)) {
-			throw new IllegalArgumentException(
-					"invalid action string for filter expression");
+		if ((filter != null) && ((action_mask & ACTION_ALL) != ACTION_GET)) {
+			throw new IllegalArgumentException("invalid action string for filter expression");
 		}
 	}
 
 	/**
-	 * Creates a new requested {@code ServicePermission} object to be used
-	 * by code that must perform {@code checkPermission} for the
-	 * {@code get} action. {@code ServicePermission} objects created
-	 * with this constructor cannot be added to a {@code ServicePermission}
-	 * permission collection.
+	 * Creates a new requested {@code ServicePermission} object to be used by
+	 * code that must perform {@code checkPermission} for the {@code get}
+	 * action. {@code ServicePermission} objects created with this constructor
+	 * cannot be added to a {@code ServicePermission} permission collection.
 	 * 
 	 * @param reference The requested service.
 	 * @param actions The action {@code get}.
@@ -193,12 +187,11 @@ public final class ServicePermission extends BasicPermission {
 	 *         {@code get} or reference is {@code null}.
 	 * @since 1.5
 	 */
-	public ServicePermission(ServiceReference< ? > reference, String actions) {
+	public ServicePermission(ServiceReference<?> reference, String actions) {
 		super(createName(reference));
 		setTransients(null, parseActions(actions));
 		this.service = reference;
-		this.objectClass = (String[]) reference
-				.getProperty(Constants.OBJECTCLASS);
+		this.objectClass = (String[]) reference.getProperty(Constants.OBJECTCLASS);
 		if ((action_mask & ACTION_ALL) != ACTION_GET) {
 			throw new IllegalArgumentException("invalid action string");
 		}
@@ -210,7 +203,7 @@ public final class ServicePermission extends BasicPermission {
 	 * @param reference ServiceReference to use to create permission name.
 	 * @return permission name.
 	 */
-	private static String createName(ServiceReference< ? > reference) {
+	private static String createName(ServiceReference<?> reference) {
 		if (reference == null) {
 			throw new IllegalArgumentException("reference must not be null");
 		}
@@ -248,8 +241,7 @@ public final class ServicePermission extends BasicPermission {
 			String name = getName();
 			int l = name.length();
 			/* if "*" or endsWith ".*" */
-			wildcard = ((name.charAt(l - 1) == '*') && ((l == 1) || (name
-					.charAt(l - 2) == '.')));
+			wildcard = ((name.charAt(l - 1) == '*') && ((l == 1) || (name.charAt(l - 2) == '.')));
 			if (wildcard && (l > 1)) {
 				prefix = name.substring(0, l - 1);
 			}
@@ -281,9 +273,7 @@ public final class ServicePermission extends BasicPermission {
 			char c;
 
 			// skip whitespace
-			while ((i != -1)
-					&& ((c = a[i]) == ' ' || c == '\r' || c == '\n'
-							|| c == '\f' || c == '\t'))
+			while ((i != -1) && ((c = a[i]) == ' ' || c == '\r' || c == '\n' || c == '\f' || c == '\t'))
 				i--;
 
 			// check for the known strings
@@ -295,8 +285,7 @@ public final class ServicePermission extends BasicPermission {
 				matchlen = 3;
 				mask |= ACTION_GET;
 
-			}
-			else
+			} else
 				if (i >= 7 && (a[i - 7] == 'r' || a[i - 7] == 'R')
 						&& (a[i - 6] == 'e' || a[i - 6] == 'E')
 						&& (a[i - 5] == 'g' || a[i - 5] == 'G')
@@ -308,11 +297,9 @@ public final class ServicePermission extends BasicPermission {
 					matchlen = 8;
 					mask |= ACTION_REGISTER;
 
-				}
-				else {
+				} else {
 					// parse error
-					throw new IllegalArgumentException("invalid permission: "
-							+ actions);
+					throw new IllegalArgumentException("invalid permission: " + actions);
 				}
 
 			// make sure we didn't just match the tail of a word
@@ -322,7 +309,7 @@ public final class ServicePermission extends BasicPermission {
 				switch (a[i - matchlen]) {
 					case ',' :
 						seencomma = true;
-					/* FALLTHROUGH */
+						/* FALLTHROUGH */
 					case ' ' :
 					case '\r' :
 					case '\n' :
@@ -330,8 +317,7 @@ public final class ServicePermission extends BasicPermission {
 					case '\t' :
 						break;
 					default :
-						throw new IllegalArgumentException(
-								"invalid permission: " + actions);
+						throw new IllegalArgumentException("invalid permission: " + actions);
 				}
 				i--;
 			}
@@ -363,18 +349,16 @@ public final class ServicePermission extends BasicPermission {
 
 		try {
 			return FrameworkUtil.createFilter(filterString);
-		}
-		catch (InvalidSyntaxException e) {
-			IllegalArgumentException iae = new IllegalArgumentException(
-					"invalid filter");
+		} catch (InvalidSyntaxException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid filter");
 			iae.initCause(e);
 			throw iae;
 		}
 	}
 
 	/**
-	 * Determines if a {@code ServicePermission} object "implies" the
-	 * specified permission.
+	 * Determines if a {@code ServicePermission} object "implies" the specified
+	 * permission.
 	 * 
 	 * @param p The target permission to check.
 	 * @return {@code true} if the specified permission is implied by this
@@ -432,13 +416,11 @@ public final class ServicePermission extends BasicPermission {
 			int pl = prefix.length();
 			for (int i = 0, l = requestedNames.length; i < l; i++) {
 				String requestedName = requestedNames[i];
-				if ((requestedName.length() > pl)
-						&& requestedName.startsWith(prefix)) {
+				if ((requestedName.length() > pl) && requestedName.startsWith(prefix)) {
 					return true;
 				}
 			}
-		}
-		else {
+		} else {
 			String name = getName();
 			for (int i = 0, l = requestedNames.length; i < l; i++) {
 				if (requestedNames[i].equals(name)) {
@@ -499,8 +481,8 @@ public final class ServicePermission extends BasicPermission {
 	 * 
 	 * @param obj The object to test for equality.
 	 * @return true if obj is a {@code ServicePermission}, and has the same
-	 *         class name and actions as this {@code ServicePermission}
-	 *         object; {@code false} otherwise.
+	 *         class name and actions as this {@code ServicePermission} object;
+	 *         {@code false} otherwise.
 	 */
 	public boolean equals(Object obj) {
 		if (obj == this) {
@@ -513,10 +495,7 @@ public final class ServicePermission extends BasicPermission {
 
 		ServicePermission sp = (ServicePermission) obj;
 
-		return (action_mask == sp.action_mask)
-				&& getName().equals(sp.getName())
-				&& ((service == sp.service) || ((service != null) && (service
-						.compareTo(sp.service) == 0)));
+		return (action_mask == sp.action_mask) && getName().equals(sp.getName()) && ((service == sp.service) || ((service != null) && (service.compareTo(sp.service) == 0)));
 	}
 
 	/**
@@ -537,8 +516,7 @@ public final class ServicePermission extends BasicPermission {
 	 * WriteObject is called to save the state of this permission to a stream.
 	 * The actions are serialized, and the superclass takes care of the name.
 	 */
-	private synchronized void writeObject(java.io.ObjectOutputStream s)
-			throws IOException {
+	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
 		if (service != null) {
 			throw new NotSerializableException("cannot serialize");
 		}
@@ -553,8 +531,7 @@ public final class ServicePermission extends BasicPermission {
 	 * readObject is called to restore the state of this permission from a
 	 * stream.
 	 */
-	private synchronized void readObject(java.io.ObjectInputStream s)
-			throws IOException, ClassNotFoundException {
+	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
 		// Read in the action, then initialize the rest
 		s.defaultReadObject();
 		setTransients(parseFilter(getName()), parseActions(actions));
@@ -598,13 +575,13 @@ public final class ServicePermission extends BasicPermission {
 		}
 		return properties = new Properties(props, service);
 	}
-	
+
 	static private final class Properties extends AbstractMap<String, Object> {
-		private final Map<String, Object>	properties;
-		private final ServiceReference< ? >	service;
+		private final Map<String, Object>							properties;
+		private final ServiceReference<?>							service;
 		private transient volatile Set<Map.Entry<String, Object>>	entries;
 
-		Properties(Map<String, Object> properties, ServiceReference< ? > service) {
+		Properties(Map<String, Object> properties, ServiceReference<?> service) {
 			this.properties = properties;
 			this.service = service;
 			entries = null;
@@ -629,8 +606,7 @@ public final class ServicePermission extends BasicPermission {
 			if (entries != null) {
 				return entries;
 			}
-			Set<Map.Entry<String, Object>> all = new HashSet<Map.Entry<String, Object>>(
-					properties.entrySet());
+			Set<Map.Entry<String, Object>> all = new HashSet<Map.Entry<String, Object>>(properties.entrySet());
 			add: for (String key : service.getPropertyKeys()) {
 				for (String k : properties.keySet()) {
 					if (key.equalsIgnoreCase(k)) {
@@ -641,7 +617,7 @@ public final class ServicePermission extends BasicPermission {
 			}
 			return entries = Collections.unmodifiableSet(all);
 		}
-		
+
 		static private final class Entry implements Map.Entry<String, Object> {
 			private final String	k;
 			private final Object	v;
@@ -650,22 +626,27 @@ public final class ServicePermission extends BasicPermission {
 				this.k = key;
 				this.v = value;
 			}
+
 			public String getKey() {
 				return k;
 			}
+
 			public Object getValue() {
 				return v;
 			}
+
 			public Object setValue(Object value) {
 				throw new UnsupportedOperationException();
 			}
+
 			public String toString() {
 				return k + "=" + v;
 			}
+
 			public int hashCode() {
-				return ((k == null) ? 0 : k.hashCode())
-						^ ((v == null) ? 0 : v.hashCode());
+				return ((k == null) ? 0 : k.hashCode()) ^ ((v == null) ? 0 : v.hashCode());
 			}
+
 			public boolean equals(Object obj) {
 				if (obj == this) {
 					return true;
@@ -673,7 +654,7 @@ public final class ServicePermission extends BasicPermission {
 				if (!(obj instanceof Map.Entry)) {
 					return false;
 				}
-				Map.Entry< ? , ? > e = (Map.Entry< ? , ? >) obj;
+				Map.Entry<?, ?> e = (Map.Entry<?, ?>) obj;
 				final Object key = e.getKey();
 				if ((k == key) || ((k != null) && k.equals(key))) {
 					final Object value = e.getValue();
@@ -695,7 +676,7 @@ public final class ServicePermission extends BasicPermission {
  * @see java.security.PermissionCollection
  */
 final class ServicePermissionCollection extends PermissionCollection {
-	static final long	serialVersionUID	= 662615640374640621L;
+	static final long									serialVersionUID	= 662615640374640621L;
 	/**
 	 * Table of permissions.
 	 * 
@@ -709,7 +690,7 @@ final class ServicePermissionCollection extends PermissionCollection {
 	 * @serial
 	 * @GuardedBy this
 	 */
-	private boolean		all_allowed;
+	private boolean										all_allowed;
 
 	/**
 	 * Table of permissions with filter expressions.
@@ -733,26 +714,22 @@ final class ServicePermissionCollection extends PermissionCollection {
 	 * @param permission The Permission object to add.
 	 * @throws IllegalArgumentException If the specified permission is not a
 	 *         ServicePermission object.
-	 * @throws SecurityException If this
-	 *         {@code ServicePermissionCollection} object has been marked
-	 *         read-only.
+	 * @throws SecurityException If this {@code ServicePermissionCollection}
+	 *         object has been marked read-only.
 	 */
 	public void add(final Permission permission) {
 		if (!(permission instanceof ServicePermission)) {
-			throw new IllegalArgumentException("invalid permission: "
-					+ permission);
+			throw new IllegalArgumentException("invalid permission: " + permission);
 		}
 		if (isReadOnly()) {
-			throw new SecurityException("attempt to add a Permission to a "
-					+ "readonly PermissionCollection");
+			throw new SecurityException("attempt to add a Permission to a " + "readonly PermissionCollection");
 		}
 
 		final ServicePermission sp = (ServicePermission) permission;
 		if (sp.service != null) {
-			throw new IllegalArgumentException("cannot add to collection: "
-					+ sp);
+			throw new IllegalArgumentException("cannot add to collection: " + sp);
 		}
-		
+
 		final String name = sp.getName();
 		final Filter f = sp.filter;
 		synchronized (this) {
@@ -763,25 +740,21 @@ final class ServicePermissionCollection extends PermissionCollection {
 				if (pc == null) {
 					filterPermissions = pc = new HashMap<String, ServicePermission>();
 				}
-			}
-			else {
+			} else {
 				pc = permissions;
 			}
 			final ServicePermission existing = pc.get(name);
-			
+
 			if (existing != null) {
 				final int oldMask = existing.action_mask;
 				final int newMask = sp.action_mask;
 				if (oldMask != newMask) {
-					pc
-							.put(name, new ServicePermission(name, oldMask
-							| newMask));
+					pc.put(name, new ServicePermission(name, oldMask | newMask));
 				}
-			}
-			else {
+			} else {
 				pc.put(name, sp);
 			}
-			
+
 			if (!all_allowed) {
 				if (name.equals("*")) {
 					all_allowed = true;
@@ -795,9 +768,8 @@ final class ServicePermissionCollection extends PermissionCollection {
 	 * {@code permission}.
 	 * 
 	 * @param permission The Permission object to compare.
-	 * @return {@code true} if {@code permission} is a proper
-	 *         subset of a permission in the set; {@code false}
-	 *         otherwise.
+	 * @return {@code true} if {@code permission} is a proper subset of a
+	 *         permission in the set; {@code false} otherwise.
 	 */
 	public boolean implies(final Permission permission) {
 		if (!(permission instanceof ServicePermission)) {
@@ -823,7 +795,7 @@ final class ServicePermissionCollection extends PermissionCollection {
 					}
 				}
 			}
-			
+
 			String[] requestedNames = requested.objectClass;
 			/* if requested permission not created with ServiceReference */
 			if (requestedNames == null) {
@@ -846,7 +818,7 @@ final class ServicePermissionCollection extends PermissionCollection {
 			}
 			perms = pc.values();
 		}
-		
+
 		/* iterate one by one over filteredPermissions */
 		for (ServicePermission perm : perms) {
 			if (perm.implies0(requested, effective)) {
@@ -865,8 +837,7 @@ final class ServicePermissionCollection extends PermissionCollection {
 	 * @param effective The effective actions.
 	 * @return The new effective actions.
 	 */
-	private int effective(String requestedName, final int desired,
-			int effective) {
+	private int effective(String requestedName, final int desired, int effective) {
 		final Map<String, ServicePermission> pc = permissions;
 		ServicePermission sp = pc.get(requestedName);
 		// strategy:
@@ -899,10 +870,10 @@ final class ServicePermissionCollection extends PermissionCollection {
 		 */
 		return effective;
 	}
-	
+
 	/**
-	 * Returns an enumeration of all the {@code ServicePermission}
-	 * objects in the container.
+	 * Returns an enumeration of all the {@code ServicePermission} objects in
+	 * the container.
 	 * 
 	 * @return Enumeration of all the ServicePermission objects.
 	 */
@@ -914,17 +885,13 @@ final class ServicePermissionCollection extends PermissionCollection {
 		}
 		return Collections.enumeration(all);
 	}
-	
+
 	/* serialization logic */
-	private static final ObjectStreamField[]	serialPersistentFields	= {
-			new ObjectStreamField("permissions", Hashtable.class),
-			new ObjectStreamField("all_allowed", Boolean.TYPE),
+	private static final ObjectStreamField[]	serialPersistentFields	= {new ObjectStreamField("permissions", Hashtable.class), new ObjectStreamField("all_allowed", Boolean.TYPE),
 			new ObjectStreamField("filterPermissions", HashMap.class)	};
 
-	private synchronized void writeObject(ObjectOutputStream out)
-			throws IOException {
-		Hashtable<String, ServicePermission> hashtable = new Hashtable<String, ServicePermission>(
-				permissions);
+	private synchronized void writeObject(ObjectOutputStream out) throws IOException {
+		Hashtable<String, ServicePermission> hashtable = new Hashtable<String, ServicePermission>(permissions);
 		ObjectOutputStream.PutField pfields = out.putFields();
 		pfields.put("permissions", hashtable);
 		pfields.put("all_allowed", all_allowed);
@@ -932,15 +899,12 @@ final class ServicePermissionCollection extends PermissionCollection {
 		out.writeFields();
 	}
 
-	private synchronized void readObject(java.io.ObjectInputStream in)
-			throws IOException, ClassNotFoundException {
+	private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
 		ObjectInputStream.GetField gfields = in.readFields();
-		Hashtable<String, ServicePermission> hashtable = (Hashtable<String, ServicePermission>) gfields
-				.get("permissions", null);
+		Hashtable<String, ServicePermission> hashtable = (Hashtable<String, ServicePermission>) gfields.get("permissions", null);
 		permissions = new HashMap<String, ServicePermission>(hashtable);
 		all_allowed = gfields.get("all_allowed", false);
-		HashMap<String, ServicePermission> fp = (HashMap<String, ServicePermission>) gfields
-				.get("filterPermissions", null);
+		HashMap<String, ServicePermission> fp = (HashMap<String, ServicePermission>) gfields.get("filterPermissions", null);
 		filterPermissions = fp;
 	}
 }
diff --git a/src/main/java/org/osgi/framework/ServiceReference.java b/src/main/java/org/osgi/framework/ServiceReference.java
index ad38df7..7541517 100644
--- a/src/main/java/org/osgi/framework/ServiceReference.java
+++ b/src/main/java/org/osgi/framework/ServiceReference.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,36 +26,36 @@ import java.util.Dictionary;
  * {@code BundleContext.getServiceReference} and
  * {@code BundleContext.getServiceReferences} methods.
  * <p>
- * A {@code ServiceReference} object may be shared between bundles and can
- * be used to examine the properties of the service and to get the service
- * object.
+ * A {@code ServiceReference} object may be shared between bundles and can be
+ * used to examine the properties of the service and to get the service object.
  * <p>
  * Every service registered in the Framework has a unique
  * {@code ServiceRegistration} object and may have multiple, distinct
- * {@code ServiceReference} objects referring to it.
- * {@code ServiceReference} objects associated with a
- * {@code ServiceRegistration} object have the same {@code hashCode}
- * and are considered equal (more specifically, their {@code equals()}
- * method will return {@code true} when compared).
+ * {@code ServiceReference} objects referring to it. {@code ServiceReference}
+ * objects associated with a {@code ServiceRegistration} object have the same
+ * {@code hashCode} and are considered equal (more specifically, their
+ * {@code equals()} method will return {@code true} when compared).
  * <p>
  * If the same service object is registered multiple times,
  * {@code ServiceReference} objects associated with different
  * {@code ServiceRegistration} objects are not equal.
  * 
  * @param <S> Type of Service.
- * @see BundleContext#getServiceReference
- * @see BundleContext#getServiceReferences
- * @see BundleContext#getService
+ * @see BundleContext#getServiceReference(Class)
+ * @see BundleContext#getServiceReference(String)
+ * @see BundleContext#getServiceReferences(Class, String)
+ * @see BundleContext#getServiceReferences(String, String)
+ * @see BundleContext#getService(ServiceReference)
  * @ThreadSafe
  * @noimplement
- * @version $Id: 771b9b4d4f65dbe593154d02912edba51a085b0c $
+ * @version $Id: 75352193f9f11a2c19692890153c6ff91611023b $
  */
 
 public interface ServiceReference<S> extends Comparable<Object> {
 	/**
 	 * Returns the property value to which the specified property key is mapped
-	 * in the properties {@code Dictionary} object of the service
-	 * referenced by this {@code ServiceReference} object.
+	 * in the properties {@code Dictionary} object of the service referenced by
+	 * this {@code ServiceReference} object.
 	 * 
 	 * <p>
 	 * Property keys are case-insensitive.
@@ -63,32 +63,31 @@ public interface ServiceReference<S> extends Comparable<Object> {
 	 * <p>
 	 * This method must continue to return property values after the service has
 	 * been unregistered. This is so references to unregistered services (for
-	 * example, {@code ServiceReference} objects stored in the log) can
-	 * still be interrogated.
+	 * example, {@code ServiceReference} objects stored in the log) can still be
+	 * interrogated.
 	 * 
 	 * @param key The property key.
-	 * @return The property value to which the key is mapped; {@code null}
-	 *         if there is no property named after the key.
+	 * @return The property value to which the key is mapped; {@code null} if
+	 *         there is no property named after the key.
 	 */
 	public Object getProperty(String key);
 
 	/**
-	 * Returns an array of the keys in the properties {@code Dictionary}
-	 * object of the service referenced by this {@code ServiceReference}
-	 * object.
+	 * Returns an array of the keys in the properties {@code Dictionary} object
+	 * of the service referenced by this {@code ServiceReference} object.
 	 * 
 	 * <p>
 	 * This method will continue to return the keys after the service has been
 	 * unregistered. This is so references to unregistered services (for
-	 * example, {@code ServiceReference} objects stored in the log) can
-	 * still be interrogated.
+	 * example, {@code ServiceReference} objects stored in the log) can still be
+	 * interrogated.
 	 * 
 	 * <p>
 	 * This method is <i>case-preserving </i>; this means that every key in the
 	 * returned array must have the same case as the corresponding key in the
 	 * properties {@code Dictionary} that was passed to the
 	 * {@link BundleContext#registerService(String[],Object,Dictionary)} or
-	 * {@link ServiceRegistration#setProperties} methods.
+	 * {@link ServiceRegistration#setProperties(Dictionary)} methods.
 	 * 
 	 * @return An array of property keys.
 	 */
@@ -104,21 +103,20 @@ public interface ServiceReference<S> extends Comparable<Object> {
 	 * unregistered.
 	 * 
 	 * @return The bundle that registered the service referenced by this
-	 *         {@code ServiceReference} object; {@code null} if that
-	 *         service has already been unregistered.
+	 *         {@code ServiceReference} object; {@code null} if that service has
+	 *         already been unregistered.
 	 * @see BundleContext#registerService(String[],Object,Dictionary)
 	 */
 	public Bundle getBundle();
 
 	/**
 	 * Returns the bundles that are using the service referenced by this
-	 * {@code ServiceReference} object. Specifically, this method returns
-	 * the bundles whose usage count for that service is greater than zero.
+	 * {@code ServiceReference} object. Specifically, this method returns the
+	 * bundles whose usage count for that service is greater than zero.
 	 * 
 	 * @return An array of bundles whose usage count for the service referenced
-	 *         by this {@code ServiceReference} object is greater than
-	 *         zero; {@code null} if no bundles are currently using that
-	 *         service.
+	 *         by this {@code ServiceReference} object is greater than zero;
+	 *         {@code null} if no bundles are currently using that service.
 	 * 
 	 * @since 1.1
 	 */
@@ -126,17 +124,16 @@ public interface ServiceReference<S> extends Comparable<Object> {
 
 	/**
 	 * Tests if the bundle that registered the service referenced by this
-	 * {@code ServiceReference} and the specified bundle use the same
-	 * source for the package of the specified class name.
+	 * {@code ServiceReference} and the specified bundle use the same source for
+	 * the package of the specified class name.
 	 * <p>
 	 * This method performs the following checks:
 	 * <ol>
 	 * <li>Get the package name from the specified class name.</li>
 	 * <li>For the bundle that registered the service referenced by this
-	 * {@code ServiceReference} (registrant bundle); find the source for
-	 * the package. If no source is found then return {@code true} if the
-	 * registrant bundle is equal to the specified bundle; otherwise return
-	 * {@code false}.</li>
+	 * {@code ServiceReference} (registrant bundle); find the source for the
+	 * package. If no source is found then return {@code true} if the registrant
+	 * bundle is equal to the specified bundle; otherwise return {@code false}.</li>
 	 * <li>If the package source of the registrant bundle is equal to the
 	 * package source of the specified bundle then return {@code true};
 	 * otherwise return {@code false}.</li>
@@ -145,11 +142,11 @@ public interface ServiceReference<S> extends Comparable<Object> {
 	 * @param bundle The {@code Bundle} object to check.
 	 * @param className The class name to check.
 	 * @return {@code true} if the bundle which registered the service
-	 *         referenced by this {@code ServiceReference} and the
-	 *         specified bundle use the same source for the package of the
-	 *         specified class name. Otherwise {@code false} is returned.
-	 * @throws IllegalArgumentException If the specified {@code Bundle} was
-	 *         not created by the same framework instance as this
+	 *         referenced by this {@code ServiceReference} and the specified
+	 *         bundle use the same source for the package of the specified class
+	 *         name. Otherwise {@code false} is returned.
+	 * @throws IllegalArgumentException If the specified {@code Bundle} was not
+	 *         created by the same framework instance as this
 	 *         {@code ServiceReference}.
 	 * @since 1.3
 	 */
@@ -162,24 +159,23 @@ public interface ServiceReference<S> extends Comparable<Object> {
 	 * <p>
 	 * If this {@code ServiceReference} and the specified
 	 * {@code ServiceReference} have the same {@link Constants#SERVICE_ID
-	 * service id} they are equal. This {@code ServiceReference} is less
-	 * than the specified {@code ServiceReference} if it has a lower
+	 * service id} they are equal. This {@code ServiceReference} is less than
+	 * the specified {@code ServiceReference} if it has a lower
 	 * {@link Constants#SERVICE_RANKING service ranking} and greater if it has a
-	 * higher service ranking. Otherwise, if this {@code ServiceReference}
-	 * and the specified {@code ServiceReference} have the same
+	 * higher service ranking. Otherwise, if this {@code ServiceReference} and
+	 * the specified {@code ServiceReference} have the same
 	 * {@link Constants#SERVICE_RANKING service ranking}, this
 	 * {@code ServiceReference} is less than the specified
-	 * {@code ServiceReference} if it has a higher
-	 * {@link Constants#SERVICE_ID service id} and greater if it has a lower
-	 * service id.
+	 * {@code ServiceReference} if it has a higher {@link Constants#SERVICE_ID
+	 * service id} and greater if it has a lower service id.
 	 * 
 	 * @param reference The {@code ServiceReference} to be compared.
 	 * @return Returns a negative integer, zero, or a positive integer if this
-	 *         {@code ServiceReference} is less than, equal to, or greater
-	 *         than the specified {@code ServiceReference}.
+	 *         {@code ServiceReference} is less than, equal to, or greater than
+	 *         the specified {@code ServiceReference}.
 	 * @throws IllegalArgumentException If the specified
-	 *         {@code ServiceReference} was not created by the same
-	 *         framework instance as this {@code ServiceReference}.
+	 *         {@code ServiceReference} was not created by the same framework
+	 *         instance as this {@code ServiceReference}.
 	 * @since 1.4
 	 */
 	public int compareTo(Object reference);
diff --git a/src/main/java/org/osgi/framework/ServiceRegistration.java b/src/main/java/org/osgi/framework/ServiceRegistration.java
index e4cfc0e..702e918 100644
--- a/src/main/java/org/osgi/framework/ServiceRegistration.java
+++ b/src/main/java/org/osgi/framework/ServiceRegistration.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,31 +23,28 @@ import java.util.Dictionary;
  * 
  * <p>
  * The Framework returns a {@code ServiceRegistration} object when a
- * {@code BundleContext.registerService} method invocation is successful.
- * The {@code ServiceRegistration} object is for the private use of the
- * registering bundle and should not be shared with other bundles.
+ * {@code BundleContext.registerService} method invocation is successful. The
+ * {@code ServiceRegistration} object is for the private use of the registering
+ * bundle and should not be shared with other bundles.
  * <p>
- * The {@code ServiceRegistration} object may be used to update the
- * properties of the service or to unregister the service.
+ * The {@code ServiceRegistration} object may be used to update the properties
+ * of the service or to unregister the service.
  * 
  * @param <S> Type of Service.
  * @see BundleContext#registerService(String[],Object,Dictionary)
  * @ThreadSafe
  * @noimplement
- * @version $Id: dc742ff3749821529f9ae62e05d9bd5d8eca00d7 $
+ * @version $Id: a84248da0db0538708d2394a9478153e06b8afb9 $
  */
 
 public interface ServiceRegistration<S> {
 	/**
-	 * Returns a {@code ServiceReference} object for a service being
-	 * registered.
+	 * Returns a {@code ServiceReference} object for a service being registered.
 	 * <p>
-	 * The {@code ServiceReference} object may be shared with other
-	 * bundles.
+	 * The {@code ServiceReference} object may be shared with other bundles.
 	 * 
-	 * @throws IllegalStateException If this
-	 *         {@code ServiceRegistration} object has already been
-	 *         unregistered.
+	 * @throws IllegalStateException If this {@code ServiceRegistration} object
+	 *         has already been unregistered.
 	 * @return {@code ServiceReference} object.
 	 */
 	public ServiceReference<S> getReference();
@@ -72,43 +69,41 @@ public interface ServiceRegistration<S> {
 	 *        be made to this object after calling this method. To update the
 	 *        service's properties this method should be called again.
 	 * 
-	 * @throws IllegalStateException If this {@code ServiceRegistration}
-	 *         object has already been unregistered.
-	 * @throws IllegalArgumentException If {@code properties} contains
-	 *         case variants of the same key name.
+	 * @throws IllegalStateException If this {@code ServiceRegistration} object
+	 *         has already been unregistered.
+	 * @throws IllegalArgumentException If {@code properties} contains case
+	 *         variants of the same key name.
 	 */
-	public void setProperties(Dictionary<String, ? > properties);
+	public void setProperties(Dictionary<String, ?> properties);
 
 	/**
-	 * Unregisters a service. Remove a {@code ServiceRegistration} object
-	 * from the Framework service registry. All {@code ServiceReference}
-	 * objects associated with this {@code ServiceRegistration} object
-	 * can no longer be used to interact with the service once unregistration is
-	 * complete.
+	 * Unregisters a service. Remove a {@code ServiceRegistration} object from
+	 * the Framework service registry. All {@code ServiceReference} objects
+	 * associated with this {@code ServiceRegistration} object can no longer be
+	 * used to interact with the service once unregistration is complete.
 	 * 
 	 * <p>
 	 * The following steps are required to unregister a service:
 	 * <ol>
-	 * <li>The service is removed from the Framework service registry so that
-	 * it can no longer be obtained.
+	 * <li>The service is removed from the Framework service registry so that it
+	 * can no longer be obtained.
 	 * <li>A service event of type {@link ServiceEvent#UNREGISTERING} is fired
 	 * so that bundles using this service can release their use of the service.
 	 * Once delivery of the service event is complete, the
-	 * {@code ServiceReference} objects for the service may no longer be
-	 * used to get a service object for the service.
+	 * {@code ServiceReference} objects for the service may no longer be used to
+	 * get a service object for the service.
 	 * <li>For each bundle whose use count for this service is greater than
 	 * zero: <br>
 	 * The bundle's use count for this service is set to zero. <br>
 	 * If the service was registered with a {@link ServiceFactory} object, the
-	 * {@code ServiceFactory.ungetService} method is called to release
-	 * the service object for the bundle.
+	 * {@code ServiceFactory.ungetService} method is called to release the
+	 * service object for the bundle.
 	 * </ol>
 	 * 
-	 * @throws IllegalStateException If this
-	 *         {@code ServiceRegistration} object has already been
-	 *         unregistered.
-	 * @see BundleContext#ungetService
-	 * @see ServiceFactory#ungetService
+	 * @throws IllegalStateException If this {@code ServiceRegistration} object
+	 *         has already been unregistered.
+	 * @see BundleContext#ungetService(ServiceReference)
+	 * @see ServiceFactory#ungetService(Bundle, ServiceRegistration, Object)
 	 */
 	public void unregister();
 }
diff --git a/src/main/java/org/osgi/framework/SignerProperty.java b/src/main/java/org/osgi/framework/SignerProperty.java
index 8b357c1..9236dfa 100644
--- a/src/main/java/org/osgi/framework/SignerProperty.java
+++ b/src/main/java/org/osgi/framework/SignerProperty.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2009, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2009, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ import java.util.Map;
  * during filter expression evaluation in the permission implies method.
  * 
  * @Immutable
- * @version $Id: 3589831a7594cf36e645a51ab9b9ae5ebfd80beb $
+ * @version $Id: 94eea19050b84907f1257d7a12ebf8ab404f4473 $
  */
 final class SignerProperty {
 	private final Bundle	bundle;
@@ -70,20 +70,17 @@ final class SignerProperty {
 		SignerProperty other = (SignerProperty) o;
 		Bundle matchBundle = bundle != null ? bundle : other.bundle;
 		String matchPattern = bundle != null ? other.pattern : pattern;
-		Map<X509Certificate, List<X509Certificate>> signers = matchBundle
-				.getSignerCertificates(Bundle.SIGNERS_TRUSTED);
+		Map<X509Certificate, List<X509Certificate>> signers = matchBundle.getSignerCertificates(Bundle.SIGNERS_TRUSTED);
 		for (List<X509Certificate> signerCerts : signers.values()) {
 			List<String> dnChain = new ArrayList<String>(signerCerts.size());
 			for (X509Certificate signerCert : signerCerts) {
 				dnChain.add(signerCert.getSubjectDN().getName());
 			}
 			try {
-				if (FrameworkUtil.matchDistinguishedNameChain(matchPattern,
-						dnChain)) {
+				if (FrameworkUtil.matchDistinguishedNameChain(matchPattern, dnChain)) {
 					return true;
 				}
-			}
-			catch (IllegalArgumentException e) {
+			} catch (IllegalArgumentException e) {
 				continue; // bad pattern
 			}
 		}
@@ -107,8 +104,7 @@ final class SignerProperty {
 		if (bundle == null) {
 			return false;
 		}
-		Map<X509Certificate, List<X509Certificate>> signers = bundle
-				.getSignerCertificates(Bundle.SIGNERS_TRUSTED);
+		Map<X509Certificate, List<X509Certificate>> signers = bundle.getSignerCertificates(Bundle.SIGNERS_TRUSTED);
 		return !signers.isEmpty();
 	}
 }
diff --git a/src/main/java/org/osgi/framework/SynchronousBundleListener.java b/src/main/java/org/osgi/framework/SynchronousBundleListener.java
index 227dc59..ee8474c 100644
--- a/src/main/java/org/osgi/framework/SynchronousBundleListener.java
+++ b/src/main/java/org/osgi/framework/SynchronousBundleListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2001, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2011). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,38 +17,37 @@
 package org.osgi.framework;
 
 /**
- * A synchronous {@code BundleEvent} listener.
- * {@code SynchronousBundleListener} is a listener interface that may be
- * implemented by a bundle developer. When a {@code BundleEvent} is fired,
- * it is synchronously delivered to a {@code SynchronousBundleListener}.
- * The Framework may deliver {@code BundleEvent} objects to a
- * {@code SynchronousBundleListener} out of order and may concurrently call
- * and/or reenter a {@code SynchronousBundleListener}.
+ * A synchronous {@code BundleEvent} listener. {@code SynchronousBundleListener}
+ * is a listener interface that may be implemented by a bundle developer. When a
+ * {@code BundleEvent} is fired, it is synchronously delivered to a
+ * {@code SynchronousBundleListener}. The Framework may deliver
+ * {@code BundleEvent} objects to a {@code SynchronousBundleListener} out of
+ * order and may concurrently call and/or reenter a
+ * {@code SynchronousBundleListener}.
  * 
  * <p>
  * For {@code BundleEvent} types {@link BundleEvent#STARTED STARTED} and
  * {@link BundleEvent#LAZY_ACTIVATION LAZY_ACTIVATION}, the Framework must not
  * hold the referenced bundle's "state change" lock when the
- * {@code BundleEvent} is delivered to a
- * {@code SynchronousBundleListener}. For the other
- * {@code BundleEvent} types, the Framework must hold the referenced
+ * {@code BundleEvent} is delivered to a {@code SynchronousBundleListener}. For
+ * the other {@code BundleEvent} types, the Framework must hold the referenced
  * bundle's "state change" lock when the {@code BundleEvent} is
  * delivered to a {@code SynchronousBundleListener}. A
- * {@code SynchronousBundleListener} cannot directly call life cycle
- * methods on the referenced bundle when the Framework is holding the referenced
- * bundle's "state change" lock.
+ * {@code SynchronousBundleListener} cannot directly call life cycle methods on
+ * the referenced bundle when the Framework is holding the referenced bundle's
+ * "state change" lock.
  * 
  * <p>
- * A {@code SynchronousBundleListener} object is registered with the
- * Framework using the {@link BundleContext#addBundleListener} method.
+ * A {@code SynchronousBundleListener} object is registered with the Framework
+ * using the {@link BundleContext#addBundleListener(BundleListener)} method.
  * {@code SynchronousBundleListener} objects are called with a
  * {@code BundleEvent} object when a bundle has been installed, resolved,
  * starting, started, stopping, stopped, updated, unresolved, or uninstalled.
  * <p>
  * Unlike normal {@code BundleListener} objects,
- * {@code SynchronousBundleListener}s are synchronously called during
- * bundle lifecycle processing. The bundle lifecycle processing will not proceed
- * until all {@code SynchronousBundleListener}s have completed.
+ * {@code SynchronousBundleListener}s are synchronously called during bundle
+ * lifecycle processing. The bundle lifecycle processing will not proceed until
+ * all {@code SynchronousBundleListener}s have completed.
  * {@code SynchronousBundleListener} objects will be called prior to
  * {@code BundleListener} objects.
  * <p>
@@ -58,7 +57,7 @@ package org.osgi.framework;
  * @since 1.1
  * @see BundleEvent
  * @ThreadSafe
- * @version $Id: b22484f48ebdcb2141da9bba9eb65f5c40e0f520 $
+ * @version $Id: 74246f4ceeba7f9a5ee198048522f93d4691c51a $
  */
 
 public interface SynchronousBundleListener extends BundleListener {
diff --git a/src/main/java/org/osgi/framework/UnfilteredServiceListener.java b/src/main/java/org/osgi/framework/UnfilteredServiceListener.java
new file mode 100644
index 0000000..d712fcf
--- /dev/null
+++ b/src/main/java/org/osgi/framework/UnfilteredServiceListener.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import org.osgi.framework.hooks.service.ListenerHook;
+
+/**
+ * A {@code ServiceEvent} listener that does <i>not</i> filter based upon any
+ * filter string specified to
+ * {@link BundleContext#addServiceListener(ServiceListener, String)}. Using an
+ * {@code UnfilteredServiceListener} and specifying a filter string to
+ * {@link BundleContext#addServiceListener(ServiceListener, String)} allows the
+ * listener to receive all {@code ServiceEvent} objects while still advising
+ * {@link ListenerHook} implementation of the service interests in the filter
+ * string.
+ * 
+ * For example, an implementation of Declarative Services would add an
+ * {@code UnfilteredServiceListener} with a filter string listing all the
+ * services referenced by all the service components. The Declarative Services
+ * implementation would receive all {@code ServiceEvent} objects for internal
+ * processing and a Remote Services discovery service implementation can observe
+ * the service interests of the service components using a {@link ListenerHook}.
+ * When the set of service components being processed changes, the Declarative
+ * Services implementation would re-add the {@code UnfilteredServiceListener}
+ * with an updated filter string.
+ * 
+ * <p>
+ * When a {@code ServiceEvent} is fired, it is synchronously delivered to an
+ * {@code UnfilteredServiceListener}. The Framework may deliver
+ * {@code ServiceEvent} objects to an {@code UnfilteredServiceListener} out of
+ * order and may concurrently call and/or reenter an
+ * {@code UnfilteredServiceListener}.
+ * 
+ * <p>
+ * An {@code UnfilteredServiceListener} object is registered with the Framework
+ * using the {@code BundleContext.addServiceListener} method.
+ * {@code UnfilteredServiceListener} objects are called with a
+ * {@code ServiceEvent} object when a service is registered, modified, or is in
+ * the process of unregistering.
+ * 
+ * <p>
+ * {@code ServiceEvent} object delivery to {@code UnfilteredServiceListener}
+ * objects are <i>not</i> filtered by the filter specified when the listener was
+ * registered. If the Java Runtime Environment supports permissions, then some
+ * filtering is done. {@code ServiceEvent} objects are only delivered to the
+ * listener if the bundle which defines the listener object's class has the
+ * appropriate {@code ServicePermission} to get the service using at least one
+ * of the named classes under which the service was registered.
+ * 
+ * @see ServiceEvent
+ * @see ServicePermission
+ * @ThreadSafe
+ * @since 1.7
+ * @version $Id: 543a345802f8dc7a49d29e8fb7aee7004ee2b329 $
+ */
+
+public interface UnfilteredServiceListener extends ServiceListener {
+	// This is a marker interface
+}
diff --git a/src/main/java/org/osgi/framework/Version.java b/src/main/java/org/osgi/framework/Version.java
index fd2484e..02f6ddd 100644
--- a/src/main/java/org/osgi/framework/Version.java
+++ b/src/main/java/org/osgi/framework/Version.java
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
- * 
+ * Copyright (c) OSGi Alliance (2004, 2012). All Rights Reserved.
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
@@ -20,7 +20,7 @@ import java.util.NoSuchElementException;
 import java.util.StringTokenizer;
 
 /**
- * Version identifier for bundles and packages.
+ * Version identifier for capabilities such as bundles and packages.
  * 
  * <p>
  * Version identifiers have four components.
@@ -28,8 +28,8 @@ import java.util.StringTokenizer;
  * <li>Major version. A non-negative integer.</li>
  * <li>Minor version. A non-negative integer.</li>
  * <li>Micro version. A non-negative integer.</li>
- * <li>Qualifier. A text string. See {@code Version(String)} for the
- * format of the qualifier string.</li>
+ * <li>Qualifier. A text string. See {@code Version(String)} for the format of
+ * the qualifier string.</li>
  * </ol>
  * 
  * <p>
@@ -37,7 +37,7 @@ import java.util.StringTokenizer;
  * 
  * @since 1.3
  * @Immutable
- * @version $Id: a71e2e2d7685e65b5bbe375efdf97fda16eff0a5 $
+ * @version $Id: a0b5a865f7fbf2b3dcb77a13b2e99da0b64702bb $
  */
 
 public class Version implements Comparable<Version> {
@@ -46,7 +46,8 @@ public class Version implements Comparable<Version> {
 	private final int			micro;
 	private final String		qualifier;
 	private static final String	SEPARATOR		= ".";
-	private transient String	versionString;
+	private transient String	versionString /* default to null */;
+	private transient int		hash /* default to 0 */;
 
 	/**
 	 * The empty version "0.0.0".
@@ -76,8 +77,8 @@ public class Version implements Comparable<Version> {
 	 * @param minor Minor component of the version identifier.
 	 * @param micro Micro component of the version identifier.
 	 * @param qualifier Qualifier component of the version identifier. If
-	 *        {@code null} is specified, then the qualifier will be set to
-	 *        the empty string.
+	 *        {@code null} is specified, then the qualifier will be set to the
+	 *        empty string.
 	 * @throws IllegalArgumentException If the numerical components are negative
 	 *         or the qualifier string is invalid.
 	 */
@@ -90,15 +91,14 @@ public class Version implements Comparable<Version> {
 		this.minor = minor;
 		this.micro = micro;
 		this.qualifier = qualifier;
-		versionString = null;
 		validate();
 	}
 
 	/**
-	 * Created a version identifier from the specified string.
+	 * Creates a version identifier from the specified string.
 	 * 
 	 * <p>
-	 * Here is the grammar for version strings.
+	 * Version string grammar:
 	 * 
 	 * <pre>
 	 * version ::= major('.'minor('.'micro('.'qualifier)?)?)?
@@ -110,9 +110,8 @@ public class Version implements Comparable<Version> {
 	 * alpha ::= [a..zA..Z]
 	 * </pre>
 	 * 
-	 * There must be no whitespace in version.
-	 * 
-	 * @param version String representation of the version identifier.
+	 * @param version String representation of the version identifier. There
+	 *        must be no whitespace in the argument.
 	 * @throws IllegalArgumentException If {@code version} is improperly
 	 *         formatted.
 	 */
@@ -124,31 +123,28 @@ public class Version implements Comparable<Version> {
 
 		try {
 			StringTokenizer st = new StringTokenizer(version, SEPARATOR, true);
-			maj = Integer.parseInt(st.nextToken());
+			maj = parseInt(st.nextToken(), version);
 
 			if (st.hasMoreTokens()) { // minor
 				st.nextToken(); // consume delimiter
-				min = Integer.parseInt(st.nextToken());
+				min = parseInt(st.nextToken(), version);
 
 				if (st.hasMoreTokens()) { // micro
 					st.nextToken(); // consume delimiter
-					mic = Integer.parseInt(st.nextToken());
+					mic = parseInt(st.nextToken(), version);
 
-					if (st.hasMoreTokens()) { // qualifier
+					if (st.hasMoreTokens()) { // qualifier separator
 						st.nextToken(); // consume delimiter
 						qual = st.nextToken(""); // remaining string
 
 						if (st.hasMoreTokens()) { // fail safe
-							throw new IllegalArgumentException(
-									"invalid format: " + version);
+							throw new IllegalArgumentException("invalid version \"" + version + "\": invalid format");
 						}
 					}
 				}
 			}
-		}
-		catch (NoSuchElementException e) {
-			IllegalArgumentException iae = new IllegalArgumentException(
-					"invalid format: " + version);
+		} catch (NoSuchElementException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid version \"" + version + "\": invalid format");
 			iae.initCause(e);
 			throw iae;
 		}
@@ -157,11 +153,27 @@ public class Version implements Comparable<Version> {
 		minor = min;
 		micro = mic;
 		qualifier = qual;
-		versionString = null;
 		validate();
 	}
 
 	/**
+	 * Parse numeric component into an int.
+	 * 
+	 * @param value Numeric component
+	 * @param version Complete version string for exception message, if any
+	 * @return int value of numeric component
+	 */
+	private static int parseInt(String value, String version) {
+		try {
+			return Integer.parseInt(value);
+		} catch (NumberFormatException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid version \"" + version + "\": non-numeric \"" + value + "\"");
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
 	 * Called by the Version constructors to validate the version components.
 	 * 
 	 * @throws IllegalArgumentException If the numerical components are negative
@@ -169,17 +181,15 @@ public class Version implements Comparable<Version> {
 	 */
 	private void validate() {
 		if (major < 0) {
-			throw new IllegalArgumentException("negative major");
+			throw new IllegalArgumentException("invalid version \"" + toString0() + "\": negative number \"" + major + "\"");
 		}
 		if (minor < 0) {
-			throw new IllegalArgumentException("negative minor");
+			throw new IllegalArgumentException("invalid version \"" + toString0() + "\": negative number \"" + minor + "\"");
 		}
 		if (micro < 0) {
-			throw new IllegalArgumentException("negative micro");
+			throw new IllegalArgumentException("invalid version \"" + toString0() + "\": negative number \"" + micro + "\"");
 		}
-		char[] chars = qualifier.toCharArray();
-		for (int i = 0, length = chars.length; i < length; i++) {
-	        char ch = chars[i];
+		for (char ch : qualifier.toCharArray()) {
 			if (('A' <= ch) && (ch <= 'Z')) {
 				continue;
 			}
@@ -192,8 +202,7 @@ public class Version implements Comparable<Version> {
 			if ((ch == '_') || (ch == '-')) {
 				continue;
 			}
-			throw new IllegalArgumentException("invalid qualifier: "
-					+ qualifier);
+			throw new IllegalArgumentException("invalid version \"" + toString0() + "\": invalid qualifier \"" + qualifier + "\"");
 		}
 	}
 
@@ -205,10 +214,9 @@ public class Version implements Comparable<Version> {
 	 * 
 	 * @param version String representation of the version identifier. Leading
 	 *        and trailing whitespace will be ignored.
-	 * @return A {@code Version} object representing the version
-	 *         identifier. If {@code version} is {@code null} or
-	 *         the empty string then {@code emptyVersion} will be
-	 *         returned.
+	 * @return A {@code Version} object representing the version identifier. If
+	 *         {@code version} is {@code null} or the empty string then
+	 *         {@code emptyVersion} will be returned.
 	 * @throws IllegalArgumentException If {@code version} is improperly
 	 *         formatted.
 	 */
@@ -265,13 +273,22 @@ public class Version implements Comparable<Version> {
 	 * Returns the string representation of this version identifier.
 	 * 
 	 * <p>
-	 * The format of the version string will be {@code major.minor.micro}
-	 * if qualifier is the empty string or
-	 * {@code major.minor.micro.qualifier} otherwise.
+	 * The format of the version string will be {@code major.minor.micro} if
+	 * qualifier is the empty string or {@code major.minor.micro.qualifier}
+	 * otherwise.
 	 * 
 	 * @return The string representation of this version identifier.
 	 */
 	public String toString() {
+		return toString0();
+	}
+
+	/**
+	 * Internal toString behavior
+	 * 
+	 * @return The string representation of this version identifier.
+	 */
+	String toString0() {
 		if (versionString != null) {
 			return versionString;
 		}
@@ -295,8 +312,15 @@ public class Version implements Comparable<Version> {
 	 * @return An integer which is a hash code value for this object.
 	 */
 	public int hashCode() {
-		return (major << 24) + (minor << 16) + (micro << 8)
-				+ qualifier.hashCode();
+		if (hash != 0) {
+			return hash;
+		}
+		int h = 31 * 17;
+		h = 31 * h + major;
+		h = 31 * h + minor;
+		h = 31 * h + micro;
+		h = 31 * h + qualifier.hashCode();
+		return hash = h;
 	}
 
 	/**
@@ -308,9 +332,8 @@ public class Version implements Comparable<Version> {
 	 * is equal (using {@code String.equals}).
 	 * 
 	 * @param object The {@code Version} object to be compared.
-	 * @return {@code true} if {@code object} is a
-	 *         {@code Version} and is equal to this object;
-	 *         {@code false} otherwise.
+	 * @return {@code true} if {@code object} is a {@code Version} and is equal
+	 *         to this object; {@code false} otherwise.
 	 */
 	public boolean equals(Object object) {
 		if (object == this) { // quicktest
@@ -322,15 +345,14 @@ public class Version implements Comparable<Version> {
 		}
 
 		Version other = (Version) object;
-		return (major == other.major) && (minor == other.minor)
-				&& (micro == other.micro) && qualifier.equals(other.qualifier);
+		return (major == other.major) && (minor == other.minor) && (micro == other.micro) && qualifier.equals(other.qualifier);
 	}
 
 	/**
 	 * Compares this {@code Version} object to another {@code Version}.
 	 * 
 	 * <p>
-	 * A version is considered to be <b>less than </b> another version if its
+	 * A version is considered to be <b>less than</b> another version if its
 	 * major component is less than the other version's major component, or the
 	 * major components are equal and its minor component is less than the other
 	 * version's minor component, or the major and minor components are equal
diff --git a/src/main/java/org/osgi/framework/VersionRange.java b/src/main/java/org/osgi/framework/VersionRange.java
new file mode 100644
index 0000000..0589a75
--- /dev/null
+++ b/src/main/java/org/osgi/framework/VersionRange.java
@@ -0,0 +1,509 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+/**
+ * Version range. A version range is an interval describing a set of
+ * {@link Version versions}.
+ * 
+ * <p>
+ * A range has a left (lower) endpoint and a right (upper) endpoint. Each
+ * endpoint can be open (excluded from the set) or closed (included in the set).
+ * 
+ * <p>
+ * {@code VersionRange} objects are immutable.
+ * 
+ * @since 1.7
+ * @Immutable
+ * @version $Id: d0c21e6a5015a7fa0b33179a29122ea7d137145a $
+ */
+
+public class VersionRange {
+	/**
+	 * The left endpoint is open and is excluded from the range.
+	 * <p>
+	 * The value of {@code LEFT_OPEN} is {@code '('}.
+	 */
+	public static final char	LEFT_OPEN				= '(';
+	/**
+	 * The left endpoint is closed and is included in the range.
+	 * <p>
+	 * The value of {@code LEFT_CLOSED} is {@code '['}.
+	 */
+	public static final char	LEFT_CLOSED				= '[';
+	/**
+	 * The right endpoint is open and is excluded from the range.
+	 * <p>
+	 * The value of {@code RIGHT_OPEN} is {@code ')'}.
+	 */
+	public static final char	RIGHT_OPEN				= ')';
+	/**
+	 * The right endpoint is closed and is included in the range.
+	 * <p>
+	 * The value of {@code RIGHT_CLOSED} is {@code ']'}.
+	 */
+	public static final char	RIGHT_CLOSED			= ']';
+
+	private final boolean		leftClosed;
+	private final Version		left;
+	private final Version		right;
+	private final boolean		rightClosed;
+	private final boolean		empty;
+
+	private transient String	versionRangeString /* default to null */;
+	private transient int		hash /* default to 0 */;
+
+	private static final String	LEFT_OPEN_DELIMITER		= "(";
+	private static final String	LEFT_CLOSED_DELIMITER	= "[";
+	private static final String	LEFT_DELIMITERS			= LEFT_CLOSED_DELIMITER + LEFT_OPEN_DELIMITER;
+	private static final String	RIGHT_OPEN_DELIMITER	= ")";
+	private static final String	RIGHT_CLOSED_DELIMITER	= "]";
+	private static final String	RIGHT_DELIMITERS		= RIGHT_OPEN_DELIMITER + RIGHT_CLOSED_DELIMITER;
+	private static final String	ENDPOINT_DELIMITER		= ",";
+
+	/**
+	 * Creates a version range from the specified versions.
+	 * 
+	 * @param leftType Must be either {@link #LEFT_CLOSED} or {@link #LEFT_OPEN}
+	 *        .
+	 * @param leftEndpoint Left endpoint of range. Must not be {@code null}.
+	 * @param rightEndpoint Right endpoint of range. May be {@code null} to
+	 *        indicate the right endpoint is <i>Infinity</i>.
+	 * @param rightType Must be either {@link #RIGHT_CLOSED} or
+	 *        {@link #RIGHT_OPEN}.
+	 * @throws IllegalArgumentException If the arguments are invalid.
+	 */
+	public VersionRange(char leftType, Version leftEndpoint, Version rightEndpoint, char rightType) {
+		if ((leftType != LEFT_CLOSED) && (leftType != LEFT_OPEN)) {
+			throw new IllegalArgumentException("invalid leftType \"" + leftType + "\"");
+		}
+		if ((rightType != RIGHT_OPEN) && (rightType != RIGHT_CLOSED)) {
+			throw new IllegalArgumentException("invalid rightType \"" + rightType + "\"");
+		}
+		if (leftEndpoint == null) {
+			throw new IllegalArgumentException("null leftEndpoint argument");
+		}
+		leftClosed = leftType == LEFT_CLOSED;
+		rightClosed = rightType == RIGHT_CLOSED;
+		left = leftEndpoint;
+		right = rightEndpoint;
+		empty = isEmpty0();
+	}
+
+	/**
+	 * Creates a version range from the specified string.
+	 * 
+	 * <p>
+	 * Version range string grammar:
+	 * 
+	 * <pre>
+	 * range ::= interval | atleast
+	 * interval ::= ( '[' | '(' ) left ',' right ( ']' | ')' )
+	 * left ::= version
+	 * right ::= version
+	 * atleast ::= version
+	 * </pre>
+	 * 
+	 * @param range String representation of the version range. The versions in
+	 *        the range must contain no whitespace. Other whitespace in the
+	 *        range string is ignored.
+	 * @throws IllegalArgumentException If {@code range} is improperly
+	 *         formatted.
+	 */
+	public VersionRange(String range) {
+		boolean closedLeft;
+		boolean closedRight;
+		Version endpointLeft;
+		Version endpointRight;
+
+		try {
+			StringTokenizer st = new StringTokenizer(range, LEFT_DELIMITERS, true);
+			String token = st.nextToken().trim(); // whitespace or left delim
+			if (token.length() == 0) { // leading whitespace
+				token = st.nextToken(); // left delim
+			}
+			closedLeft = LEFT_CLOSED_DELIMITER.equals(token);
+			if (!closedLeft && !LEFT_OPEN_DELIMITER.equals(token)) {
+				// first token is not a delimiter, so it must be "atleast"
+				if (st.hasMoreTokens()) { // there must be no more tokens
+					throw new IllegalArgumentException("invalid range \"" + range + "\": invalid format");
+				}
+				leftClosed = true;
+				rightClosed = false;
+				left = parseVersion(token, range);
+				right = null;
+				empty = false;
+				return;
+			}
+			String version = st.nextToken(ENDPOINT_DELIMITER);
+			endpointLeft = parseVersion(version, range);
+			token = st.nextToken(); // consume comma
+			version = st.nextToken(RIGHT_DELIMITERS);
+			token = st.nextToken(); // right delim
+			closedRight = RIGHT_CLOSED_DELIMITER.equals(token);
+			if (!closedRight && !RIGHT_OPEN_DELIMITER.equals(token)) {
+				throw new IllegalArgumentException("invalid range \"" + range + "\": invalid format");
+			}
+			endpointRight = parseVersion(version, range);
+
+			if (st.hasMoreTokens()) { // any more tokens have to be whitespace
+				token = st.nextToken("").trim();
+				if (token.length() != 0) { // trailing whitespace
+					throw new IllegalArgumentException("invalid range \"" + range + "\": invalid format");
+				}
+			}
+		} catch (NoSuchElementException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid range \"" + range + "\": invalid format");
+			iae.initCause(e);
+			throw iae;
+		}
+
+		leftClosed = closedLeft;
+		rightClosed = closedRight;
+		left = endpointLeft;
+		right = endpointRight;
+		empty = isEmpty0();
+	}
+
+	/**
+	 * Parse version component into a Version.
+	 * 
+	 * @param version version component string
+	 * @param range Complete range string for exception message, if any
+	 * @return Version
+	 */
+	private static Version parseVersion(String version, String range) {
+		try {
+			return Version.parseVersion(version);
+		} catch (IllegalArgumentException e) {
+			IllegalArgumentException iae = new IllegalArgumentException("invalid range \"" + range + "\": " + e.getMessage());
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
+	 * Returns the left endpoint of this version range.
+	 * 
+	 * @return The left endpoint.
+	 */
+	public Version getLeft() {
+		return left;
+	}
+
+	/**
+	 * Returns the right endpoint of this version range.
+	 * 
+	 * @return The right endpoint. May be {@code null} which indicates the right
+	 *         endpoint is <i>Infinity</i>.
+	 */
+	public Version getRight() {
+		return right;
+	}
+
+	/**
+	 * Returns the type of the left endpoint of this version range.
+	 * 
+	 * @return {@link #LEFT_CLOSED} if the left endpoint is closed or
+	 *         {@link #LEFT_OPEN} if the left endpoint is open.
+	 */
+	public char getLeftType() {
+		return leftClosed ? LEFT_CLOSED : LEFT_OPEN;
+	}
+
+	/**
+	 * Returns the type of the right endpoint of this version range.
+	 * 
+	 * @return {@link #RIGHT_CLOSED} if the right endpoint is closed or
+	 *         {@link #RIGHT_OPEN} if the right endpoint is open.
+	 */
+	public char getRightType() {
+		return rightClosed ? RIGHT_CLOSED : RIGHT_OPEN;
+	}
+
+	/**
+	 * Returns whether this version range includes the specified version.
+	 * 
+	 * @param version The version to test for inclusion in this version range.
+	 * @return {@code true} if the specified version is included in this version
+	 *         range; {@code false} otherwise.
+	 */
+	public boolean includes(Version version) {
+		if (empty) {
+			return false;
+		}
+		if (left.compareTo(version) >= (leftClosed ? 1 : 0)) {
+			return false;
+		}
+		if (right == null) {
+			return true;
+		}
+		return right.compareTo(version) >= (rightClosed ? 0 : 1);
+	}
+
+	/**
+	 * Returns the intersection of this version range with the specified version
+	 * ranges.
+	 * 
+	 * @param ranges The version ranges to intersect with this version range.
+	 * @return A version range representing the intersection of this version
+	 *         range and the specified version ranges. If no version ranges are
+	 *         specified, then this version range is returned.
+	 */
+	public VersionRange intersection(VersionRange... ranges) {
+		if ((ranges == null) || (ranges.length == 0)) {
+			return this;
+		}
+		// prime with data from this version range
+		boolean closedLeft = leftClosed;
+		boolean closedRight = rightClosed;
+		Version endpointLeft = left;
+		Version endpointRight = right;
+
+		for (VersionRange range : ranges) {
+			int comparison = endpointLeft.compareTo(range.left);
+			if (comparison == 0) {
+				closedLeft = closedLeft && range.leftClosed;
+			} else {
+				if (comparison < 0) { // move endpointLeft to the right
+					endpointLeft = range.left;
+					closedLeft = range.leftClosed;
+				}
+			}
+			if (range.right != null) {
+				if (endpointRight == null) {
+					endpointRight = range.right;
+					closedRight = range.rightClosed;
+				} else {
+					comparison = endpointRight.compareTo(range.right);
+					if (comparison == 0) {
+						closedRight = closedRight && range.rightClosed;
+					} else {
+						if (comparison > 0) { // move endpointRight to the left
+							endpointRight = range.right;
+							closedRight = range.rightClosed;
+						}
+					}
+				}
+			}
+		}
+
+		return new VersionRange(closedLeft ? LEFT_CLOSED : LEFT_OPEN, endpointLeft, endpointRight, closedRight ? RIGHT_CLOSED : RIGHT_OPEN);
+	}
+
+	/**
+	 * Returns whether this version range is empty. A version range is empty if
+	 * the set of versions defined by the interval is empty.
+	 * 
+	 * @return {@code true} if this version range is empty; {@code false}
+	 *         otherwise.
+	 */
+	public boolean isEmpty() {
+		return empty;
+	}
+
+	/**
+	 * Internal isEmpty behavior.
+	 * 
+	 * @return {@code true} if this version range is empty; {@code false}
+	 *         otherwise.
+	 */
+	private boolean isEmpty0() {
+		if (right == null) { // infinity
+			return false;
+		}
+		int comparison = left.compareTo(right);
+		if (comparison == 0) { // endpoints equal
+			return !leftClosed || !rightClosed;
+		}
+		return comparison > 0; // true if left > right
+	}
+
+	/**
+	 * Returns whether this version range contains only a single version.
+	 * 
+	 * @return {@code true} if this version range contains only a single
+	 *         version; {@code false} otherwise.
+	 */
+	public boolean isExact() {
+		if (empty || (right == null)) {
+			return false;
+		}
+		if (leftClosed) {
+			if (rightClosed) {
+				// [l,r]: exact if l == r
+				return left.equals(right);
+			} else {
+				// [l,r): exact if l++ >= r
+				Version adjacent1 = new Version(left.getMajor(), left.getMinor(), left.getMicro(), left.getQualifier() + "-");
+				return adjacent1.compareTo(right) >= 0;
+			}
+		} else {
+			if (rightClosed) {
+				// (l,r] is equivalent to [l++,r]: exact if l++ == r
+				Version adjacent1 = new Version(left.getMajor(), left.getMinor(), left.getMicro(), left.getQualifier() + "-");
+				return adjacent1.equals(right);
+			} else {
+				// (l,r) is equivalent to [l++,r): exact if (l++)++ >=r
+				Version adjacent2 = new Version(left.getMajor(), left.getMinor(), left.getMicro(), left.getQualifier() + "--");
+				return adjacent2.compareTo(right) >= 0;
+			}
+		}
+	}
+
+	/**
+	 * Returns the string representation of this version range.
+	 * 
+	 * <p>
+	 * The format of the version range string will be a version string if the
+	 * right end point is <i>Infinity</i> ({@code null}) or an interval string.
+	 * 
+	 * @return The string representation of this version range.
+	 */
+	public String toString() {
+		if (versionRangeString != null) {
+			return versionRangeString;
+		}
+		String leftVersion = left.toString();
+		if (right == null) {
+			StringBuffer result = new StringBuffer(leftVersion.length() + 1);
+			result.append(left.toString0());
+			return versionRangeString = result.toString();
+		}
+		String rightVerion = right.toString();
+		StringBuffer result = new StringBuffer(leftVersion.length() + rightVerion.length() + 5);
+		result.append(leftClosed ? LEFT_CLOSED : LEFT_OPEN);
+		result.append(left.toString0());
+		result.append(ENDPOINT_DELIMITER);
+		result.append(right.toString0());
+		result.append(rightClosed ? RIGHT_CLOSED : RIGHT_OPEN);
+		return versionRangeString = result.toString();
+	}
+
+	/**
+	 * Returns a hash code value for the object.
+	 * 
+	 * @return An integer which is a hash code value for this object.
+	 */
+	public int hashCode() {
+		if (hash != 0) {
+			return hash;
+		}
+		if (empty) {
+			return hash = 31;
+		}
+		int h = 31 + (leftClosed ? 7 : 5);
+		h = 31 * h + left.hashCode();
+		if (right != null) {
+			h = 31 * h + right.hashCode();
+			h = 31 * h + (rightClosed ? 7 : 5);
+		}
+		return hash = h;
+	}
+
+	/**
+	 * Compares this {@code VersionRange} object to another object.
+	 * 
+	 * <p>
+	 * A version range is considered to be <b>equal to </b> another version
+	 * range if both the endpoints and their types are equal or if both version
+	 * ranges are {@link #isEmpty() empty}.
+	 * 
+	 * @param object The {@code VersionRange} object to be compared.
+	 * @return {@code true} if {@code object} is a {@code VersionRange} and is
+	 *         equal to this object; {@code false} otherwise.
+	 */
+	public boolean equals(Object object) {
+		if (object == this) { // quicktest
+			return true;
+		}
+		if (!(object instanceof VersionRange)) {
+			return false;
+		}
+		VersionRange other = (VersionRange) object;
+		if (empty && other.empty) {
+			return true;
+		}
+		if (right == null) {
+			return (leftClosed == other.leftClosed) && (other.right == null) && left.equals(other.left);
+		}
+		return (leftClosed == other.leftClosed) && (rightClosed == other.rightClosed) && left.equals(other.left) && right.equals(other.right);
+	}
+
+	/**
+	 * Returns the filter string for this version range using the specified
+	 * attribute name.
+	 * 
+	 * @param attributeName The attribute name to use in the returned filter
+	 *        string.
+	 * @return A filter string for this version range using the specified
+	 *         attribute name.
+	 * @throws IllegalArgumentException If the specified attribute name is not a
+	 *         valid attribute name.
+	 * 
+	 * @see "Core Specification, Filters, for a description of the filter string syntax."
+	 */
+	public String toFilterString(String attributeName) {
+		if (attributeName.length() == 0) {
+			throw new IllegalArgumentException("invalid attributeName \"" + attributeName + "\"");
+		}
+		for (char ch : attributeName.toCharArray()) {
+			if ((ch == '=') || (ch == '>') || (ch == '<') || (ch == '~') || (ch == '(') || (ch == ')')) {
+				throw new IllegalArgumentException("invalid attributeName \"" + attributeName + "\"");
+			}
+		}
+
+		StringBuffer result = new StringBuffer(128);
+		if (right != null) {
+			result.append("(&");
+		}
+		if (leftClosed) {
+			result.append('(');
+			result.append(attributeName);
+			result.append(">=");
+			result.append(left.toString0());
+			result.append(')');
+		} else {
+			result.append("(!(");
+			result.append(attributeName);
+			result.append("<=");
+			result.append(left.toString0());
+			result.append("))");
+		}
+		if (right != null) {
+			if (rightClosed) {
+				result.append('(');
+				result.append(attributeName);
+				result.append("<=");
+				result.append(right.toString0());
+				result.append(')');
+			} else {
+				result.append("(!(");
+				result.append(attributeName);
+				result.append(">=");
+				result.append(right.toString0());
+				result.append("))");
+			}
+			result.append(')');
+		}
+
+		return result.toString();
+	}
+}
diff --git a/src/main/java/org/osgi/framework/hooks/bundle/CollisionHook.java b/src/main/java/org/osgi/framework/hooks/bundle/CollisionHook.java
new file mode 100644
index 0000000..37446ff
--- /dev/null
+++ b/src/main/java/org/osgi/framework/hooks/bundle/CollisionHook.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.hooks.bundle;
+
+import java.util.Collection;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+/**
+ * OSGi Framework Bundle Collision Hook Service.
+ * 
+ * <p>
+ * If the framework was launched with the {@link Constants#FRAMEWORK_BSNVERSION
+ * org.osgi.framework.bsnversion} framework launching property set to
+ * {@link Constants#FRAMEWORK_BSNVERSION_MANAGED managed}, then all registered
+ * collision hook services will be called during framework bundle install and
+ * update operations to determine if an install or update operation will result
+ * in a bundle symbolic name and version collision.
+ * 
+ * @ThreadSafe
+ * @version $Id: a1a25ee0432f210a56e911246f477f19edc28bc1 $
+ */
+public interface CollisionHook {
+
+	/**
+	 * Specifies a bundle install operation is being performed.
+	 */
+	int	INSTALLING	= 1;
+
+	/**
+	 * Specifies a bundle update operation is being performed.
+	 */
+	int	UPDATING	= 2;
+
+	/**
+	 * Filter bundle collisions hook method. This method is called during the
+	 * install or update operation. The operation type will be
+	 * {@link #INSTALLING installing} or {@link #UPDATING updating}. Depending
+	 * on the operation type the target bundle and the collision candidate
+	 * collection are the following:
+	 * <ul>
+	 * <li> {@link #INSTALLING installing} - The target is the bundle associated
+	 * with the {@link BundleContext} used to call one of the
+	 * {@link BundleContext#installBundle(String) install} methods. The
+	 * collision candidate collection contains the existing bundles installed
+	 * which have the same symbolic name and version as the bundle being
+	 * installed.
+	 * <li> {@link #UPDATING updating} - The target is the bundle used to call
+	 * one of the {@link Bundle#update() update} methods. The collision
+	 * candidate collection contains the existing bundles installed which have
+	 * the same symbolic name and version as the content the target bundle is
+	 * being updated to.
+	 * </ul>
+	 * This method can filter the collection of collision candidates by removing
+	 * potential collisions. For the specified operation to succeed, the
+	 * collection of collision candidates must be empty after all registered
+	 * collision hook services have been called.
+	 * 
+	 * @param operationType The operation type. Must be the value of
+	 *        {@link #INSTALLING installing} or {@link #UPDATING updating}.
+	 * @param target The target bundle used to determine what collision
+	 *        candidates to filter.
+	 * @param collisionCandidates The collection of collision candidates. The
+	 *        collection supports all the optional {@code Collection} operations
+	 *        except {@code add} and {@code addAll}. Attempting to add to the
+	 *        collection will result in an {@code UnsupportedOperationException}
+	 *        . The collection is not synchronized.
+	 */
+	void filterCollisions(int operationType, Bundle target, Collection<Bundle> collisionCandidates);
+}
diff --git a/src/main/java/org/osgi/framework/hooks/bundle/EventHook.java b/src/main/java/org/osgi/framework/hooks/bundle/EventHook.java
index 4b50ab3..e66a20e 100644
--- a/src/main/java/org/osgi/framework/hooks/bundle/EventHook.java
+++ b/src/main/java/org/osgi/framework/hooks/bundle/EventHook.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,11 +17,10 @@
 package org.osgi.framework.hooks.bundle;
 
 import java.util.Collection;
-
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
 
-/** 
+/**
  * OSGi Framework Bundle Event Hook Service.
  * 
  * <p>
@@ -29,21 +28,23 @@ import org.osgi.framework.BundleEvent;
  * (install, start, stop, update, and uninstall bundle) operations.
  * 
  * @ThreadSafe
- * @version $Id: 18ea1ec1f14f47410a43e99be4da3b2583149722 $
+ * @version $Id: e1471b36491a02bd8598a30d05c889ee58edc760 $
  */
 public interface EventHook {
 
 	/**
-	 * Bundle event hook method.  This method is called prior to bundle event
-	 * delivery when a bundle is installed, resolved, started, stopped, unresolved, or
-	 * uninstalled.  This method can filter the bundles which receive the event.
+	 * Bundle event hook method. This method is called prior to bundle event
+	 * delivery when a bundle is installed, resolved, started, stopped,
+	 * unresolved, or uninstalled. This method can filter the bundles which
+	 * receive the event.
 	 * <p>
-	 * This method must be called by the framework one and only one time for each bundle 
-	 * event generated, this included bundle events which are generated when there are no 
-	 * bundle listeners registered.  This method must be called on the same thread that is 
-	 * performing the action which generated the specified event.  The specified 
-	 * collection includes bundle contexts with synchronous and asynchronous bundle 
-	 * listeners registered with them.
+	 * This method must be called by the framework one and only one time for
+	 * each bundle event generated, this included bundle events which are
+	 * generated when there are no bundle listeners registered. This method must
+	 * be called on the same thread that is performing the action which
+	 * generated the specified event. The specified collection includes bundle
+	 * contexts with synchronous and asynchronous bundle listeners registered
+	 * with them.
 	 * 
 	 * @param event The bundle event to be delivered
 	 * @param contexts A collection of Bundle Contexts for bundles which have
@@ -52,9 +53,9 @@ public interface EventHook {
 	 *        collection to prevent the event from being delivered to the
 	 *        associated bundles. The collection supports all the optional
 	 *        {@code Collection} operations except {@code add} and
-	 *        {@code addAll}. Attempting to add to the collection will
-	 *        result in an {@code UnsupportedOperationException}. The
-	 *        collection is not synchronized.
+	 *        {@code addAll}. Attempting to add to the collection will result in
+	 *        an {@code UnsupportedOperationException}. The collection is not
+	 *        synchronized.
 	 */
 	void event(BundleEvent event, Collection<BundleContext> contexts);
 }
diff --git a/src/main/java/org/osgi/framework/hooks/bundle/FindHook.java b/src/main/java/org/osgi/framework/hooks/bundle/FindHook.java
index e55ee3b..af556ea 100644
--- a/src/main/java/org/osgi/framework/hooks/bundle/FindHook.java
+++ b/src/main/java/org/osgi/framework/hooks/bundle/FindHook.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,10 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.osgi.framework.hooks.bundle;
 
 import java.util.Collection;
-
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
@@ -29,7 +29,7 @@ import org.osgi.framework.BundleException;
  * (get bundles) operations.
  * 
  * @ThreadSafe
- * @version $Id: 4492a677df650072fe6acaea9ea35571f31eb5a9 $
+ * @version $Id: ae6bf5fc5cf999ac39dfc195c99ef7e223e3b847 $
  */
 public interface FindHook {
 	/**
@@ -48,19 +48,16 @@ public interface FindHook {
 	 * {@link BundleException#REJECTED_BY_HOOK} exception.</li>
 	 * </ul>
 	 * 
-	 * @param context
-	 *            The bundle context of the bundle performing the find
-	 *            operation.
-	 * @param bundles
-	 *            A collection of Bundles to be returned as a result of the find
-	 *            operation. The implementation of this method may remove
-	 *            bundles from the collection to prevent the bundles from being
-	 *            returned to the bundle performing the find operation. The
-	 *            collection supports all the optional {@code Collection}
-	 *            operations except {@code add} and {@code addAll}. Attempting
-	 *            to add to the collection will result in an
-	 *            {@code UnsupportedOperationException}. The collection is not
-	 *            synchronized.
+	 * @param context The bundle context of the bundle performing the find
+	 *        operation.
+	 * @param bundles A collection of Bundles to be returned as a result of the
+	 *        find operation. The implementation of this method may remove
+	 *        bundles from the collection to prevent the bundles from being
+	 *        returned to the bundle performing the find operation. The
+	 *        collection supports all the optional {@code Collection} operations
+	 *        except {@code add} and {@code addAll}. Attempting to add to the
+	 *        collection will result in an {@code UnsupportedOperationException}
+	 *        . The collection is not synchronized.
 	 */
 	void find(BundleContext context, Collection<Bundle> bundles);
 }
diff --git a/src/main/java/org/osgi/framework/hooks/resolver/ResolverHook.java b/src/main/java/org/osgi/framework/hooks/resolver/ResolverHook.java
index bbde7ff..51c46ec 100644
--- a/src/main/java/org/osgi/framework/hooks/resolver/ResolverHook.java
+++ b/src/main/java/org/osgi/framework/hooks/resolver/ResolverHook.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,8 +17,9 @@
 package org.osgi.framework.hooks.resolver;
 
 import java.util.Collection;
-
 import org.osgi.framework.Bundle;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.IdentityNamespace;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleRevision;
@@ -51,62 +52,70 @@ import org.osgi.framework.wiring.FrameworkWiring;
  * must be thrown to the caller of the API which triggered the resolve process.
  * In cases where the the caller is not available a framework event of type
  * error should be fired.</li>
+ * 
  * <li>For each registered hook factory call the
  * {@link ResolverHookFactory#begin(Collection)} method to inform the hooks
  * about a resolve process beginning and to obtain a Resolver Hook instance that
  * will be used for the duration of the resolve process.</li>
+ * 
  * <li>Determine the collection of unresolved bundle revisions that may be
  * considered for resolution during the current resolution process and place
- * each of the bundle revisions in a shrinkable collection {@code R}. For each
- * resolver hook call the {@link #filterResolvable(Collection)} method with the
- * shrinkable collection {@code R}.</li>
- * <li>The shrinkable collection {@code R} now contains all the unresolved
- * bundle revisions that may end up as resolved at the end of the current
- * resolve process. Any other bundle revisions that got removed from the
- * shrinkable collection {@code R} must not end up as resolved at the end of the
- * current resolve process.</li>
+ * each of the bundle revisions in a shrinkable collection {@code Resolvable}.
+ * For each resolver hook call the {@link #filterResolvable(Collection)} method
+ * with the shrinkable collection {@code Resolvable}.</li>
+ * <li>The shrinkable collection {@code Resolvable} now contains all the
+ * unresolved bundle revisions that may end up as resolved at the end of the
+ * current resolve process. Any other bundle revisions that got removed from the
+ * shrinkable collection {@code Resolvable} must not end up as resolved at the
+ * end of the current resolve process.</li>
  * <li>For each bundle revision {@code B} left in the shrinkable collection
- * {@code R} that represents a singleton bundle do the following:<br/>
- * Determine the collection of available capabilities that have a name space of
- * {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle}, are singletons,
- * and have the same symbolic name as the singleton bundle revision {@code B}
- * and place each of the matching capabilities into a shrinkable collection
- * {@code S}.
- * 
- * Remove the {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle}
- * capability provided by bundle revision {@code B} from shrinkable collection
- * {@code S}. A singleton bundle cannot collide with itself.
- * 
+ * {@code Resolvable} and any bundle revision {@code B} which is currently
+ * resolved that represents a singleton bundle do the following:
+ * <p/>
+ * Determine the collection of available capabilities that have a namespace of
+ * {@link IdentityNamespace osgi.identity}, are singletons, and have the same
+ * symbolic name as the singleton bundle revision {@code B} and place each of
+ * the matching capabilities into a shrinkable collection {@code Collisions}.
+ * <p/>
+ * Remove the {@link IdentityNamespace osgi.identity} capability provided by
+ * bundle revision {@code B} from shrinkable collection {@code Collisions}. A
+ * singleton bundle cannot collide with itself.
+ * <p/>
  * For each resolver hook call the
  * {@link #filterSingletonCollisions(BundleCapability, Collection)} with the
- * {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle} capability
- * provided by bundle revision {@code B} and the shrinkable collection {@code S}
- * 
- * The shrinkable collection {@code S} now contains all singleton
- * {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle} capabilities that
- * can influence the ability of bundle revision {@code B} to resolve.</li>
+ * {@link IdentityNamespace osgi.identity} capability provided by bundle
+ * revision {@code B} and the shrinkable collection {@code Collisions}
+ * <p/>
+ * The shrinkable collection {@code Collisions} now contains all singleton
+ * {@link IdentityNamespace osgi.identity} capabilities that can influence the
+ * ability of bundle revision {@code B} to resolve.
+ * <p/>
+ * If the bundle revision {@code B} is already resolved then any resolvable
+ * bundle revision contained in the collection {@code Collisions} is not allowed
+ * to resolve.</li>
  * <li>During a resolve process a framework is free to attempt to resolve any or
- * all bundles contained in shrinkable collection {@code R}. For each bundle
- * revision {@code B} left in the shrinkable collection {@code R} which the
- * framework attempts to resolve the following steps must be followed:
+ * all bundles contained in shrinkable collection {@code Resolvable}. For each
+ * bundle revision {@code B} left in the shrinkable collection
+ * {@code Resolvable} which the framework attempts to resolve the following
+ * steps must be followed:
  * <p/>
- * For each requirement {@code T} specified by bundle revision {@code B}
+ * For each requirement {@code R} specified by bundle revision {@code B}
  * determine the collection of capabilities that satisfy (or match) the
  * requirement and place each matching capability into a shrinkable collection
- * {@code C}. A capability is considered to match a particular requirement if
- * its attributes satisfy a specified requirement and the requirer bundle has
- * permission to access the capability.
+ * {@code Candidates}. A capability is considered to match a particular
+ * requirement if its attributes satisfy a specified requirement and the
+ * requirer bundle has permission to access the capability.
  * 
  * <p/>
  * For each resolver hook call the
  * {@link #filterMatches(BundleRequirement, Collection)} with the requirement
- * {@code T} and the shrinkable collection {@code C}.
+ * {@code R} and the shrinkable collection {@code Candidates}.
  * 
  * <p/>
- * The shrinkable collection {@code C} now contains all the capabilities that
- * may be used to satisfy the requirement {@code T}. Any other capabilities that
- * got removed from the shrinkable collection {@code C} must not be used to
- * satisfy requirement {@code T}.</li>
+ * The shrinkable collection {@code Candidates} now contains all the
+ * capabilities that may be used to satisfy the requirement {@code R}. Any other
+ * capabilities that got removed from the shrinkable collection
+ * {@code Candidates} must not be used to satisfy requirement {@code R}.</li>
  * <li>For each resolver hook call the {@link #end()} method to inform the hooks
  * about a resolve process ending.</li>
  * </ol>
@@ -125,18 +134,18 @@ import org.osgi.framework.wiring.FrameworkWiring;
  * 
  * @see ResolverHookFactory
  * @NotThreadSafe
- * @version $Id: ea23400257d780706250f8825ec886aaebb0e5d8 $
+ * @version $Id: 9d3ef6240aead0952b5a47b793780c1c0589089a $
  */
 public interface ResolverHook {
 	/**
-	 * Filter resolvable candidates hook method.  This method may be called
-	 * multiple times during a single resolve process.
-	 * This method can filter the collection of candidates by removing 
-	 * potential candidates.  Removing a candidate will prevent the candidate
-	 * from resolving during the current resolve process. 
+	 * Filter resolvable candidates hook method. This method may be called
+	 * multiple times during a single resolve process. This method can filter
+	 * the collection of candidates by removing potential candidates. Removing a
+	 * candidate will prevent the candidate from resolving during the current
+	 * resolve process.
 	 * 
-	 * @param candidates the collection of resolvable candidates available during
-	 * a resolve process. 
+	 * @param candidates the collection of resolvable candidates available
+	 *        during a resolve process.
 	 */
 	void filterResolvable(Collection<BundleRevision> candidates);
 
@@ -146,19 +155,18 @@ public interface ResolverHook {
 	 * represents a singleton capability and the specified collection represent
 	 * a collection of singleton capabilities which are considered collision
 	 * candidates. The singleton capability and the collection of collision
-	 * candidates must all use the same name space.
+	 * candidates must all use the same namespace.
 	 * <p>
-	 * Currently only capabilities with the name space of
-	 * {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle} can be
-	 * singletons. In that case all the collision candidates have the name space
-	 * of {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle}, are
+	 * Currently only capabilities with the namespace of {@link BundleNamespace
+	 * osgi.wiring.bundle} and {@link IdentityNamespace osgi.identity} can be
+	 * singletons. The collision candidates will all have the same namespace, be
 	 * singletons, and have the same symbolic name as the specified singleton
 	 * capability.
 	 * <p>
-	 * In the future, capabilities in other name spaces may support the
-	 * singleton concept. Hook implementations should be prepared to receive
-	 * calls to this method for capabilities in name spaces other than
-	 * {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle}.
+	 * In the future, capabilities in other namespaces may support the singleton
+	 * concept. Hook implementations should be prepared to receive calls to this
+	 * method for capabilities in namespaces other than {@link BundleNamespace
+	 * osgi.wiring.bundle} or {@link IdentityNamespace osgi.identity}.
 	 * <p>
 	 * This method can filter the list of collision candidates by removing
 	 * potential collisions. Removing a collision candidate will allow the
@@ -171,28 +179,29 @@ public interface ResolverHook {
 	void filterSingletonCollisions(BundleCapability singleton, Collection<BundleCapability> collisionCandidates);
 
 	/**
-	 * Filter matches hook method. This method is called during the resolve process for the 
-	 * specified requirement.  The collection of candidates match the specified requirement.
-	 * This method can filter the collection of matching candidates by removing candidates from 
-	 * the collection.  Removing a candidate will prevent the resolve process from choosing the 
-	 * removed candidate to satisfy the requirement.
+	 * Filter matches hook method. This method is called during the resolve
+	 * process for the specified requirement. The collection of candidates match
+	 * the specified requirement. This method can filter the collection of
+	 * matching candidates by removing candidates from the collection. Removing
+	 * a candidate will prevent the resolve process from choosing the removed
+	 * candidate to satisfy the requirement.
 	 * <p>
-	 * All of the candidates will have the same name space and will 
-	 * match the specified requirement.
+	 * All of the candidates will have the same namespace and will match the
+	 * specified requirement.
 	 * <p>
-	 * If the Java Runtime Environment supports permissions then the collection of 
-	 * candidates will only contain candidates for which the requirer has permission to
-	 * access.
+	 * If the Java Runtime Environment supports permissions then the collection
+	 * of candidates will only contain candidates for which the requirer has
+	 * permission to access.
+	 * 
 	 * @param requirement the requirement to filter candidates for
 	 * @param candidates a collection of candidates that match the requirement
 	 */
 	void filterMatches(BundleRequirement requirement, Collection<BundleCapability> candidates);
 
 	/**
-	 * This method is called once at the end of the resolve process.
-	 * After the end method is called the resolve process has ended.
-	 * The framework must not hold onto this resolver hook instance
-	 * after end has been called.
+	 * This method is called once at the end of the resolve process. After the
+	 * end method is called the resolve process has ended. The framework must
+	 * not hold onto this resolver hook instance after end has been called.
 	 */
 	void end();
 }
diff --git a/src/main/java/org/osgi/framework/hooks/resolver/ResolverHookFactory.java b/src/main/java/org/osgi/framework/hooks/resolver/ResolverHookFactory.java
index 1d4edd4..91ce5f7 100644
--- a/src/main/java/org/osgi/framework/hooks/resolver/ResolverHookFactory.java
+++ b/src/main/java/org/osgi/framework/hooks/resolver/ResolverHookFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,78 +17,88 @@
 package org.osgi.framework.hooks.resolver;
 
 import java.util.Collection;
-
 import org.osgi.framework.Bundle;
 import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.framework.wiring.FrameworkWiring;
 
-/** 
+/**
  * OSGi Framework Resolver Hook Factory Service.
  * 
  * <p>
- * Bundles registering this service will be called by the framework during 
- * a bundle resolver process to obtain a {@link ResolverHook resolver hook}
+ * Bundles registering this service will be called by the framework during a
+ * bundle resolver process to obtain a {@link ResolverHook resolver hook}
  * instance which will be used for the duration of a resolve process.
  * 
  * @ThreadSafe
  * @see ResolverHook
- * @version $Id: 4023566367435f07c047a7ba571f3bedc53aa37a $
+ * @version $Id: e0a2f3ad081c31bbb682fa366c15a3080bf6da2b $
  */
 public interface ResolverHookFactory {
 	/**
 	 * This method is called by the framework each time a resolve process begins
-	 * to obtain a {@link ResolverHook resolver hook} instance.  This resolver hook 
-	 * instance will be used for the duration of the resolve process.  At the end of 
-	 * the resolve process the method {@link ResolverHook#end()} must be called by 
-	 * the framework and the framework must not hold any references of the resolver 
-	 * hook instance.
+	 * to obtain a {@link ResolverHook resolver hook} instance. This resolver
+	 * hook instance will be used for the duration of the resolve process. At
+	 * the end of the resolve process the method {@link ResolverHook#end()} must
+	 * be called by the framework and the framework must not hold any references
+	 * of the resolver hook instance.
 	 * <p>
-	 * The triggers represent the collection of bundles which triggered
-	 * the resolve process.  This collection may be empty if the triggers
-	 * cannot be determined by the framework.  In most cases the triggers 
-	 * can easily be determined.  Calling certain methods on 
-	 * {@link Bundle bundle} when a bundle is in the {@link Bundle#INSTALLED INSTALLED} 
-	 * state will cause the framework to begin a resolve process in order to resolve the 
-	 * bundle.  The following methods will start a resolve process in this case:
+	 * The triggers represent the collection of bundles which triggered the
+	 * resolve process. This collection may be empty if the triggers cannot be
+	 * determined by the framework. In most cases the triggers can easily be
+	 * determined. Calling certain methods on {@link Bundle bundle} when a
+	 * bundle is in the {@link Bundle#INSTALLED INSTALLED} state will cause the
+	 * framework to begin a resolve process in order to resolve the bundle. The
+	 * following methods will start a resolve process in this case:
 	 * <ul>
-	 *   <li>{@link Bundle#start() start}</li>
-	 *   <li>{@link Bundle#loadClass(String) loadClass}</li>
-	 *   <li>{@link Bundle#findEntries(String, String, boolean) findEntries}</li>
-	 *   <li>{@link Bundle#getResource(String) getResource}</li>
-	 *   <li>{@link Bundle#getResources(String) getResources}</li>
-	 * </ul> 
+	 * <li>{@link Bundle#start() start}</li>
+	 * <li>{@link Bundle#loadClass(String) loadClass}</li>
+	 * <li>{@link Bundle#findEntries(String, String, boolean) findEntries}</li>
+	 * <li>{@link Bundle#getResource(String) getResource}</li>
+	 * <li>{@link Bundle#getResources(String) getResources}</li>
+	 * </ul>
 	 * In such cases the collection will contain the single bundle which the
-	 * framework is trying to resolve.  Other cases will cause multiple bundles to be
-	 * included in the trigger bundles collection.  When {@link FrameworkWiring#resolveBundles(Collection)
-	 * resolveBundles} is called the collection of triggers must include all the current bundle 
-	 * revisions for bundles passed to resolveBundles which are in the {@link Bundle#INSTALLED INSTALLED}
-	 * state.
+	 * framework is trying to resolve. Other cases will cause multiple bundles
+	 * to be included in the trigger bundles collection. When
+	 * {@link FrameworkWiring#resolveBundles(Collection) resolveBundles} is
+	 * called the collection of triggers must include all the current bundle
+	 * revisions for bundles passed to resolveBundles which are in the
+	 * {@link Bundle#INSTALLED INSTALLED} state.
 	 * <p>
-	 * When {@link FrameworkWiring#refreshBundles(Collection, org.osgi.framework.FrameworkListener...)}
-	 * is called the collection of triggers is determined with the following steps:
+	 * When
+	 * {@link FrameworkWiring#refreshBundles(Collection, org.osgi.framework.FrameworkListener...)}
+	 * is called the collection of triggers is determined with the following
+	 * steps:
 	 * <ul>
-	 *   <li>If the collection of bundles passed is null then {@link FrameworkWiring#getRemovalPendingBundles()}
-	 *   is called to get the initial collection of bundles.</li>
-	 *   <li>The equivalent of calling {@link FrameworkWiring#getDependencyClosure(Collection)} is called with
-	 *   the initial collection of bundles to get the dependency closure collection of the bundles being refreshed.</li>
-	 *   <li>Remove any non-active bundles from the dependency closure collection.</li>
-	 *   <li>For each bundle remaining in the dependency closure collection get the current bundle revision
-	 *   and add it to the collection of triggers.</li> 
+	 * <li>If the collection of bundles passed is null then
+	 * {@link FrameworkWiring#getRemovalPendingBundles()} is called to get the
+	 * initial collection of bundles.</li>
+	 * <li>The equivalent of calling
+	 * {@link FrameworkWiring#getDependencyClosure(Collection)} is called with
+	 * the initial collection of bundles to get the dependency closure
+	 * collection of the bundles being refreshed.</li>
+	 * <li>Remove any non-active bundles from the dependency closure collection.
+	 * </li>
+	 * <li>For each bundle remaining in the dependency closure collection get
+	 * the current bundle revision and add it to the collection of triggers.</li>
 	 * </ul>
 	 * <p>
-	 * As described above, a resolve process is typically initiated as a result of calling API that causes the 
-	 * framework to attempt to resolve one or more bundles.  
-	 * The framework is free to start a resolve process at any time for reasons other than calls to framework API.
-	 * For example, a resolve process may be used by the framework for diagnostic purposes and result in no
-	 * bundles actually becoming resolved at the end of the process.
-	 * Resolver hook implementations must be prepared for resolve processes that are initiated for other reasons
-	 * besides calls to framework API.
-	 * @param triggers an unmodifiable collection of bundles which triggered the resolve process.
-	 * This collection may be empty if the collection of trigger bundles cannot be
-	 * determined.
-	 * @return a resolver hook instance to be used for the duration of the resolve process.
-	 * A {@code null} value may be returned which indicates this resolver hook factory abstains from
-	 * the resolve process.
+	 * As described above, a resolve process is typically initiated as a result
+	 * of calling API that causes the framework to attempt to resolve one or
+	 * more bundles. The framework is free to start a resolve process at any
+	 * time for reasons other than calls to framework API. For example, a
+	 * resolve process may be used by the framework for diagnostic purposes and
+	 * result in no bundles actually becoming resolved at the end of the
+	 * process. Resolver hook implementations must be prepared for resolve
+	 * processes that are initiated for other reasons besides calls to framework
+	 * API.
+	 * 
+	 * @param triggers an unmodifiable collection of bundles which triggered the
+	 *        resolve process. This collection may be empty if the collection of
+	 *        trigger bundles cannot be determined.
+	 * @return a resolver hook instance to be used for the duration of the
+	 *         resolve process. A {@code null} value may be returned which
+	 *         indicates this resolver hook factory abstains from the resolve
+	 *         process.
 	 */
 	ResolverHook begin(Collection<BundleRevision> triggers);
 }
diff --git a/src/main/java/org/osgi/framework/hooks/service/EventHook.java b/src/main/java/org/osgi/framework/hooks/service/EventHook.java
index fb2ab09..03a84d4 100644
--- a/src/main/java/org/osgi/framework/hooks/service/EventHook.java
+++ b/src/main/java/org/osgi/framework/hooks/service/EventHook.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2008, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2008, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
 package org.osgi.framework.hooks.service;
 
 import java.util.Collection;
-
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceEvent;
 
@@ -30,7 +29,7 @@ import org.osgi.framework.ServiceEvent;
  * 
  * @ThreadSafe
  * @deprecated As of 1.1. Replaced by {@link EventListenerHook}.
- * @version $Id: 8fb8cfa2c8847f99fd84711e12f02a57bf06932e $
+ * @version $Id: 84757a5f719db4d7671e81a76af2b320404ae0f5 $
  */
 
 public interface EventHook {
@@ -46,9 +45,9 @@ public interface EventHook {
 	 *        collection to prevent the event from being delivered to the
 	 *        associated bundles. The collection supports all the optional
 	 *        {@code Collection} operations except {@code add} and
-	 *        {@code addAll}. Attempting to add to the collection will
-	 *        result in an {@code UnsupportedOperationException}. The
-	 *        collection is not synchronized.
+	 *        {@code addAll}. Attempting to add to the collection will result in
+	 *        an {@code UnsupportedOperationException}. The collection is not
+	 *        synchronized.
 	 */
 	void event(ServiceEvent event, Collection<BundleContext> contexts);
 }
diff --git a/src/main/java/org/osgi/framework/hooks/service/EventListenerHook.java b/src/main/java/org/osgi/framework/hooks/service/EventListenerHook.java
index 6f25291..534efc5 100644
--- a/src/main/java/org/osgi/framework/hooks/service/EventListenerHook.java
+++ b/src/main/java/org/osgi/framework/hooks/service/EventListenerHook.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package org.osgi.framework.hooks.service;
 
 import java.util.Collection;
 import java.util.Map;
-
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceEvent;
 import org.osgi.framework.hooks.service.ListenerHook.ListenerInfo;
@@ -32,7 +31,7 @@ import org.osgi.framework.hooks.service.ListenerHook.ListenerInfo;
  * 
  * @ThreadSafe
  * @since 1.1
- * @version $Id: 61c6aa7e7d4c85b3e5a6a3a340155bcda0074505 $
+ * @version $Id: b0b99b29206f272ad479fa08ffcd5ef5fda909b8 $
  */
 
 public interface EventListenerHook {
@@ -56,6 +55,5 @@ public interface EventListenerHook {
 	 *        collection will result in an {@code UnsupportedOperationException}
 	 *        . The map and the collections are not synchronized.
 	 */
-	void event(ServiceEvent event,
-			Map<BundleContext, Collection<ListenerInfo>> listeners);
+	void event(ServiceEvent event, Map<BundleContext, Collection<ListenerInfo>> listeners);
 }
diff --git a/src/main/java/org/osgi/framework/hooks/service/FindHook.java b/src/main/java/org/osgi/framework/hooks/service/FindHook.java
index cb334c5..4cd467c 100644
--- a/src/main/java/org/osgi/framework/hooks/service/FindHook.java
+++ b/src/main/java/org/osgi/framework/hooks/service/FindHook.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2008, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2008, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
 package org.osgi.framework.hooks.service;
 
 import java.util.Collection;
-
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 
@@ -29,7 +28,7 @@ import org.osgi.framework.ServiceReference;
  * (get service references) operations.
  * 
  * @ThreadSafe
- * @version $Id: 4a939200fa6634a563379b057e11bd1b5d174b9d $
+ * @version $Id: 45612d6a10a25ca0b40ba695eb8dba21c2c78c24 $
  */
 
 public interface FindHook {
@@ -40,12 +39,12 @@ public interface FindHook {
 	 * 
 	 * @param context The bundle context of the bundle performing the find
 	 *        operation.
-	 * @param name The class name of the services to find or {@code null}
-	 *        to find all services.
-	 * @param filter The filter criteria of the services to find or
-	 *        {@code null} for no filter criteria.
-	 * @param allServices {@code true} if the find operation is the result
-	 *        of a call to
+	 * @param name The class name of the services to find or {@code null} to
+	 *        find all services.
+	 * @param filter The filter criteria of the services to find or {@code null}
+	 *        for no filter criteria.
+	 * @param allServices {@code true} if the find operation is the result of a
+	 *        call to
 	 *        {@link BundleContext#getAllServiceReferences(String, String)}
 	 * @param references A collection of Service References to be returned as a
 	 *        result of the find operation. The implementation of this method
@@ -53,10 +52,9 @@ public interface FindHook {
 	 *        references from being returned to the bundle performing the find
 	 *        operation. The collection supports all the optional
 	 *        {@code Collection} operations except {@code add} and
-	 *        {@code addAll}. Attempting to add to the collection will
-	 *        result in an {@code UnsupportedOperationException}. The
-	 *        collection is not synchronized.
+	 *        {@code addAll}. Attempting to add to the collection will result in
+	 *        an {@code UnsupportedOperationException}. The collection is not
+	 *        synchronized.
 	 */
-	void find(BundleContext context, String name, String filter,
-			boolean allServices, Collection<ServiceReference< ? >> references);
+	void find(BundleContext context, String name, String filter, boolean allServices, Collection<ServiceReference<?>> references);
 }
diff --git a/src/main/java/org/osgi/framework/hooks/service/ListenerHook.java b/src/main/java/org/osgi/framework/hooks/service/ListenerHook.java
index bdac7b5..ef933c3 100644
--- a/src/main/java/org/osgi/framework/hooks/service/ListenerHook.java
+++ b/src/main/java/org/osgi/framework/hooks/service/ListenerHook.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2008, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2008, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
 package org.osgi.framework.hooks.service;
 
 import java.util.Collection;
-
 import org.osgi.framework.BundleContext;
 
 /**
@@ -28,7 +27,7 @@ import org.osgi.framework.BundleContext;
  * addition and removal.
  * 
  * @ThreadSafe
- * @version $Id: c1687e95e568589cf3e6d927b7d372c9f88c5d16 $
+ * @version $Id: 94029e2b70119793b3e7d77d6e1d5052d9ee1723 $
  */
 
 public interface ListenerHook {
@@ -43,8 +42,8 @@ public interface ListenerHook {
 	 * @param listeners A collection of {@link ListenerInfo}s for newly added
 	 *        service listeners which are now listening to service events.
 	 *        Attempting to add to or remove from the collection will result in
-	 *        an {@code UnsupportedOperationException}. The collection is
-	 *        not synchronized.
+	 *        an {@code UnsupportedOperationException}. The collection is not
+	 *        synchronized.
 	 */
 	void added(Collection<ListenerInfo> listeners);
 
@@ -57,8 +56,8 @@ public interface ListenerHook {
 	 * @param listeners A collection of {@link ListenerInfo}s for newly removed
 	 *        service listeners which are no longer listening to service events.
 	 *        Attempting to add to or remove from the collection will result in
-	 *        an {@code UnsupportedOperationException}. The collection is
-	 *        not synchronized.
+	 *        an {@code UnsupportedOperationException}. The collection is not
+	 *        synchronized.
 	 */
 	void removed(Collection<ListenerInfo> listeners);
 
@@ -81,17 +80,15 @@ public interface ListenerHook {
 		 * Return the filter string with which the listener was added.
 		 * 
 		 * @return The filter string with which the listener was added. This may
-		 *         be {@code null} if the listener was added without a
-		 *         filter.
+		 *         be {@code null} if the listener was added without a filter.
 		 */
 		String getFilter();
 
 		/**
 		 * Return the state of the listener for this addition and removal life
-		 * cycle. Initially this method will return {@code false}
-		 * indicating the listener has been added but has not been removed.
-		 * After the listener has been removed, this method must always return
-		 * {@code true}.
+		 * cycle. Initially this method will return {@code false} indicating the
+		 * listener has been added but has not been removed. After the listener
+		 * has been removed, this method must always return {@code true}.
 		 * 
 		 * <p>
 		 * There is an extremely rare case in which removed notification to
@@ -109,19 +106,16 @@ public interface ListenerHook {
 		boolean isRemoved();
 
 		/**
-		 * Compares this {@code ListenerInfo} to another
-		 * {@code ListenerInfo}. Two {@code ListenerInfo}s are equals
-		 * if they refer to the same listener for a given addition and removal
-		 * life cycle. If the same listener is added again, it must have a
-		 * different {@code ListenerInfo} which is not equal to this
-		 * {@code ListenerInfo}.
+		 * Compares this {@code ListenerInfo} to another {@code ListenerInfo}.
+		 * Two {@code ListenerInfo}s are equals if they refer to the same
+		 * listener for a given addition and removal life cycle. If the same
+		 * listener is added again, it must have a different
+		 * {@code ListenerInfo} which is not equal to this {@code ListenerInfo}.
 		 * 
-		 * @param obj The object to compare against this
-		 *        {@code ListenerInfo}.
-		 * @return {@code true} if the other object is a
-		 *         {@code ListenerInfo} object and both objects refer to
-		 *         the same listener for a given addition and removal life
-		 *         cycle.
+		 * @param obj The object to compare against this {@code ListenerInfo}.
+		 * @return {@code true} if the other object is a {@code ListenerInfo}
+		 *         object and both objects refer to the same listener for a
+		 *         given addition and removal life cycle.
 		 */
 		boolean equals(Object obj);
 
diff --git a/src/main/java/org/osgi/framework/hooks/weaving/WovenClass.java b/src/main/java/org/osgi/framework/hooks/weaving/WovenClass.java
index 34aa6d2..697a435 100644
--- a/src/main/java/org/osgi/framework/hooks/weaving/WovenClass.java
+++ b/src/main/java/org/osgi/framework/hooks/weaving/WovenClass.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package org.osgi.framework.hooks.weaving;
 
 import java.security.ProtectionDomain;
 import java.util.List;
-
 import org.osgi.framework.wiring.BundleWiring;
 
 /**
@@ -35,7 +34,7 @@ import org.osgi.framework.wiring.BundleWiring;
  * 
  * @NotThreadSafe
  * @noimplement
- * @version $Id: c689a4c27dc39af1bf5f51338f1a8eaca1dddc1a $
+ * @version $Id: 549caef41027c8f0d0fdb4deae756eae6b69d1ee $
  */
 public interface WovenClass {
 
@@ -138,15 +137,16 @@ public interface WovenClass {
 	public ProtectionDomain getProtectionDomain();
 
 	/**
-	 * Returns the class associated with this woven class. When loading a class
-	 * for the first time this method will return {@code null} until weaving is
-	 * {@link #isWeavingComplete() complete}. Once weaving is complete, this
-	 * method will return the class object.
+	 * Returns the class defined by this woven class. During weaving, this
+	 * method will return {@code null}. Once weaving is
+	 * {@link #isWeavingComplete() complete}, this method will return the class
+	 * object if this woven class was used to define the class.
 	 * 
 	 * @return The class associated with this woven class, or {@code null} if
-	 *         weaving is not complete or the class definition failed.
+	 *         weaving is not complete, the class definition failed or this
+	 *         woven class was not used to define the class.
 	 */
-	public Class< ? > getDefinedClass();
+	public Class<?> getDefinedClass();
 
 	/**
 	 * Returns the bundle wiring whose class loader will define the woven class.
diff --git a/src/main/java/org/osgi/framework/launch/Framework.java b/src/main/java/org/osgi/framework/launch/Framework.java
index 672db44..54d599b 100644
--- a/src/main/java/org/osgi/framework/launch/Framework.java
+++ b/src/main/java/org/osgi/framework/launch/Framework.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2008, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2008, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@ package org.osgi.framework.launch;
 import java.io.InputStream;
 import java.net.URL;
 import java.util.Enumeration;
-
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.Constants;
@@ -35,7 +34,7 @@ import org.osgi.framework.FrameworkEvent;
  * 
  * @ThreadSafe
  * @noimplement
- * @version $Id: 2be857d06f3605a04f701b59f11e127c0f8940dc $
+ * @version $Id: e76240d5de584d1666880d9bc358571a76cbd8fb $
  */
 public interface Framework extends Bundle {
 
@@ -76,13 +75,12 @@ public interface Framework extends Bundle {
 	void init() throws BundleException;
 
 	/**
-	 * Wait until this Framework has completely stopped. The {@code stop}
-	 * and {@code update} methods on a Framework performs an asynchronous
-	 * stop of the Framework. This method can be used to wait until the
-	 * asynchronous stop of this Framework has completed. This method will only
-	 * wait if called when this Framework is in the {@link #STARTING},
-	 * {@link #ACTIVE}, or {@link #STOPPING} states. Otherwise it will return
-	 * immediately.
+	 * Wait until this Framework has completely stopped. The {@code stop} and
+	 * {@code update} methods on a Framework performs an asynchronous stop of
+	 * the Framework. This method can be used to wait until the asynchronous
+	 * stop of this Framework has completed. This method will only wait if
+	 * called when this Framework is in the {@link #STARTING}, {@link #ACTIVE},
+	 * or {@link #STOPPING} states. Otherwise it will return immediately.
 	 * <p>
 	 * A Framework Event is returned to indicate why this Framework has stopped.
 	 * 
@@ -90,8 +88,8 @@ public interface Framework extends Bundle {
 	 *        Framework has completely stopped. A value of zero will wait
 	 *        indefinitely.
 	 * @return A Framework Event indicating the reason this method returned. The
-	 *         following {@code FrameworkEvent} types may be returned by
-	 *         this method.
+	 *         following {@code FrameworkEvent} types may be returned by this
+	 *         method.
 	 *         <ul>
 	 *         <li>{@link FrameworkEvent#STOPPED STOPPED} - This Framework has
 	 *         been stopped. </li>
@@ -230,8 +228,8 @@ public interface Framework extends Bundle {
 	 * 
 	 * @throws BundleException This Framework cannot be uninstalled.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         {@code AdminPermission[this,LIFECYCLE]}, and the Java
-	 *         Runtime Environment supports permissions.
+	 *         {@code AdminPermission[this,LIFECYCLE]}, and the Java Runtime
+	 *         Environment supports permissions.
 	 */
 	void uninstall() throws BundleException;
 
@@ -251,8 +249,8 @@ public interface Framework extends Bundle {
 	 * @throws BundleException If stopping and restarting this Framework could
 	 *         not be initiated.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         {@code AdminPermission[this,LIFECYCLE]}, and the Java
-	 *         Runtime Environment supports permissions.
+	 *         {@code AdminPermission[this,LIFECYCLE]}, and the Java Runtime
+	 *         Environment supports permissions.
 	 */
 	void update() throws BundleException;
 
@@ -268,8 +266,8 @@ public interface Framework extends Bundle {
 	 * @throws BundleException If stopping and restarting this Framework could
 	 *         not be initiated.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         {@code AdminPermission[this,LIFECYCLE]}, and the Java
-	 *         Runtime Environment supports permissions.
+	 *         {@code AdminPermission[this,LIFECYCLE]}, and the Java Runtime
+	 *         Environment supports permissions.
 	 */
 	void update(InputStream in) throws BundleException;
 
@@ -284,8 +282,8 @@ public interface Framework extends Bundle {
 
 	/**
 	 * Returns the Framework location identifier. This Framework is assigned the
-	 * unique location "{@code System Bundle}" since this
-	 * Framework is also a System Bundle.
+	 * unique location "{@code System Bundle}" since this Framework is
+	 * also a System Bundle.
 	 * 
 	 * @return The string "{@code System Bundle}".
 	 * @throws SecurityException If the caller does not have the appropriate
@@ -299,8 +297,8 @@ public interface Framework extends Bundle {
 	/**
 	 * Returns the symbolic name of this Framework. The symbolic name is unique
 	 * for the implementation of the framework. However, the symbolic name
-	 * "{@code system.bundle}" must be recognized as an alias to
-	 * the implementation-defined symbolic name since this Framework is also a
+	 * "{@code system.bundle}" must be recognized as an alias to the
+	 * implementation-defined symbolic name since this Framework is also a
 	 * System Bundle.
 	 * 
 	 * @return The symbolic name of this Framework.
@@ -310,22 +308,22 @@ public interface Framework extends Bundle {
 	String getSymbolicName();
 
 	/**
-	 * Returns {@code null} as a framework implementation does not have a
-	 * proper bundle from which to return entry paths.
+	 * Returns {@code null} as a framework implementation does not have a proper
+	 * bundle from which to return entry paths.
 	 * 
 	 * @param path Ignored.
-	 * @return {@code null} as a framework implementation does not have a
-	 *         proper bundle from which to return entry paths.
+	 * @return {@code null} as a framework implementation does not have a proper
+	 *         bundle from which to return entry paths.
 	 */
 	Enumeration<String> getEntryPaths(String path);
 
 	/**
-	 * Returns {@code null} as a framework implementation does not have a
-	 * proper bundle from which to return an entry.
+	 * Returns {@code null} as a framework implementation does not have a proper
+	 * bundle from which to return an entry.
 	 * 
 	 * @param path Ignored.
-	 * @return {@code null} as a framework implementation does not have a
-	 *         proper bundle from which to return an entry.
+	 * @return {@code null} as a framework implementation does not have a proper
+	 *         bundle from which to return an entry.
 	 */
 	URL getEntry(String path);
 
@@ -339,8 +337,7 @@ public interface Framework extends Bundle {
 	 * @return {@code null} as a framework implementation does not have a proper
 	 *         bundle from which to return entries.
 	 */
-	Enumeration<URL> findEntries(String path, String filePattern,
-			boolean recurse);
+	Enumeration<URL> findEntries(String path, String filePattern, boolean recurse);
 
 	/**
 	 * Adapt this Framework to the specified type.
diff --git a/src/main/java/org/osgi/framework/launch/FrameworkFactory.java b/src/main/java/org/osgi/framework/launch/FrameworkFactory.java
index 649ef4b..bac0183 100644
--- a/src/main/java/org/osgi/framework/launch/FrameworkFactory.java
+++ b/src/main/java/org/osgi/framework/launch/FrameworkFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2009, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2009, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
 package org.osgi.framework.launch;
 
 import java.util.Map;
-
 import org.osgi.framework.Bundle;
 
 /**
@@ -33,20 +32,20 @@ import org.osgi.framework.Bundle;
  * This UTF-8 encoded resource must contain the name of the framework
  * implementation's FrameworkFactory implementation class. Space and tab
  * characters, including blank lines, in the resource must be ignored. The
- * number sign ('#' \u0023) and all characters following it on each line are
- * a comment and must be ignored.
+ * number sign ({@code '#'} \u0023) and all characters following it on each
+ * line are a comment and must be ignored.
  * 
  * <p>
  * Launchers can find the name of the FrameworkFactory implementation class in
  * the resource and then load and construct a FrameworkFactory object for the
  * framework implementation. The FrameworkFactory implementation class must have
  * a public, no-argument constructor. Java™ SE 6 introduced the
- * {@code ServiceLoader} class which can create a FrameworkFactory instance
- * from the resource.
+ * {@code ServiceLoader} class which can create a FrameworkFactory instance from
+ * the resource.
  * 
  * @ThreadSafe
  * @noimplement
- * @version $Id: c370e19dba77231f0dbf1601218ad97b20391ea0 $
+ * @version $Id: 1684e14aa98a1f6e1ff3e0f3afa2c55982210f72 $
  */
 public interface FrameworkFactory {
 
@@ -59,15 +58,15 @@ public interface FrameworkFactory {
 	 *        use some reasonable default configuration appropriate for the
 	 *        current VM. For example, the system packages for the current
 	 *        execution environment should be properly exported. The specified
-	 *        configuration argument may be {@code null}. The created
-	 *        framework instance must copy any information needed from the
-	 *        specified configuration argument since the configuration argument
-	 *        can be changed after the framework instance has been created.
+	 *        configuration argument may be {@code null}. The created framework
+	 *        instance must copy any information needed from the specified
+	 *        configuration argument since the configuration argument can be
+	 *        changed after the framework instance has been created.
 	 * @return A new, configured {@link Framework} instance. The framework
 	 *         instance must be in the {@link Bundle#INSTALLED} state.
 	 * @throws SecurityException If the caller does not have
-	 *         {@code AllPermission}, and the Java Runtime Environment
-	 *         supports permissions.
+	 *         {@code AllPermission}, and the Java Runtime Environment supports
+	 *         permissions.
 	 */
 	Framework newFramework(Map<String, String> configuration);
 }
diff --git a/src/main/java/org/osgi/framework/namespace/AbstractWiringNamespace.java b/src/main/java/org/osgi/framework/namespace/AbstractWiringNamespace.java
new file mode 100644
index 0000000..52563e2
--- /dev/null
+++ b/src/main/java/org/osgi/framework/namespace/AbstractWiringNamespace.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.namespace;
+
+import org.osgi.resource.Namespace;
+
+/**
+ * Wiring Capability and Requirement Namespaces base class.
+ * 
+ * <p>
+ * This class is the common class shared by all OSGi defined wiring namespaces.
+ * It defines the names for the common attributes and directives for the OSGi
+ * specified wiring namespaces.
+ * 
+ * <p>
+ * The values associated with these keys are of type {@code String}, unless
+ * otherwise indicated.
+ * 
+ * @Immutable
+ * @version $Id: 383e84df9190757ce6bb6fb722e80a3b7d6b68da $
+ */
+public abstract class AbstractWiringNamespace extends Namespace {
+
+	/**
+	 * The capability directive used to specify the comma separated list of
+	 * mandatory attributes which must be specified in the
+	 * {@link Namespace#REQUIREMENT_FILTER_DIRECTIVE filter} of a requirement in
+	 * order for the capability to match the requirement.
+	 */
+	public final static String	CAPABILITY_MANDATORY_DIRECTIVE		= "mandatory";
+
+	/**
+	 * The capability attribute contains the {@code Version} of the resource
+	 * providing the capability if one is specified or {@code 0.0.0} if not
+	 * specified. The value of this attribute must be of type {@code Version}.
+	 */
+	public static final String	CAPABILITY_BUNDLE_VERSION_ATTRIBUTE	= "bundle-version";
+
+	AbstractWiringNamespace() {
+		// empty
+	}
+}
diff --git a/src/main/java/org/osgi/framework/namespace/BundleNamespace.java b/src/main/java/org/osgi/framework/namespace/BundleNamespace.java
new file mode 100644
index 0000000..84b6700
--- /dev/null
+++ b/src/main/java/org/osgi/framework/namespace/BundleNamespace.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.namespace;
+
+import org.osgi.resource.Namespace;
+
+/**
+ * Bundle Capability and Requirement Namespace.
+ * 
+ * <p>
+ * This class defines the names for the attributes and directives for this
+ * namespace. All unspecified capability attributes are of type {@code String}
+ * and are used as arbitrary matching attributes for the capability. The values
+ * associated with the specified directive and attribute keys are of type
+ * {@code String}, unless otherwise indicated.
+ * 
+ * <p>
+ * Unless otherwise noted, all directives specified on the
+ * {@code Bundle-SymbolicName} header are visible in the capability and all
+ * directives specified on the {@code Require-Bundle} header are visible in the
+ * requirement.
+ * 
+ * <ul>
+ * <li>The {@link Namespace#CAPABILITY_USES_DIRECTIVE uses} directive must be
+ * ignored. A {@code uses} directive specified on the
+ * {@code Bundle-SymbolicName} header must be ignored. A {@code uses} directive
+ * must not be present in the capability.</li>
+ * <li>The {@link Namespace#CAPABILITY_EFFECTIVE_DIRECTIVE effective}
+ * {@link Namespace#REQUIREMENT_EFFECTIVE_DIRECTIVE directives} must be ignored.
+ * This namespace is only effective at {@link Namespace#EFFECTIVE_RESOLVE
+ * resolve} time. An {@code effective} directive specified on the
+ * {@code Bundle-SymbolicName} or {@code Require-Bundle} headers must be
+ * ignored. An {@code effective} directive must not be present in a capability
+ * or requirement.</li>
+ * <li>The {@link Namespace#REQUIREMENT_CARDINALITY_DIRECTIVE cardinality}
+ * directive must be ignored. A {@code cardinality} directive specified on the
+ * {@code Require-Bundle} header must be ignored. A {@code cardinality}
+ * directive must not be present in a requirement.</li>
+ * </ul>
+ * 
+ * <p>
+ * A non-fragment resource with the {@link IdentityNamespace#TYPE_BUNDLE
+ * osgi.bundle} type {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE
+ * identity} provides exactly one<sup>†</sup> bundle capability (that is,
+ * the bundle can be required by another bundle). A fragment resource with the
+ * {@link IdentityNamespace#TYPE_FRAGMENT osgi.fragment} type
+ * {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE identity} must not declare
+ * a bundle capability. A resource requires zero or more bundle requirements
+ * (that is, required bundles).
+ * <p>
+ * † A resource with no symbolic name must not provide a bundle
+ * capability.
+ * 
+ * @Immutable
+ * @version $Id: 339f1204725aa9d9c2463b1224b2e38e505024e9 $
+ */
+public final class BundleNamespace extends AbstractWiringNamespace {
+
+	/**
+	 * Namespace name for bundle capabilities and requirements.
+	 * 
+	 * <p>
+	 * Also, the capability attribute used to specify the symbolic name of the
+	 * bundle.
+	 */
+	public static final String	BUNDLE_NAMESPACE							= "osgi.wiring.bundle";
+
+	/**
+	 * The capability directive identifying if the resource is a singleton. A
+	 * {@code String} value of "{@code true}" indicates the resource
+	 * is a singleton; any other value or {@code null} indicates the resource is
+	 * not a singleton.
+	 * 
+	 * <p>
+	 * This directive should be examined using the {@link IdentityNamespace
+	 * identity} namespace.
+	 * 
+	 * @see IdentityNamespace#CAPABILITY_SINGLETON_DIRECTIVE
+	 */
+	public static final String	CAPABILITY_SINGLETON_DIRECTIVE				= "singleton";
+
+	/**
+	 * The capability directive identifying if and when a fragment may attach to
+	 * a host bundle.
+	 * 
+	 * <p>
+	 * This directive should be examined using the {@link HostNamespace host}
+	 * namespace.
+	 * 
+	 * @see HostNamespace#CAPABILITY_FRAGMENT_ATTACHMENT_DIRECTIVE
+	 */
+	public static final String	CAPABILITY_FRAGMENT_ATTACHMENT_DIRECTIVE	= "fragment-attachment";
+
+	/**
+	 * The requirement directive used to specify the type of the extension
+	 * fragment.
+	 * 
+	 * <p>
+	 * This directive should be examined using the {@link HostNamespace host}
+	 * namespace.
+	 * 
+	 * @see HostNamespace#REQUIREMENT_EXTENSION_DIRECTIVE
+	 */
+	public final static String	REQUIREMENT_EXTENSION_DIRECTIVE				= "extension";
+
+	/**
+	 * The requirement directive used to specify the visibility type for a
+	 * requirement. The default value is {@link #VISIBILITY_PRIVATE private}.
+	 * 
+	 * @see #VISIBILITY_PRIVATE private
+	 * @see #VISIBILITY_REEXPORT reexport
+	 */
+	public final static String	REQUIREMENT_VISIBILITY_DIRECTIVE			= "visibility";
+
+	/**
+	 * The directive value identifying a private
+	 * {@link #REQUIREMENT_VISIBILITY_DIRECTIVE visibility} type. A private
+	 * visibility type indicates that any {@link PackageNamespace packages} that
+	 * are exported by the required bundle are not made visible on the export
+	 * signature of the requiring bundle. .
+	 * 
+	 * @see #REQUIREMENT_VISIBILITY_DIRECTIVE
+	 */
+	public final static String	VISIBILITY_PRIVATE							= "private";
+
+	/**
+	 * The directive value identifying a reexport
+	 * {@link #REQUIREMENT_VISIBILITY_DIRECTIVE visibility} type. A reexport
+	 * visibility type indicates any {@link PackageNamespace packages} that are
+	 * exported by the required bundle are re-exported by the requiring bundle.
+	 * 
+	 * @see #REQUIREMENT_VISIBILITY_DIRECTIVE
+	 */
+	public final static String	VISIBILITY_REEXPORT							= "reexport";
+
+	private BundleNamespace() {
+		// empty
+	}
+}
diff --git a/src/main/java/org/osgi/framework/namespace/ExecutionEnvironmentNamespace.java b/src/main/java/org/osgi/framework/namespace/ExecutionEnvironmentNamespace.java
new file mode 100644
index 0000000..5328cae
--- /dev/null
+++ b/src/main/java/org/osgi/framework/namespace/ExecutionEnvironmentNamespace.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.namespace;
+
+import org.osgi.resource.Namespace;
+
+/**
+ * Execution Environment Capability and Requirement Namespace.
+ * 
+ * <p>
+ * This class defines the names for the attributes and directives for this
+ * namespace. All unspecified capability attributes are of type {@code String}
+ * and are used as arbitrary matching attributes for the capability. The values
+ * associated with the specified directive and attribute keys are of type
+ * {@code String}, unless otherwise indicated.
+ * 
+ * @Immutable
+ * @version $Id: e1c30aac8efacc1b21ab20ffebcc1af30a1054a8 $
+ */
+public final class ExecutionEnvironmentNamespace extends Namespace {
+
+	/**
+	 * Namespace name for execution environment capabilities and requirements.
+	 * 
+	 * <p>
+	 * Also, the capability attribute used to specify the name of the execution
+	 * environment.
+	 */
+	public static final String	EXECUTION_ENVIRONMENT_NAMESPACE	= "osgi.ee";
+
+	/**
+	 * The capability attribute contains the versions of the execution
+	 * environment. The value of this attribute must be of type
+	 * {@code List<Version>}.
+	 */
+	public final static String	CAPABILITY_VERSION_ATTRIBUTE	= "version";
+
+	private ExecutionEnvironmentNamespace() {
+		// empty
+	}
+}
diff --git a/src/main/java/org/osgi/framework/namespace/HostNamespace.java b/src/main/java/org/osgi/framework/namespace/HostNamespace.java
new file mode 100644
index 0000000..5964cf5
--- /dev/null
+++ b/src/main/java/org/osgi/framework/namespace/HostNamespace.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.namespace;
+
+import org.osgi.resource.Namespace;
+
+/**
+ * Host Capability and Requirement Namespace.
+ * 
+ * <p>
+ * This class defines the names for the attributes and directives for this
+ * namespace. All unspecified capability attributes are of type {@code String}
+ * and are used as arbitrary matching attributes for the capability. The values
+ * associated with the specified directive and attribute keys are of type
+ * {@code String}, unless otherwise indicated.
+ * 
+ * <p>
+ * Unless otherwise noted, all directives specified on the
+ * {@code Bundle-SymbolicName} header are visible in the capability and all
+ * directives specified on the {@code Fragment-Host} header are visible in the
+ * requirement.
+ * 
+ * <ul>
+ * <li>The {@link Namespace#CAPABILITY_USES_DIRECTIVE uses} directive must be
+ * ignored. A {@code uses} directive specified on the
+ * {@code Bundle-SymbolicName} header must be ignored. A {@code uses} directive
+ * must not be present in the capability.</li>
+ * <li>The {@link Namespace#CAPABILITY_EFFECTIVE_DIRECTIVE effective}
+ * {@link Namespace#REQUIREMENT_EFFECTIVE_DIRECTIVE directives} must be ignored.
+ * This namespace is only effective at {@link Namespace#EFFECTIVE_RESOLVE
+ * resolve} time. An {@code effective} directive specified on the
+ * {@code Bundle-SymbolicName} or {@code Fragment-Host} headers must be ignored.
+ * An {@code effective} directive must not be present in a capability or
+ * requirement.</li>
+ * <li>The {@link Namespace#REQUIREMENT_CARDINALITY_DIRECTIVE cardinality}
+ * directive has limited applicability to this namespace. A {@code cardinality}
+ * directive specified on the {@code Fragment-Host} header must be ignored. All
+ * requirements must have the {@code cardinality} directive set to
+ * {@link Namespace#CARDINALITY_MULTIPLE multiple}.</li>
+ * </ul>
+ * 
+ * <p>
+ * A non-fragment resource with the with the
+ * {@link IdentityNamespace#TYPE_BUNDLE osgi.bundle} type
+ * {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE identity} provides zero or
+ * one<sup>†</sup> host capabilities. A fragment resource with the
+ * {@link IdentityNamespace#TYPE_FRAGMENT osgi.fragment} type
+ * {@link IdentityNamespace#CAPABILITY_TYPE_ATTRIBUTE identity} must not declare
+ * a host capability and must declare exactly one host requirement.
+ * <p>
+ * † A resource with no bundle symbolic name must not provide a host
+ * capability.
+ * 
+ * @Immutable
+ * @version $Id: aa3cc744c7b9c21d908260f456567ab8a6de1430 $
+ */
+public final class HostNamespace extends AbstractWiringNamespace {
+
+	/**
+	 * Namespace name for host capabilities and requirements.
+	 * 
+	 * <p>
+	 * Also, the capability attribute used to specify the symbolic name of the
+	 * host.
+	 * 
+	 */
+	public static final String	HOST_NAMESPACE								= "osgi.wiring.host";
+
+	/**
+	 * The capability directive identifying if the resource is a singleton. A
+	 * {@code String} value of "{@code true}" indicates the resource
+	 * is a singleton; any other value or {@code null} indicates the resource is
+	 * not a singleton.
+	 * 
+	 * <p>
+	 * This directive should be examined using the {@link IdentityNamespace
+	 * identity} namespace.
+	 * 
+	 * @see IdentityNamespace#CAPABILITY_SINGLETON_DIRECTIVE
+	 */
+	public static final String	CAPABILITY_SINGLETON_DIRECTIVE				= "singleton";
+
+	/**
+	 * The capability directive identifying if and when a fragment may attach to
+	 * a host bundle. The default value is {@link #FRAGMENT_ATTACHMENT_ALWAYS
+	 * always}.
+	 * 
+	 * @see #FRAGMENT_ATTACHMENT_ALWAYS
+	 * @see #FRAGMENT_ATTACHMENT_RESOLVETIME
+	 * @see #FRAGMENT_ATTACHMENT_NEVER
+	 */
+	public static final String	CAPABILITY_FRAGMENT_ATTACHMENT_DIRECTIVE	= "fragment-attachment";
+
+	/**
+	 * The directive value indicating that fragments are allowed to attach to
+	 * the host bundle at any time (while the host is resolved or during the
+	 * process of resolving the host bundle).
+	 * 
+	 * @see #CAPABILITY_FRAGMENT_ATTACHMENT_DIRECTIVE
+	 */
+	public static final String	FRAGMENT_ATTACHMENT_ALWAYS					= "always";
+
+	/**
+	 * The directive value indicating that fragments are allowed to attach to
+	 * the host bundle only during the process of resolving the host bundle.
+	 * 
+	 * @see #CAPABILITY_FRAGMENT_ATTACHMENT_DIRECTIVE
+	 */
+	public static final String	FRAGMENT_ATTACHMENT_RESOLVETIME				= "resolve-time";
+
+	/**
+	 * The directive value indicating that no fragments are allowed to attach to
+	 * the host bundle at any time.
+	 * 
+	 * @see #CAPABILITY_FRAGMENT_ATTACHMENT_DIRECTIVE
+	 */
+	public static final String	FRAGMENT_ATTACHMENT_NEVER					= "never";
+
+	/**
+	 * The requirement directive used to specify the type of the extension
+	 * fragment.
+	 * 
+	 * @see #EXTENSION_FRAMEWORK
+	 * @see #EXTENSION_BOOTCLASSPATH
+	 */
+	public final static String	REQUIREMENT_EXTENSION_DIRECTIVE				= "extension";
+
+	/**
+	 * The directive value indicating that the extension fragment is to be
+	 * loaded by the framework's class loader.
+	 * 
+	 * 
+	 * @see #REQUIREMENT_EXTENSION_DIRECTIVE
+	 */
+	public final static String	EXTENSION_FRAMEWORK							= "framework";
+
+	/**
+	 * The directive value indicating that the extension fragment is to be
+	 * loaded by the boot class loader.
+	 * 
+	 * @see #REQUIREMENT_EXTENSION_DIRECTIVE
+	 */
+	public final static String	EXTENSION_BOOTCLASSPATH						= "bootclasspath";
+
+	/**
+	 * The requirement directive used to specify the visibility type for a
+	 * requirement.
+	 * 
+	 * <p>
+	 * This directive should be examined using the {@link BundleNamespace
+	 * bundle} namespace.
+	 * 
+	 * @see BundleNamespace#REQUIREMENT_VISIBILITY_DIRECTIVE
+	 */
+	public final static String	REQUIREMENT_VISIBILITY_DIRECTIVE			= "visibility";
+
+	private HostNamespace() {
+		// empty
+	}
+}
diff --git a/src/main/java/org/osgi/framework/namespace/IdentityNamespace.java b/src/main/java/org/osgi/framework/namespace/IdentityNamespace.java
new file mode 100644
index 0000000..c925e5a
--- /dev/null
+++ b/src/main/java/org/osgi/framework/namespace/IdentityNamespace.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.namespace;
+
+import org.osgi.resource.Namespace;
+
+/**
+ * Identity Capability and Requirement Namespace.
+ * 
+ * <p>
+ * This class defines the names for the attributes and directives for this
+ * namespace. All unspecified capability attributes are of type {@code String}
+ * and are used as arbitrary matching attributes for the capability. The values
+ * associated with the specified directive and attribute keys are of type
+ * {@code String}, unless otherwise indicated.
+ * 
+ * <p>
+ * Each resource provides exactly one<sup>†</sup> identity capability that
+ * can be used to identify the resource.
+ * 
+ * <p>
+ * The bundle wiring for the bundle revision provides exactly
+ * one<sup>†</sup> identity capability.
+ * 
+ * <p>
+ * † A resource with no symbolic name must not provide an identity
+ * capability.
+ * 
+ * @Immutable
+ * @version $Id: e34dcaba1f828326a0db13b3d811b2d170ff97a5 $
+ */
+public final class IdentityNamespace extends Namespace {
+
+	/**
+	 * Namespace name for identity capabilities and requirements.
+	 * 
+	 * <p>
+	 * Also, the capability attribute used to specify the symbolic name of the
+	 * resource.
+	 */
+	public static final String	IDENTITY_NAMESPACE					= "osgi.identity";
+
+	/**
+	 * The capability directive identifying if the resource is a singleton. A
+	 * {@code String} value of "true" indicates the resource is a
+	 * singleton; any other value or {@code null} indicates the resource is not
+	 * a singleton.
+	 */
+	public static final String	CAPABILITY_SINGLETON_DIRECTIVE		= "singleton";
+
+	/**
+	 * The capability attribute identifying the {@code Version} of the resource
+	 * if one is specified or {@code 0.0.0} if not specified. The value of this
+	 * attribute must be of type {@code Version}.
+	 */
+	public static final String	CAPABILITY_VERSION_ATTRIBUTE		= "version";
+
+	/**
+	 * The capability attribute identifying the resource type. If the resource
+	 * has no type then the value {@link #TYPE_UNKNOWN unknown} must be used for
+	 * the attribute.
+	 * 
+	 * @see #TYPE_BUNDLE
+	 * @see #TYPE_FRAGMENT
+	 * @see #TYPE_UNKNOWN
+	 */
+	public static final String	CAPABILITY_TYPE_ATTRIBUTE			= "type";
+
+	/**
+	 * The attribute value identifying the resource
+	 * {@link #CAPABILITY_TYPE_ATTRIBUTE type} as an OSGi bundle.
+	 * 
+	 * @see #CAPABILITY_TYPE_ATTRIBUTE
+	 */
+	public static final String	TYPE_BUNDLE							= "osgi.bundle";
+
+	/**
+	 * The attribute value identifying the resource
+	 * {@link #CAPABILITY_TYPE_ATTRIBUTE type} as an OSGi fragment.
+	 * 
+	 * @see #CAPABILITY_TYPE_ATTRIBUTE
+	 */
+	public static final String	TYPE_FRAGMENT						= "osgi.fragment";
+
+	/**
+	 * The attribute value identifying the resource
+	 * {@link #CAPABILITY_TYPE_ATTRIBUTE type} as unknown.
+	 * 
+	 * @see #CAPABILITY_TYPE_ATTRIBUTE
+	 */
+	public static final String	TYPE_UNKNOWN						= "unknown";
+
+	/**
+	 * The capability attribute that contains a human readable copyright notice
+	 * for the resource. See the {@code Bundle-Copyright} manifest header.
+	 */
+	public static final String	CAPABILITY_COPYRIGHT_ATTRIBUTE		= "copyright";
+
+	/**
+	 * The capability attribute that contains a human readable description for
+	 * the resource. See the {@code Bundle-Description} manifest header.
+	 */
+	public static final String	CAPABILITY_DESCRIPTION_ATTRIBUTE	= "description";
+
+	/**
+	 * The capability attribute that contains the URL to documentation for the
+	 * resource. See the {@code Bundle-DocURL} manifest header.
+	 */
+	public static final String	CAPABILITY_DOCUMENTATION_ATTRIBUTE	= "documentation";
+
+	/**
+	 * The capability attribute that contains the URL to the license for the
+	 * resource. See the {@code name} portion of the {@code Bundle-License}
+	 * manifest header.
+	 */
+	public static final String	CAPABILITY_LICENSE_ATTRIBUTE		= "license";
+
+	/**
+	 * The requirement directive that classifies the relationship with another
+	 * resource.
+	 * 
+	 * @see #CLASSIFIER_SOURCES
+	 * @see #CLASSIFIER_JAVADOC
+	 */
+	public static final String	REQUIREMENT_CLASSIFIER_DIRECTIVE	= "classifier";
+
+	/**
+	 * The attribute value identifying the resource
+	 * {@link #REQUIREMENT_CLASSIFIER_DIRECTIVE classifier} as an archive
+	 * containing the source code in the same directory layout as the resource.
+	 * 
+	 * @see #REQUIREMENT_CLASSIFIER_DIRECTIVE
+	 */
+
+	public static final String	CLASSIFIER_SOURCES					= "sources";
+	/**
+	 * The attribute value identifying the resource
+	 * {@link #REQUIREMENT_CLASSIFIER_DIRECTIVE classifier} as an archive
+	 * containing the javadoc in the same directory layout as the resource.
+	 * 
+	 * @see #REQUIREMENT_CLASSIFIER_DIRECTIVE
+	 */
+	public static final String	CLASSIFIER_JAVADOC					= "javadoc";
+
+	private IdentityNamespace() {
+		// empty
+	}
+}
diff --git a/src/main/java/org/osgi/framework/namespace/PackageNamespace.java b/src/main/java/org/osgi/framework/namespace/PackageNamespace.java
new file mode 100644
index 0000000..2d1cbc3
--- /dev/null
+++ b/src/main/java/org/osgi/framework/namespace/PackageNamespace.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.namespace;
+
+import org.osgi.resource.Namespace;
+
+/**
+ * Package Capability and Requirement Namespace.
+ * 
+ * <p>
+ * A resource provides zero or more package capabilities (this is, exported
+ * packages) and requires zero or more package requirements (that is, imported
+ * packages).
+ * 
+ * <p>
+ * This class defines the names for the attributes and directives for this
+ * namespace. All unspecified capability attributes are of type {@code String}
+ * and are used as arbitrary matching attributes for the capability. The values
+ * associated with the specified directive and attribute keys are of type
+ * {@code String}, unless otherwise indicated.
+ * 
+ * <p>
+ * Unless otherwise noted, all directives specified on the
+ * {@code Export-Package} header are visible in the capability and all
+ * directives specified on the {@code Import-Package} and
+ * {@code DynamicImport-Package} headers are visible in the requirement.
+ * 
+ * <ul>
+ * <li>The {@link Namespace#CAPABILITY_EFFECTIVE_DIRECTIVE effective}
+ * {@link Namespace#REQUIREMENT_EFFECTIVE_DIRECTIVE directives} must be ignored.
+ * This namespace is only effective at {@link Namespace#EFFECTIVE_RESOLVE
+ * resolve} time. An {@code effective} directive specified on the
+ * {@code Export-Package}, {@code Import-Package} or
+ * {@code DynamicImport-Package} headers must be ignored. An {@code effective}
+ * directive must not be present in a capability or requirement.</li>
+ * <li>The {@link Namespace#REQUIREMENT_CARDINALITY_DIRECTIVE cardinality}
+ * directive has limited applicability to this namespace. A {@code cardinality}
+ * directive specified on the {@code Import-Package} or
+ * {@code DynamicImport-Package} headers must be ignored. Only requirements with
+ * {@link Namespace#REQUIREMENT_RESOLUTION_DIRECTIVE resolution} set to
+ * {@link #RESOLUTION_DYNAMIC dynamic} and the package name contains a wildcard
+ * must have the {@code cardinality} directive set to
+ * {@link Namespace#CARDINALITY_MULTIPLE multiple}. Otherwise, a
+ * {@code cardinality} directive must not be present in a requirement.</li>
+ * </ul>
+ * 
+ * @Immutable
+ * @version $Id: 5adc45bd1ae26120cbff3562c7c8cefc01e38bd3 $
+ */
+public final class PackageNamespace extends AbstractWiringNamespace {
+
+	/**
+	 * Namespace name for package capabilities and requirements.
+	 * 
+	 * <p>
+	 * Also, the capability attribute used to specify the name of the package.
+	 */
+	public static final String	PACKAGE_NAMESPACE							= "osgi.wiring.package";
+
+	/**
+	 * The capability directive used to specify the comma separated list of
+	 * classes which must be allowed to be exported.
+	 */
+	public final static String	CAPABILITY_INCLUDE_DIRECTIVE				= "include";
+
+	/**
+	 * The capability directive used to specify the comma separated list of
+	 * classes which must not be allowed to be exported.
+	 */
+	public final static String	CAPABILITY_EXCLUDE_DIRECTIVE				= "exclude";
+
+	/**
+	 * The capability attribute contains the {@code Version} of the package if
+	 * one is specified or {@code 0.0.0} if not specified. The value of this
+	 * attribute must be of type {@code Version}.
+	 */
+	public final static String	CAPABILITY_VERSION_ATTRIBUTE				= "version";
+
+	/**
+	 * The capability attribute contains the symbolic name of the resource
+	 * providing the package.
+	 */
+	public final static String	CAPABILITY_BUNDLE_SYMBOLICNAME_ATTRIBUTE	= "bundle-symbolic-name";
+
+	/**
+	 * The directive value identifying a dynamic requirement resolution type. A
+	 * dynamic resolution type indicates that the requirement is resolved
+	 * dynamically at runtime (such as a dynamically imported package) and the
+	 * resource will be resolved without the requirement being resolved.
+	 * 
+	 * @see Namespace#REQUIREMENT_RESOLUTION_DIRECTIVE
+	 */
+	public final static String	RESOLUTION_DYNAMIC							= "dynamic";
+
+	private PackageNamespace() {
+		// empty
+	}
+}
diff --git a/src/main/java/org/osgi/framework/startlevel/FrameworkStartLevel.java b/src/main/java/org/osgi/framework/startlevel/FrameworkStartLevel.java
index adb51ec..11a8049 100644
--- a/src/main/java/org/osgi/framework/startlevel/FrameworkStartLevel.java
+++ b/src/main/java/org/osgi/framework/startlevel/FrameworkStartLevel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2002, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2011). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ import org.osgi.framework.FrameworkListener;
  * 
  * @ThreadSafe
  * @noimplement
- * @version $Id: 2bca22671674ba50b8c6801d5d1df8e291fe2a9d $
+ * @version $Id: 12c6f60842df994c7de2cc3cfd02f791b95fc35b $
  */
 public interface FrameworkStartLevel extends BundleReference {
 	/**
@@ -126,7 +126,7 @@ public interface FrameworkStartLevel extends BundleReference {
 	 * is first installed.
 	 * 
 	 * @return The initial start level value for Bundles.
-	 * @see #setInitialBundleStartLevel
+	 * @see #setInitialBundleStartLevel(int)
 	 */
 	int getInitialBundleStartLevel();
 
diff --git a/src/main/java/org/osgi/framework/wiring/BundleCapability.java b/src/main/java/org/osgi/framework/wiring/BundleCapability.java
index c49f0ac..19d7a67 100644
--- a/src/main/java/org/osgi/framework/wiring/BundleCapability.java
+++ b/src/main/java/org/osgi/framework/wiring/BundleCapability.java
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
- * 
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
@@ -17,6 +17,8 @@
 package org.osgi.framework.wiring;
 
 import java.util.Map;
+import org.osgi.framework.namespace.AbstractWiringNamespace;
+import org.osgi.resource.Capability;
 
 /**
  * A capability that has been declared from a {@link BundleRevision bundle
@@ -24,19 +26,32 @@ import java.util.Map;
  * 
  * @ThreadSafe
  * @noimplement
- * @version $Id: 0fde13c3228af1aa97872b37ccf0aa6e23123b11 $
+ * @version $Id: 39086f7e6086c2b3d83fbcb976a011cf69483ad8 $
  */
-public interface BundleCapability {
+public interface BundleCapability extends Capability {
+
 	/**
-	 * Returns the name space of this capability.
+	 * Returns the bundle revision declaring this capability.
 	 * 
-	 * @return The name space of this capability.
+	 * @return The bundle revision declaring this capability.
+	 */
+	BundleRevision getRevision();
+
+	/**
+	 * Returns the namespace of this capability.
+	 * 
+	 * @return The namespace of this capability.
 	 */
 	String getNamespace();
 
 	/**
 	 * Returns the directives of this capability.
 	 * 
+	 * <p>
+	 * All capability directives not specified by the
+	 * {@link AbstractWiringNamespace wiring namespaces} have no specified
+	 * semantics and are considered extra user defined information.
+	 * 
 	 * @return An unmodifiable map of directive names to directive values for
 	 *         this capability, or an empty map if this capability has no
 	 *         directives.
@@ -53,9 +68,13 @@ public interface BundleCapability {
 	Map<String, Object> getAttributes();
 
 	/**
-	 * Returns the bundle revision declaring this capability.
+	 * Returns the resource declaring this capability.
 	 * 
-	 * @return The bundle revision declaring this capability.
+	 * <p>
+	 * This method returns the same value as {@link #getRevision()}.
+	 * 
+	 * @return The resource declaring this capability.
+	 * @since 1.1
 	 */
-	BundleRevision getRevision();
+	BundleRevision getResource();
 }
diff --git a/src/main/java/org/osgi/framework/wiring/BundleRequirement.java b/src/main/java/org/osgi/framework/wiring/BundleRequirement.java
index bd637e6..bb26c5d 100644
--- a/src/main/java/org/osgi/framework/wiring/BundleRequirement.java
+++ b/src/main/java/org/osgi/framework/wiring/BundleRequirement.java
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
- * 
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
@@ -17,6 +17,8 @@
 package org.osgi.framework.wiring;
 
 import java.util.Map;
+import org.osgi.framework.namespace.AbstractWiringNamespace;
+import org.osgi.resource.Requirement;
 
 /**
  * A requirement that has been declared from a {@link BundleRevision bundle
@@ -24,19 +26,43 @@ import java.util.Map;
  * 
  * @ThreadSafe
  * @noimplement
- * @version $Id: 659132c1fac7526240df377ead0e1bc8d4af2e77 $
+ * @version $Id: 212ffb64f724d982db86ff7e49ed64ea530e670a $
  */
-public interface BundleRequirement {
+public interface BundleRequirement extends Requirement {
+	/**
+	 * Returns the bundle revision declaring this requirement.
+	 * 
+	 * @return The bundle revision declaring this requirement.
+	 */
+	BundleRevision getRevision();
+
 	/**
-	 * Returns the name space of this requirement.
+	 * Returns whether the specified capability matches this requirement.
 	 * 
-	 * @return The name space of this requirement.
+	 * @param capability The capability to match to this requirement.
+	 * @return {@code true} if the specified capability has the same
+	 *         {@link #getNamespace() namespace} as this requirement and the
+	 *         filter for this requirement matches the
+	 *         {@link BundleCapability#getAttributes() attributes of the
+	 *         specified capability}; {@code false} otherwise.
+	 */
+	boolean matches(BundleCapability capability);
+
+	/**
+	 * Returns the namespace of this requirement.
+	 * 
+	 * @return The namespace of this requirement.
 	 */
 	String getNamespace();
 
 	/**
 	 * Returns the directives of this requirement.
 	 * 
+	 * <p>
+	 * All requirement directives not specified by the
+	 * {@link AbstractWiringNamespace wiring namespaces} have no specified
+	 * semantics and are considered extra user defined information.
+	 * 
 	 * @return An unmodifiable map of directive names to directive values for
 	 *         this requirement, or an empty map if this requirement has no
 	 *         directives.
@@ -46,6 +72,10 @@ public interface BundleRequirement {
 	/**
 	 * Returns the attributes of this requirement.
 	 * 
+	 * <p>
+	 * Requirement attributes have no specified semantics and are considered
+	 * extra user defined information.
+	 * 
 	 * @return An unmodifiable map of attribute names to attribute values for
 	 *         this requirement, or an empty map if this requirement has no
 	 *         attributes.
@@ -53,21 +83,14 @@ public interface BundleRequirement {
 	Map<String, Object> getAttributes();
 
 	/**
-	 * Returns the bundle revision declaring this requirement.
+	 * Returns the resource declaring this requirement.
 	 * 
-	 * @return The bundle revision declaring this requirement.
-	 */
-	BundleRevision getRevision();
-
-	/**
-	 * Returns whether the specified capability matches this requirement.
+	 * <p>
+	 * This method returns the same value as {@link #getRevision()}.
 	 * 
-	 * @param capability The capability to match to this requirement.
-	 * @return {@code true} if the specified capability has the same
-	 *         {@link #getNamespace() name space} as this requirement and the
-	 *         filter for this requirement matches the
-	 *         {@link BundleCapability#getAttributes() attributes of the
-	 *         specified capability}; {@code false} otherwise.
+	 * @return The resource declaring this requirement. This can be {@code null}
+	 *         if this requirement is synthesized.
+	 * @since 1.1
 	 */
-	boolean matches(BundleCapability capability);
+	BundleRevision getResource();
 }
diff --git a/src/main/java/org/osgi/framework/wiring/BundleRevision.java b/src/main/java/org/osgi/framework/wiring/BundleRevision.java
index 5924dc1..1ba9365 100644
--- a/src/main/java/org/osgi/framework/wiring/BundleRevision.java
+++ b/src/main/java/org/osgi/framework/wiring/BundleRevision.java
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
- * 
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
@@ -17,11 +17,16 @@
 package org.osgi.framework.wiring;
 
 import java.util.List;
-
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleReference;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
 
 /**
  * Bundle Revision. When a bundle is installed and each time a bundle is
@@ -38,18 +43,18 @@ import org.osgi.framework.Version;
  * a current revision, adapting such a bundle returns {@code null}.
  * 
  * <p>
- * The framework defines name spaces for {@link #PACKAGE_NAMESPACE package},
- * {@link #BUNDLE_NAMESPACE bundle} and {@link #HOST_NAMESPACE host}
- * capabilities and requirements. These name spaces are defined only to express
- * wiring information by the framework. They must not be used in
+ * The framework defines namespaces for {@link PackageNamespace package},
+ * {@link BundleNamespace bundle} and {@link HostNamespace host} capabilities
+ * and requirements. These namespaces are defined only to express wiring
+ * information by the framework. They must not be used in
  * {@link Constants#PROVIDE_CAPABILITY Provide-Capability} and
  * {@link Constants#REQUIRE_CAPABILITY Require-Capability} manifest headers.
  * 
  * @ThreadSafe
  * @noimplement
- * @version $Id: 139b3046ebd46c48b03dda8d36f2f9d79e2e616d $
+ * @version $Id: e68e01a670f0ae9d6eb736414f875c8b216ed1bc $
  */
-public interface BundleRevision extends BundleReference {
+public interface BundleRevision extends BundleReference, Resource {
 	/**
 	 * Returns the symbolic name for this bundle revision.
 	 * 
@@ -71,41 +76,43 @@ public interface BundleRevision extends BundleReference {
 	/**
 	 * Returns the capabilities declared by this bundle revision.
 	 * 
-	 * @param namespace The name space of the declared capabilities to return or
-	 *        {@code null} to return the declared capabilities from all name
-	 *        spaces.
-	 * @return A list containing a snapshot of the declared
-	 *         {@link BundleCapability}s, or an empty list if this bundle
-	 *         revision declares no capabilities in the specified name space.
-	 *         The list contains the declared capabilities in the order they are
-	 *         specified in the manifest.
+	 * @param namespace The namespace of the declared capabilities to return or
+	 *        {@code null} to return the declared capabilities from all
+	 *        namespaces.
+	 * @return An unmodifiable list containing the declared
+	 *         {@link BundleCapability}s from the specified namespace. The
+	 *         returned list will be empty if this bundle revision declares no
+	 *         capabilities in the specified namespace. The list contains the
+	 *         declared capabilities in the order they are specified in the
+	 *         manifest.
 	 */
 	List<BundleCapability> getDeclaredCapabilities(String namespace);
 
 	/**
 	 * Returns the requirements declared by this bundle revision.
 	 * 
-	 * @param namespace The name space of the declared requirements to return or
-	 *        {@code null} to return the declared requirements from all name
-	 *        spaces.
-	 * @return A list containing a snapshot of the declared
-	 *         {@link BundleRequirement}s, or an empty list if this bundle
-	 *         revision declares no requirements in the specified name space.
-	 *         The list contains the declared requirements in the order they are
-	 *         specified in the manifest.
+	 * @param namespace The namespace of the declared requirements to return or
+	 *        {@code null} to return the declared requirements from all
+	 *        namespaces.
+	 * @return An unmodifiable list containing the declared
+	 *         {@link BundleRequirement}s from the specified namespace. The
+	 *         returned list will be empty if this bundle revision declares no
+	 *         requirements in the specified namespace. The list contains the
+	 *         declared requirements in the order they are specified in the
+	 *         manifest.
 	 */
 	List<BundleRequirement> getDeclaredRequirements(String namespace);
 
 	/**
-	 * Name space for package capabilities and requirements.
+	 * Namespace for package capabilities and requirements.
 	 * 
 	 * <p>
 	 * The name of the package is stored in the capability attribute of the same
-	 * name as this name space (osgi.wiring.package). The other
-	 * directives and attributes of the package, from the
-	 * {@link Constants#EXPORT_PACKAGE Export-Package} manifest header, can be
-	 * found in the cabability's {@link BundleCapability#getDirectives()
-	 * directives} and {@link BundleCapability#getAttributes() attributes}. The
+	 * name as this namespace (osgi.wiring.package). The other directives and
+	 * attributes of the package, from the {@link Constants#EXPORT_PACKAGE
+	 * Export-Package} manifest header, can be found in the cabability's
+	 * {@link BundleCapability#getDirectives() directives} and
+	 * {@link BundleCapability#getAttributes() attributes}. The
 	 * {@link Constants#VERSION_ATTRIBUTE version} capability attribute must
 	 * contain the {@link Version} of the package if one is specified or
 	 * {@link Version#emptyVersion} if not specified. The
@@ -136,16 +143,18 @@ public interface BundleRevision extends BundleReference {
 	 * resolved package requirements (that is, imported packages). The number of
 	 * package wires required by a bundle wiring may change as the bundle wiring
 	 * may dynamically import additional packages.
+	 * 
+	 * @see PackageNamespace
 	 */
-	String	PACKAGE_NAMESPACE	= "osgi.wiring.package";
+	String	PACKAGE_NAMESPACE	= PackageNamespace.PACKAGE_NAMESPACE;
 
 	/**
-	 * Name space for bundle capabilities and requirements.
+	 * Namespace for bundle capabilities and requirements.
 	 * 
 	 * <p>
 	 * The bundle symbolic name of the bundle is stored in the capability
-	 * attribute of the same name as this name space (osgi.wiring.bundle).
-	 * The other directives and attributes of the bundle, from the
+	 * attribute of the same name as this namespace (osgi.wiring.bundle). The
+	 * other directives and attributes of the bundle, from the
 	 * {@link Constants#BUNDLE_SYMBOLICNAME Bundle-SymbolicName} manifest
 	 * header, can be found in the cabability's
 	 * {@link BundleCapability#getDirectives() directives} and
@@ -174,16 +183,18 @@ public interface BundleRevision extends BundleReference {
 	 * † A bundle with no bundle symbolic name (that is, a bundle with
 	 * {@link Constants#BUNDLE_MANIFESTVERSION Bundle-ManifestVersion}
 	 * {@literal <} 2) must not provide a bundle capability.
+	 * 
+	 * @see BundleNamespace
 	 */
-	String	BUNDLE_NAMESPACE	= "osgi.wiring.bundle";
+	String	BUNDLE_NAMESPACE	= BundleNamespace.BUNDLE_NAMESPACE;
 
 	/**
-	 * Name space for host capabilities and requirements.
+	 * Namespace for host capabilities and requirements.
 	 * 
 	 * <p>
 	 * The bundle symbolic name of the bundle is stored in the capability
-	 * attribute of the same name as this name space (osgi.wiring.host).
-	 * The other directives and attributes of the bundle, from the
+	 * attribute of the same name as this namespace (osgi.wiring.host). The
+	 * other directives and attributes of the bundle, from the
 	 * {@link Constants#BUNDLE_SYMBOLICNAME Bundle-SymbolicName} manifest
 	 * header, can be found in the cabability's
 	 * {@link BundleCapability#getDirectives() directives} and
@@ -215,8 +226,10 @@ public interface BundleRevision extends BundleReference {
 	 * † A bundle with no bundle symbolic name (that is, a bundle with
 	 * {@link Constants#BUNDLE_MANIFESTVERSION Bundle-ManifestVersion}
 	 * {@literal <} 2) must not provide a host capability.
+	 * 
+	 * @see HostNamespace
 	 */
-	String	HOST_NAMESPACE		= "osgi.wiring.host";
+	String	HOST_NAMESPACE		= HostNamespace.HOST_NAMESPACE;
 
 	/**
 	 * Returns the special types of this bundle revision. The bundle revision
@@ -252,4 +265,40 @@ public interface BundleRevision extends BundleReference {
 	 * @see BundleWiring#getRevision()
 	 */
 	BundleWiring getWiring();
+
+	/**
+	 * Returns the capabilities declared by this resource.
+	 * 
+	 * <p>
+	 * This method returns the same value as
+	 * {@link #getDeclaredCapabilities(String)}.
+	 * 
+	 * @param namespace The namespace of the declared capabilities to return or
+	 *        {@code null} to return the declared capabilities from all
+	 *        namespaces.
+	 * @return An unmodifiable list containing the declared {@link Capability}s
+	 *         from the specified namespace. The returned list will be empty if
+	 *         this resource declares no capabilities in the specified
+	 *         namespace.
+	 * @since 1.1
+	 */
+	List<Capability> getCapabilities(String namespace);
+
+	/**
+	 * Returns the requirements declared by this bundle resource.
+	 * 
+	 * <p>
+	 * This method returns the same value as
+	 * {@link #getDeclaredRequirements(String)}.
+	 * 
+	 * @param namespace The namespace of the declared requirements to return or
+	 *        {@code null} to return the declared requirements from all
+	 *        namespaces.
+	 * @return An unmodifiable list containing the declared {@link Requirement}
+	 *         s from the specified namespace. The returned list will be empty
+	 *         if this resource declares no requirements in the specified
+	 *         namespace.
+	 * @since 1.1
+	 */
+	List<Requirement> getRequirements(String namespace);
 }
diff --git a/src/main/java/org/osgi/framework/wiring/BundleRevisions.java b/src/main/java/org/osgi/framework/wiring/BundleRevisions.java
index a619dbb..f0d03ff 100644
--- a/src/main/java/org/osgi/framework/wiring/BundleRevisions.java
+++ b/src/main/java/org/osgi/framework/wiring/BundleRevisions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
 package org.osgi.framework.wiring;
 
 import java.util.List;
-
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleReference;
 
@@ -38,7 +37,7 @@ import org.osgi.framework.BundleReference;
  * 
  * @ThreadSafe
  * @noimplement
- * @version $Id: 1d95ad10f0f08b100f8ee2485bdd34120032c7af $
+ * @version $Id: 8423242078417873faf0f8979e153e3c1f3a0e4b $
  */
 public interface BundleRevisions extends BundleReference {
 	/**
diff --git a/src/main/java/org/osgi/framework/wiring/BundleWire.java b/src/main/java/org/osgi/framework/wiring/BundleWire.java
index 1b19e4c..d14829a 100644
--- a/src/main/java/org/osgi/framework/wiring/BundleWire.java
+++ b/src/main/java/org/osgi/framework/wiring/BundleWire.java
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
- * 
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
@@ -16,14 +16,16 @@
 
 package org.osgi.framework.wiring;
 
+import org.osgi.resource.Wire;
+
 /**
  * A wire connecting a {@link BundleCapability} to a {@link BundleRequirement}.
  * 
  * @ThreadSafe
  * @noimplement
- * @version $Id: 4f936a84065762ec3267a44f86ae01b0150e44ce $
+ * @version $Id: 02e7cd6ec0fa9fdb73f782a6890984d5d4e7ca21 $
  */
-public interface BundleWire {
+public interface BundleWire extends Wire {
 	/**
 	 * Returns the {@link BundleCapability} for this wire.
 	 * 
@@ -44,7 +46,7 @@ public interface BundleWire {
 	 * 
 	 * <p>
 	 * The bundle revision referenced by the returned bundle wiring may differ
-	 * from the bundle revision reference by the {@link #getCapability()
+	 * from the bundle revision referenced by the {@link #getCapability()
 	 * capability}.
 	 * 
 	 * @return The bundle wiring providing the capability. If the bundle wiring
@@ -60,7 +62,7 @@ public interface BundleWire {
 	 * 
 	 * <p>
 	 * The bundle revision referenced by the returned bundle wiring may differ
-	 * from the bundle revision reference by the {@link #getRequirement()
+	 * from the bundle revision referenced by the {@link #getRequirement()
 	 * requirement}.
 	 * 
 	 * @return The bundle wiring whose requirement is wired to the capability.
@@ -69,4 +71,38 @@ public interface BundleWire {
 	 *         returned.
 	 */
 	BundleWiring getRequirerWiring();
+
+	/**
+	 * Returns the resource providing the {@link #getCapability() capability}.
+	 * 
+	 * <p>
+	 * The returned resource may differ from the resource referenced by the
+	 * {@link #getCapability() capability}.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getProviderWiring()}.
+	 * {@link BundleWiring#getRevision() getRevision()}.
+	 * 
+	 * @return The resource providing the capability.
+	 * @since 1.1
+	 */
+	BundleRevision getProvider();
+
+	/**
+	 * Returns the resource who {@link #getRequirement() requires} the
+	 * {@link #getCapability() capability}.
+	 * 
+	 * <p>
+	 * The returned resource may differ from the resource referenced by the
+	 * {@link #getRequirement() requirement}.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getRequirerWiring()}.
+	 * {@link BundleWiring#getRevision() getRevision()}.
+	 * 
+	 * @return The resource who requires the capability.
+	 * @since 1.1
+	 */
+	BundleRevision getRequirer();
+
 }
diff --git a/src/main/java/org/osgi/framework/wiring/BundleWiring.java b/src/main/java/org/osgi/framework/wiring/BundleWiring.java
index 8d8956a..b234c38 100644
--- a/src/main/java/org/osgi/framework/wiring/BundleWiring.java
+++ b/src/main/java/org/osgi/framework/wiring/BundleWiring.java
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
- * 
+ * Copyright (c) OSGi Alliance (2010, 2012). All Rights Reserved.
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
@@ -19,9 +19,15 @@ package org.osgi.framework.wiring;
 import java.net.URL;
 import java.util.Collection;
 import java.util.List;
-
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleReference;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Namespace;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Wire;
+import org.osgi.resource.Wiring;
 
 /**
  * A wiring for a bundle. Each time a bundle is resolved, a new bundle wiring
@@ -47,9 +53,9 @@ import org.osgi.framework.BundleReference;
  * 
  * @ThreadSafe
  * @noimplement
- * @version $Id: 58b8ec3bb9649387d4ccba1070f034f217d06ea2 $
+ * @version $Id: a3b3fd7ad7d289a5bfc6e4e02c875bc42a34df89 $
  */
-public interface BundleWiring extends BundleReference {
+public interface BundleWiring extends BundleReference, Wiring {
 	/**
 	 * Returns {@code true} if this bundle wiring is the current bundle wiring.
 	 * The bundle wiring for a bundle is the current bundle wiring if it is the
@@ -77,27 +83,41 @@ public interface BundleWiring extends BundleReference {
 	 * Returns the capabilities provided by this bundle wiring.
 	 * 
 	 * <p>
+	 * Only capabilities considered by the resolver are returned. For example,
+	 * capabilities with {@link Namespace#CAPABILITY_EFFECTIVE_DIRECTIVE
+	 * effective} directive not equal to {@link Namespace#EFFECTIVE_RESOLVE
+	 * resolve} are not returned.
+	 * 
+	 * <p>
 	 * A capability may not be required by any bundle wiring and thus there may
 	 * be no {@link #getProvidedWires(String) wires} for the capability.
 	 * 
 	 * <p>
 	 * A bundle wiring for a non-fragment revision provides a subset of the
 	 * declared capabilities from the bundle revision and all attached fragment
-	 * revisions. Not all declared capabilities may be provided since some may
-	 * be discarded. For example, if a package is declared to be exported and
-	 * import, only one is selected and the other is discarded.
+	 * revisions<sup>†</sup>. Not all declared capabilities may be
+	 * provided since some may be discarded. For example, if a package is
+	 * declared to be both exported and imported, only one is selected and the
+	 * other is discarded.
+	 * <p>
+	 * A bundle wiring for a fragment revision with a symbolic name must provide
+	 * exactly one {@link IdentityNamespace identity} capability.
+	 * <p>
+	 * † The {@link IdentityNamespace identity} capability provided by
+	 * attached fragment revisions must not be included in the capabilities of
+	 * the host bundle wiring.
 	 * 
-	 * @param namespace The name space of the capabilities to return or
-	 *        {@code null} to return the capabilities from all name spaces.
+	 * @param namespace The namespace of the capabilities to return or
+	 *        {@code null} to return the capabilities from all namespaces.
 	 * @return A list containing a snapshot of the {@link BundleCapability}s, or
 	 *         an empty list if this bundle wiring provides no capabilities in
-	 *         the specified name space. If this bundle wiring is not
+	 *         the specified namespace. If this bundle wiring is not
 	 *         {@link #isInUse() in use}, {@code null} will be returned. For a
-	 *         given name space, the list contains the wires in the order the
+	 *         given namespace, the list contains the wires in the order the
 	 *         capabilities were specified in the manifests of the
-	 *         {@link #getRevision() bundle revision} and the attached fragments
-	 *         of this bundle wiring. There is no ordering defined between
-	 *         capabilities in different name spaces.
+	 *         {@link #getRevision() bundle revision} and the attached
+	 *         fragments<sup>†</sup> of this bundle wiring. There is no
+	 *         ordering defined between capabilities in different namespaces.
 	 */
 	List<BundleCapability> getCapabilities(String namespace);
 
@@ -105,23 +125,29 @@ public interface BundleWiring extends BundleReference {
 	 * Returns the requirements of this bundle wiring.
 	 * 
 	 * <p>
+	 * Only requirements considered by the resolver are returned. For example,
+	 * requirements with {@link Namespace#REQUIREMENT_EFFECTIVE_DIRECTIVE
+	 * effective} directive not equal to {@link Namespace#EFFECTIVE_RESOLVE
+	 * resolve} are not returned.
+	 * 
+	 * <p>
 	 * A bundle wiring for a non-fragment revision has a subset of the declared
 	 * requirements from the bundle revision and all attached fragment
 	 * revisions. Not all declared requirements may be present since some may be
 	 * discarded. For example, if a package is declared to be optionally
 	 * imported and is not actually imported, the requirement must be discarded.
 	 * 
-	 * @param namespace The name space of the requirements to return or
-	 *        {@code null} to return the requirements from all name spaces.
+	 * @param namespace The namespace of the requirements to return or
+	 *        {@code null} to return the requirements from all namespaces.
 	 * @return A list containing a snapshot of the {@link BundleRequirement}s,
 	 *         or an empty list if this bundle wiring uses no requirements in
-	 *         the specified name space. If this bundle wiring is not
+	 *         the specified namespace. If this bundle wiring is not
 	 *         {@link #isInUse() in use}, {@code null} will be returned. For a
-	 *         given name space, the list contains the wires in the order the
+	 *         given namespace, the list contains the wires in the order the
 	 *         requirements were specified in the manifests of the
 	 *         {@link #getRevision() bundle revision} and the attached fragments
 	 *         of this bundle wiring. There is no ordering defined between
-	 *         requirements in different name spaces.
+	 *         requirements in different namespaces.
 	 */
 	List<BundleRequirement> getRequirements(String namespace);
 
@@ -129,19 +155,19 @@ public interface BundleWiring extends BundleReference {
 	 * Returns the {@link BundleWire}s to the provided {@link BundleCapability
 	 * capabilities} of this bundle wiring.
 	 * 
-	 * @param namespace The name space of the capabilities for which to return
+	 * @param namespace The namespace of the capabilities for which to return
 	 *        wires or {@code null} to return the wires for the capabilities in
-	 *        all name spaces.
+	 *        all namespaces.
 	 * @return A list containing a snapshot of the {@link BundleWire}s for the
 	 *         {@link BundleCapability capabilities} of this bundle wiring, or
 	 *         an empty list if this bundle wiring has no capabilities in the
-	 *         specified name space. If this bundle wiring is not
+	 *         specified namespace. If this bundle wiring is not
 	 *         {@link #isInUse() in use}, {@code null} will be returned. For a
-	 *         given name space, the list contains the wires in the order the
+	 *         given namespace, the list contains the wires in the order the
 	 *         capabilities were specified in the manifests of the
 	 *         {@link #getRevision() bundle revision} and the attached fragments
 	 *         of this bundle wiring. There is no ordering defined between
-	 *         capabilities in different name spaces.
+	 *         capabilities in different namespaces.
 	 */
 	List<BundleWire> getProvidedWires(String namespace);
 
@@ -154,19 +180,19 @@ public interface BundleWiring extends BundleReference {
 	 * to more requirements. For example, dynamically importing a package will
 	 * establish a new wire to the dynamically imported package.
 	 * 
-	 * @param namespace The name space of the requirements for which to return
+	 * @param namespace The namespace of the requirements for which to return
 	 *        wires or {@code null} to return the wires for the requirements in
-	 *        all name spaces.
+	 *        all namespaces.
 	 * @return A list containing a snapshot of the {@link BundleWire}s for the
 	 *         {@link BundleRequirement requirements} of this bundle wiring, or
 	 *         an empty list if this bundle wiring has no requirements in the
-	 *         specified name space. If this bundle wiring is not
+	 *         specified namespace. If this bundle wiring is not
 	 *         {@link #isInUse() in use}, {@code null} will be returned. For a
-	 *         given name space, the list contains the wires in the order the
+	 *         given namespace, the list contains the wires in the order the
 	 *         requirements were specified in the manifests of the
 	 *         {@link #getRevision() bundle revision} and the attached fragments
 	 *         of this bundle wiring. There is no ordering defined between
-	 *         requirements in different name spaces.
+	 *         requirements in different namespaces.
 	 */
 	List<BundleWire> getRequiredWires(String namespace);
 
@@ -210,7 +236,7 @@ public interface BundleWiring extends BundleReference {
 	 * <p>
 	 * This method takes into account that the "contents" of this
 	 * bundle wiring can have attached fragments. This "bundle space"
-	 * is not a name space with unique members; the same entry name can be
+	 * is not a namespace with unique members; the same entry name can be
 	 * present multiple times. This method therefore returns a list of URL
 	 * objects. These URLs can come from different JARs but have the same path
 	 * name. This method can either return only entries in the specified path or
@@ -218,6 +244,8 @@ public interface BundleWiring extends BundleReference {
 	 * beginning at the specified path.
 	 * 
 	 * <p>
+	 * URLs for directory entries must have their path end with "/".
+	 * <p>
 	 * Note: Jar and zip files are not required to include directory entries.
 	 * URLs to directory entries will not be returned if the bundle contents do
 	 * not contain directory entries.
@@ -303,8 +331,7 @@ public interface BundleWiring extends BundleReference {
 	 *         must contain no duplicate resource names. If this bundle wiring
 	 *         is not {@link #isInUse() in use}, {@code null} must be returned.
 	 */
-	Collection<String> listResources(String path, String filePattern,
-			int options);
+	Collection<String> listResources(String path, String filePattern, int options);
 
 	/**
 	 * The list resource names operation must recurse into subdirectories.
@@ -325,7 +352,7 @@ public interface BundleWiring extends BundleReference {
 	 * matching resources contained in this bundle wiring's
 	 * {@link #getRevision() bundle revision} and its attached fragment
 	 * revisions. The result must not include resource names for resources in
-	 * {@link BundleRevision#PACKAGE_NAMESPACE package} names which are
+	 * {@link PackageNamespace package} names which are
 	 * {@link #getRequiredWires(String) imported} by this wiring.
 	 * 
 	 * <p>
@@ -341,4 +368,135 @@ public interface BundleWiring extends BundleReference {
 	 * @see #listResources(String, String, int)
 	 */
 	int	LISTRESOURCES_LOCAL		= 0x00000002;
+
+	/**
+	 * Returns the capabilities provided by this wiring.
+	 * 
+	 * <p>
+	 * Only capabilities considered by the resolver are returned. For example,
+	 * capabilities with {@link Namespace#CAPABILITY_EFFECTIVE_DIRECTIVE
+	 * effective} directive not equal to {@link Namespace#EFFECTIVE_RESOLVE
+	 * resolve} are not returned.
+	 * 
+	 * <p>
+	 * A capability may not be required by any wiring and thus there may be no
+	 * {@link #getProvidedResourceWires(String) wires} for the capability.
+	 * 
+	 * <p>
+	 * A wiring for a non-fragment resource provides a subset of the declared
+	 * capabilities from the resource and all attached fragment
+	 * resources<sup>†</sup>. Not all declared capabilities may be
+	 * provided since some may be discarded. For example, if a package is
+	 * declared to be both exported and imported, only one is selected and the
+	 * other is discarded.
+	 * <p>
+	 * A wiring for a fragment resource with a symbolic name must provide
+	 * exactly one {@code osgi.identity} capability.
+	 * <p>
+	 * † The {@code osgi.identity} capability provided by attached
+	 * fragment resource must not be included in the capabilities of the host
+	 * wiring.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getCapabilities(String)}.
+	 * 
+	 * @param namespace The namespace of the capabilities to return or
+	 *        {@code null} to return the capabilities from all namespaces.
+	 * @return A list containing a snapshot of the {@link Capability}s, or an
+	 *         empty list if this wiring provides no capabilities in the
+	 *         specified namespace. For a given namespace, the list contains the
+	 *         wires in the order the capabilities were specified in the
+	 *         manifests of the {@link #getResource() resource} and the attached
+	 *         fragment resources<sup>†</sup> of this wiring. There is no
+	 *         ordering defined between capabilities in different namespaces.
+	 * @since 1.1
+	 */
+	List<Capability> getResourceCapabilities(String namespace);
+
+	/**
+	 * Returns the requirements of this wiring.
+	 * 
+	 * <p>
+	 * Only requirements considered by the resolver are returned. For example,
+	 * requirements with {@link Namespace#REQUIREMENT_EFFECTIVE_DIRECTIVE
+	 * effective} directive not equal to {@link Namespace#EFFECTIVE_RESOLVE
+	 * resolve} are not returned.
+	 * 
+	 * <p>
+	 * A wiring for a non-fragment resource has a subset of the declared
+	 * requirements from the resource and all attached fragment resources. Not
+	 * all declared requirements may be present since some may be discarded. For
+	 * example, if a package is declared to be optionally imported and is not
+	 * actually imported, the requirement must be discarded.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getRequirements(String)}.
+	 * 
+	 * @param namespace The namespace of the requirements to return or
+	 *        {@code null} to return the requirements from all namespaces.
+	 * @return A list containing a snapshot of the {@link Requirement}s, or an
+	 *         empty list if this wiring uses no requirements in the specified
+	 *         namespace. For a given namespace, the list contains the wires in
+	 *         the order the requirements were specified in the manifests of the
+	 *         {@link #getResource() resource} and the attached fragment
+	 *         resources of this wiring. There is no ordering defined between
+	 *         requirements in different namespaces.
+	 * @since 1.1
+	 */
+	List<Requirement> getResourceRequirements(String namespace);
+
+	/**
+	 * Returns the {@link Wire}s to the provided {@link Capability capabilities}
+	 * of this wiring.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getProvidedWires(String)}.
+	 * 
+	 * @param namespace The namespace of the capabilities for which to return
+	 *        wires or {@code null} to return the wires for the capabilities in
+	 *        all namespaces.
+	 * @return A list containing a snapshot of the {@link Wire}s for the
+	 *         {@link Capability capabilities} of this wiring, or an empty list
+	 *         if this wiring has no capabilities in the specified namespace.
+	 *         For a given namespace, the list contains the wires in the order
+	 *         the capabilities were specified in the manifests of the
+	 *         {@link #getResource() resource} and the attached fragment
+	 *         resources of this wiring. There is no ordering defined between
+	 *         capabilities in different namespaces.
+	 * @since 1.1
+	 */
+	List<Wire> getProvidedResourceWires(String namespace);
+
+	/**
+	 * Returns the {@link Wire}s to the {@link Requirement requirements} in use
+	 * by this wiring.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getRequiredWires(String)}.
+	 * 
+	 * @param namespace The namespace of the requirements for which to return
+	 *        wires or {@code null} to return the wires for the requirements in
+	 *        all namespaces.
+	 * @return A list containing a snapshot of the {@link Wire}s for the
+	 *         {@link Requirement requirements} of this wiring, or an empty list
+	 *         if this wiring has no requirements in the specified namespace.
+	 *         For a given namespace, the list contains the wires in the order
+	 *         the requirements were specified in the manifests of the
+	 *         {@link #getResource() resource} and the attached fragment
+	 *         resources of this wiring. There is no ordering defined between
+	 *         requirements in different namespaces.
+	 * @since 1.1
+	 */
+	List<Wire> getRequiredResourceWires(String namespace);
+
+	/**
+	 * Returns the resource associated with this wiring.
+	 * 
+	 * <p>
+	 * This method returns the same value as {@link #getRevision()}.
+	 * 
+	 * @return The resource associated with this wiring.
+	 * @since 1.1
+	 */
+	BundleRevision getResource();
 }
diff --git a/src/main/java/org/osgi/framework/wiring/FrameworkWiring.java b/src/main/java/org/osgi/framework/wiring/FrameworkWiring.java
index 046a6c2..ce9952c 100644
--- a/src/main/java/org/osgi/framework/wiring/FrameworkWiring.java
+++ b/src/main/java/org/osgi/framework/wiring/FrameworkWiring.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2001, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
 package org.osgi.framework.wiring;
 
 import java.util.Collection;
-
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleReference;
 import org.osgi.framework.FrameworkListener;
@@ -34,7 +33,7 @@ import org.osgi.framework.FrameworkListener;
  * 
  * @ThreadSafe
  * @noimplement
- * @version $Id: f9f3f89b5b8d369453d645a52a482a385a2bd520 $
+ * @version $Id: bff4cdf85c632e2946e18c1640a86e80c069dd37 $
  */
 public interface FrameworkWiring extends BundleReference {
 	/**
@@ -110,8 +109,7 @@ public interface FrameworkWiring extends BundleReference {
 	 *         {@code AdminPermission[System Bundle,RESOLVE]} and the Java
 	 *         runtime environment supports permissions.
 	 */
-	void refreshBundles(Collection<Bundle> bundles,
-			FrameworkListener... listeners);
+	void refreshBundles(Collection<Bundle> bundles, FrameworkListener... listeners);
 
 	/**
 	 * Resolves the specified bundles. The Framework must attempt to resolve the
diff --git a/src/main/java/org/osgi/resource/Capability.java b/src/main/java/org/osgi/resource/Capability.java
new file mode 100644
index 0000000..bda0ce6
--- /dev/null
+++ b/src/main/java/org/osgi/resource/Capability.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.resource;
+
+import java.util.Map;
+
+/**
+ * A capability that has been declared from a {@link Resource}.
+ * 
+ * <p>
+ * Instances of this type must be <i>effectively immutable</i>. That is, for a
+ * given instance of this interface, the methods defined by this interface must
+ * always return the same result.
+ * 
+ * @ThreadSafe
+ * @version $Id: 5f40514f7bf45f6dce59651e8812b0922580e77e $
+ */
+public interface Capability {
+
+	/**
+	 * Returns the namespace of this capability.
+	 * 
+	 * @return The namespace of this capability.
+	 */
+	String getNamespace();
+
+	/**
+	 * Returns the directives of this capability.
+	 * 
+	 * @return An unmodifiable map of directive names to directive values for
+	 *         this capability, or an empty map if this capability has no
+	 *         directives.
+	 */
+	Map<String, String> getDirectives();
+
+	/**
+	 * Returns the attributes of this capability.
+	 * 
+	 * @return An unmodifiable map of attribute names to attribute values for
+	 *         this capability, or an empty map if this capability has no
+	 *         attributes.
+	 */
+	Map<String, Object> getAttributes();
+
+	/**
+	 * Returns the resource declaring this capability.
+	 * 
+	 * @return The resource declaring this capability.
+	 */
+	Resource getResource();
+
+	/**
+	 * Compares this {@code Capability} to another {@code Capability}.
+	 * 
+	 * <p>
+	 * This {@code Capability} is equal to another {@code Capability} if they
+	 * have the same namespace, directives and attributes and are declared by
+	 * the same resource.
+	 * 
+	 * @param obj The object to compare against this {@code Capability}.
+	 * @return {@code true} if this {@code Capability} is equal to the other
+	 *         object; {@code false} otherwise.
+	 */
+	boolean equals(Object obj);
+
+	/**
+	 * Returns the hashCode of this {@code Capability}.
+	 * 
+	 * @return The hashCode of this {@code Capability}.
+	 */
+	int hashCode();
+}
diff --git a/src/main/java/org/osgi/resource/Namespace.java b/src/main/java/org/osgi/resource/Namespace.java
new file mode 100644
index 0000000..abda616
--- /dev/null
+++ b/src/main/java/org/osgi/resource/Namespace.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.resource;
+
+/**
+ * Capability and Requirement Namespaces base class.
+ * 
+ * <p>
+ * This class is the common class shared by all OSGi defined namespaces. It
+ * defines the names for the common attributes and directives for the OSGi
+ * specified namespaces.
+ * 
+ * <p>
+ * The OSGi Alliance reserves the right to extend the set of directives and
+ * attributes which have specified semantics for all of the specified
+ * namespaces.
+ * 
+ * <p>
+ * The values associated with these keys are of type {@code String}, unless
+ * otherwise indicated.
+ * 
+ * @Immutable
+ * @version $Id: 43c9ff5cea19546d71c4703db71a2b5070a3f2fa $
+ */
+public abstract class Namespace {
+
+	/**
+	 * The capability directive used to specify the comma separated list of
+	 * package names used by a capability.
+	 */
+	public final static String	CAPABILITY_USES_DIRECTIVE			= "uses";
+
+	/**
+	 * The capability directive used to specify the effective time for the
+	 * capability. The default value is {@link #EFFECTIVE_RESOLVE resolve}.
+	 * 
+	 * @see #EFFECTIVE_RESOLVE resolve
+	 * @see #EFFECTIVE_ACTIVE active
+	 */
+	public final static String	CAPABILITY_EFFECTIVE_DIRECTIVE		= "effective";
+
+	/**
+	 * The requirement directive used to specify a capability filter. This
+	 * filter is used to match against a capability's attributes.
+	 */
+	public final static String	REQUIREMENT_FILTER_DIRECTIVE		= "filter";
+
+	/**
+	 * The requirement directive used to specify the resolution type for a
+	 * requirement. The default value is {@link #RESOLUTION_MANDATORY mandatory}
+	 * .
+	 * 
+	 * @see #RESOLUTION_MANDATORY mandatory
+	 * @see #RESOLUTION_OPTIONAL optional
+	 */
+	public final static String	REQUIREMENT_RESOLUTION_DIRECTIVE	= "resolution";
+
+	/**
+	 * The directive value identifying a mandatory requirement resolution type.
+	 * A mandatory resolution type indicates that the requirement must be
+	 * resolved when the resource is resolved. If such a requirement cannot be
+	 * resolved, the resource fails to resolve.
+	 * 
+	 * @see #REQUIREMENT_RESOLUTION_DIRECTIVE
+	 */
+	public final static String	RESOLUTION_MANDATORY				= "mandatory";
+
+	/**
+	 * The directive value identifying an optional requirement resolution type.
+	 * An optional resolution type indicates that the requirement is optional
+	 * and the resource may be resolved without the requirement being resolved.
+	 * 
+	 * @see #REQUIREMENT_RESOLUTION_DIRECTIVE
+	 */
+	public final static String	RESOLUTION_OPTIONAL					= "optional";
+
+	/**
+	 * The requirement directive used to specify the effective time for the
+	 * requirement. The default value is {@link #EFFECTIVE_RESOLVE resolve}.
+	 * 
+	 * @see #EFFECTIVE_RESOLVE resolve
+	 * @see #EFFECTIVE_ACTIVE active
+	 */
+	public final static String	REQUIREMENT_EFFECTIVE_DIRECTIVE		= "effective";
+
+	/**
+	 * The directive value identifying a {@link #CAPABILITY_EFFECTIVE_DIRECTIVE
+	 * capability} or {@link #REQUIREMENT_EFFECTIVE_DIRECTIVE requirement} that
+	 * is effective at resolve time. Capabilities and requirements with an
+	 * effective time of resolve are the only capabilities which are processed
+	 * while resolving a resource.
+	 * 
+	 * @see #REQUIREMENT_EFFECTIVE_DIRECTIVE
+	 * @see #CAPABILITY_EFFECTIVE_DIRECTIVE
+	 */
+	public final static String	EFFECTIVE_RESOLVE					= "resolve";
+
+	/**
+	 * The directive value identifying a {@link #CAPABILITY_EFFECTIVE_DIRECTIVE
+	 * capability} or {@link #REQUIREMENT_EFFECTIVE_DIRECTIVE requirement} that
+	 * is effective at active time. Capabilities and requirements with an
+	 * effective time of active are ignored while resolving a resource.
+	 * 
+	 * @see #REQUIREMENT_EFFECTIVE_DIRECTIVE
+	 * @see #CAPABILITY_EFFECTIVE_DIRECTIVE
+	 */
+	public final static String	EFFECTIVE_ACTIVE					= "active";
+
+	/**
+	 * The requirement directive used to specify the cardinality for a
+	 * requirement. The default value is {@link #CARDINALITY_SINGLE single}.
+	 * 
+	 * @see #CARDINALITY_MULTIPLE multiple
+	 * @see #CARDINALITY_SINGLE single
+	 */
+	public final static String	REQUIREMENT_CARDINALITY_DIRECTIVE	= "cardinality";
+
+	/**
+	 * The directive value identifying a multiple
+	 * {@link #REQUIREMENT_CARDINALITY_DIRECTIVE cardinality} type.
+	 * 
+	 * @see #REQUIREMENT_CARDINALITY_DIRECTIVE
+	 */
+	public final static String	CARDINALITY_MULTIPLE				= "multiple";
+
+	/**
+	 * The directive value identifying a
+	 * {@link #REQUIREMENT_CARDINALITY_DIRECTIVE cardinality} type of single.
+	 * 
+	 * @see #REQUIREMENT_CARDINALITY_DIRECTIVE
+	 */
+	public final static String	CARDINALITY_SINGLE					= "single";
+
+	/**
+	 * Protected constructor for Namespace sub-types.
+	 */
+	protected Namespace() {
+		// empty
+	}
+}
diff --git a/src/main/java/org/osgi/resource/Requirement.java b/src/main/java/org/osgi/resource/Requirement.java
new file mode 100644
index 0000000..cf931bf
--- /dev/null
+++ b/src/main/java/org/osgi/resource/Requirement.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.resource;
+
+import java.util.Map;
+
+/**
+ * A requirement that has been declared from a {@link Resource} .
+ * 
+ * <p>
+ * Instances of this type must be <i>effectively immutable</i>. That is, for a
+ * given instance of this interface, the methods defined by this interface must
+ * always return the same result.
+ * 
+ * @ThreadSafe
+ * @version $Id: 212b26179910f98fd2c59c3e1e7dd0d086f42b5d $
+ */
+public interface Requirement {
+	/**
+	 * Returns the namespace of this requirement.
+	 * 
+	 * @return The namespace of this requirement.
+	 */
+	String getNamespace();
+
+	/**
+	 * Returns the directives of this requirement.
+	 * 
+	 * @return An unmodifiable map of directive names to directive values for
+	 *         this requirement, or an empty map if this requirement has no
+	 *         directives.
+	 */
+	Map<String, String> getDirectives();
+
+	/**
+	 * Returns the attributes of this requirement.
+	 * 
+	 * <p>
+	 * Requirement attributes have no specified semantics and are considered
+	 * extra user defined information.
+	 * 
+	 * @return An unmodifiable map of attribute names to attribute values for
+	 *         this requirement, or an empty map if this requirement has no
+	 *         attributes.
+	 */
+	Map<String, Object> getAttributes();
+
+	/**
+	 * Returns the resource declaring this requirement.
+	 * 
+	 * @return The resource declaring this requirement. This can be {@code null}
+	 *         if this requirement is synthesized.
+	 */
+	Resource getResource();
+
+	/**
+	 * Compares this {@code Requirement} to another {@code Requirement}.
+	 * 
+	 * <p>
+	 * This {@code Requirement} is equal to another {@code Requirement} if they
+	 * have the same namespace, directives and attributes and are declared by
+	 * the same resource.
+	 * 
+	 * @param obj The object to compare against this {@code Requirement}.
+	 * @return {@code true} if this {@code Requirement} is equal to the other
+	 *         object; {@code false} otherwise.
+	 */
+	boolean equals(Object obj);
+
+	/**
+	 * Returns the hashCode of this {@code Requirement}.
+	 * 
+	 * @return The hashCode of this {@code Requirement}.
+	 */
+	int hashCode();
+}
diff --git a/src/main/java/org/osgi/resource/Resource.java b/src/main/java/org/osgi/resource/Resource.java
new file mode 100644
index 0000000..455d891
--- /dev/null
+++ b/src/main/java/org/osgi/resource/Resource.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.resource;
+
+import java.util.List;
+
+/**
+ * A resource is the representation of a uniquely identified and typed data. A
+ * resource declares requirements that need to be satisfied by capabilities
+ * before it can provide its capabilities.
+ * 
+ * <p>
+ * Instances of this type must be <i>effectively immutable</i>. That is, for a
+ * given instance of this interface, the methods defined by this interface must
+ * always return the same result.
+ * 
+ * @ThreadSafe
+ * @version $Id: 40958d5777ee269d27d58e9f646a4c91bcc6daa4 $
+ */
+public interface Resource {
+	/**
+	 * Returns the capabilities declared by this resource.
+	 * 
+	 * @param namespace The namespace of the declared capabilities to return or
+	 *        {@code null} to return the declared capabilities from all
+	 *        namespaces.
+	 * @return An unmodifiable list containing the declared {@link Capability}s
+	 *         from the specified namespace. The returned list will be empty if
+	 *         this resource declares no capabilities in the specified
+	 *         namespace.
+	 */
+	List<Capability> getCapabilities(String namespace);
+
+	/**
+	 * Returns the requirements declared by this bundle resource.
+	 * 
+	 * @param namespace The namespace of the declared requirements to return or
+	 *        {@code null} to return the declared requirements from all
+	 *        namespaces.
+	 * @return An unmodifiable list containing the declared {@link Requirement}
+	 *         s from the specified namespace. The returned list will be empty
+	 *         if this resource declares no requirements in the specified
+	 *         namespace.
+	 */
+	List<Requirement> getRequirements(String namespace);
+
+	/**
+	 * Compares this {@code Resource} to another {@code Resource}.
+	 * 
+	 * <p>
+	 * This {@code Resource} is equal to another {@code Resource} if both have
+	 * the same content and come from the same location. Location may be defined
+	 * as the bundle location if the resource is an installed bundle or the
+	 * repository location if the resource is in a repository.
+	 * 
+	 * @param obj The object to compare against this {@code Resource}.
+	 * @return {@code true} if this {@code Resource} is equal to the other
+	 *         object; {@code false} otherwise.
+	 */
+	boolean equals(Object obj);
+
+	/**
+	 * Returns the hashCode of this {@code Resource}.
+	 * 
+	 * @return The hashCode of this {@code Resource}.
+	 */
+	int hashCode();
+}
diff --git a/src/main/java/org/osgi/resource/Wire.java b/src/main/java/org/osgi/resource/Wire.java
new file mode 100644
index 0000000..18feab8
--- /dev/null
+++ b/src/main/java/org/osgi/resource/Wire.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.resource;
+
+/**
+ * A wire connecting a {@link Capability} to a {@link Requirement}.
+ * 
+ * <p>
+ * Instances of this type must be <i>effectively immutable</i>. That is, for a
+ * given instance of this interface, the methods defined by this interface must
+ * always return the same result.
+ * 
+ * @ThreadSafe
+ * @version $Id: d7ca9a5d3e8dd2277f8243a750e40fbcf79185bd $
+ */
+public interface Wire {
+	/**
+	 * Returns the {@link Capability} for this wire.
+	 * 
+	 * @return The {@link Capability} for this wire.
+	 */
+	Capability getCapability();
+
+	/**
+	 * Returns the {@link Requirement} for this wire.
+	 * 
+	 * @return The {@link Requirement} for this wire.
+	 */
+	Requirement getRequirement();
+
+	/**
+	 * Returns the resource providing the {@link #getCapability() capability}.
+	 * 
+	 * <p>
+	 * The returned resource may differ from the resource referenced by the
+	 * {@link #getCapability() capability}.
+	 * 
+	 * @return The resource providing the capability.
+	 */
+	Resource getProvider();
+
+	/**
+	 * Returns the resource who {@link #getRequirement() requires} the
+	 * {@link #getCapability() capability}.
+	 * 
+	 * <p>
+	 * The returned resource may differ from the resource referenced by the
+	 * {@link #getRequirement() requirement}.
+	 * 
+	 * @return The resource who requires the capability.
+	 */
+	Resource getRequirer();
+
+	/**
+	 * Compares this {@code Wire} to another {@code Wire}.
+	 * 
+	 * <p>
+	 * This {@code Wire} is equal to another {@code Wire} if they have the same
+	 * capability, requirement, provider and requirer.
+	 * 
+	 * @param obj The object to compare against this {@code Wire}.
+	 * @return {@code true} if this {@code Wire} is equal to the other object;
+	 *         {@code false} otherwise.
+	 */
+	boolean equals(Object obj);
+
+	/**
+	 * Returns the hashCode of this {@code Wire}.
+	 * 
+	 * @return The hashCode of this {@code Wire}.
+	 */
+	int hashCode();
+}
diff --git a/src/main/java/org/osgi/resource/Wiring.java b/src/main/java/org/osgi/resource/Wiring.java
new file mode 100644
index 0000000..230fef0
--- /dev/null
+++ b/src/main/java/org/osgi/resource/Wiring.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) OSGi Alliance (2011, 2012). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.resource;
+
+import java.util.List;
+
+/**
+ * A wiring for a resource. A wiring is associated with a resource and
+ * represents the dependencies with other wirings.
+ * 
+ * <p>
+ * Instances of this type must be <i>effectively immutable</i>. That is, for a
+ * given instance of this interface, the methods defined by this interface must
+ * always return the same result.
+ * 
+ * @ThreadSafe
+ * @version $Id: b65dec3887cfa1d5731e860db558a01503c0f47d $
+ */
+public interface Wiring {
+	/**
+	 * Returns the capabilities provided by this wiring.
+	 * 
+	 * <p>
+	 * Only capabilities considered by the resolver are returned. For example,
+	 * capabilities with {@link Namespace#CAPABILITY_EFFECTIVE_DIRECTIVE
+	 * effective} directive not equal to {@link Namespace#EFFECTIVE_RESOLVE
+	 * resolve} are not returned.
+	 * 
+	 * <p>
+	 * A capability may not be required by any wiring and thus there may be no
+	 * {@link #getProvidedResourceWires(String) wires} for the capability.
+	 * 
+	 * <p>
+	 * A wiring for a non-fragment resource provides a subset of the declared
+	 * capabilities from the resource and all attached fragment
+	 * resources<sup>†</sup>. Not all declared capabilities may be
+	 * provided since some may be discarded. For example, if a package is
+	 * declared to be both exported and imported, only one is selected and the
+	 * other is discarded.
+	 * <p>
+	 * A wiring for a fragment resource with a symbolic name must provide
+	 * exactly one {@code osgi.identity} capability.
+	 * <p>
+	 * † The {@code osgi.identity} capability provided by attached
+	 * fragment resource must not be included in the capabilities of the host
+	 * wiring.
+	 * 
+	 * @param namespace The namespace of the capabilities to return or
+	 *        {@code null} to return the capabilities from all namespaces.
+	 * @return A list containing a snapshot of the {@link Capability}s, or an
+	 *         empty list if this wiring provides no capabilities in the
+	 *         specified namespace. For a given namespace, the list contains the
+	 *         wires in the order the capabilities were specified in the
+	 *         manifests of the {@link #getResource() resource} and the attached
+	 *         fragment resources<sup>†</sup> of this wiring. There is no
+	 *         ordering defined between capabilities in different namespaces.
+	 */
+	List<Capability> getResourceCapabilities(String namespace);
+
+	/**
+	 * Returns the requirements of this wiring.
+	 * 
+	 * <p>
+	 * Only requirements considered by the resolver are returned. For example,
+	 * requirements with {@link Namespace#REQUIREMENT_EFFECTIVE_DIRECTIVE
+	 * effective} directive not equal to {@link Namespace#EFFECTIVE_RESOLVE
+	 * resolve} are not returned.
+	 * 
+	 * <p>
+	 * A wiring for a non-fragment resource has a subset of the declared
+	 * requirements from the resource and all attached fragment resources. Not
+	 * all declared requirements may be present since some may be discarded. For
+	 * example, if a package is declared to be optionally imported and is not
+	 * actually imported, the requirement must be discarded.
+	 * 
+	 * @param namespace The namespace of the requirements to return or
+	 *        {@code null} to return the requirements from all namespaces.
+	 * @return A list containing a snapshot of the {@link Requirement}s, or an
+	 *         empty list if this wiring uses no requirements in the specified
+	 *         namespace. For a given namespace, the list contains the wires in
+	 *         the order the requirements were specified in the manifests of the
+	 *         {@link #getResource() resource} and the attached fragment
+	 *         resources of this wiring. There is no ordering defined between
+	 *         requirements in different namespaces.
+	 */
+	List<Requirement> getResourceRequirements(String namespace);
+
+	/**
+	 * Returns the {@link Wire}s to the provided {@link Capability capabilities}
+	 * of this wiring.
+	 * 
+	 * @param namespace The namespace of the capabilities for which to return
+	 *        wires or {@code null} to return the wires for the capabilities in
+	 *        all namespaces.
+	 * @return A list containing a snapshot of the {@link Wire}s for the
+	 *         {@link Capability capabilities} of this wiring, or an empty list
+	 *         if this wiring has no capabilities in the specified namespace.
+	 *         For a given namespace, the list contains the wires in the order
+	 *         the capabilities were specified in the manifests of the
+	 *         {@link #getResource() resource} and the attached fragment
+	 *         resources of this wiring. There is no ordering defined between
+	 *         capabilities in different namespaces.
+	 */
+	List<Wire> getProvidedResourceWires(String namespace);
+
+	/**
+	 * Returns the {@link Wire}s to the {@link Requirement requirements} in use
+	 * by this wiring.
+	 * 
+	 * @param namespace The namespace of the requirements for which to return
+	 *        wires or {@code null} to return the wires for the requirements in
+	 *        all namespaces.
+	 * @return A list containing a snapshot of the {@link Wire}s for the
+	 *         {@link Requirement requirements} of this wiring, or an empty list
+	 *         if this wiring has no requirements in the specified namespace.
+	 *         For a given namespace, the list contains the wires in the order
+	 *         the requirements were specified in the manifests of the
+	 *         {@link #getResource() resource} and the attached fragment
+	 *         resources of this wiring. There is no ordering defined between
+	 *         requirements in different namespaces.
+	 */
+	List<Wire> getRequiredResourceWires(String namespace);
+
+	/**
+	 * Returns the resource associated with this wiring.
+	 * 
+	 * @return The resource associated with this wiring.
+	 */
+	Resource getResource();
+}
diff --git a/src/main/java/org/osgi/service/packageadmin/ExportedPackage.java b/src/main/java/org/osgi/service/packageadmin/ExportedPackage.java
index abe1515..4dd3a3a 100644
--- a/src/main/java/org/osgi/service/packageadmin/ExportedPackage.java
+++ b/src/main/java/org/osgi/service/packageadmin/ExportedPackage.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2001, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2011). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -45,7 +45,7 @@ import org.osgi.framework.Version;
  * @noimplement
  * @deprecated The PackageAdmin service has been replaced by the
  *             <code>org.osgi.framework.wiring</code> package.
- * @version $Id: c56b99465e3f62a9808297a47de8cb7edb802119 $
+ * @version $Id: 22ce5e8e388107b04edba3aea2f3036b8026798d $
  */
 public interface ExportedPackage {
 	/**
@@ -83,9 +83,9 @@ public interface ExportedPackage {
 	/**
 	 * Returns the version of this exported package.
 	 * 
-	 * @return The version of this exported package, or {@code null} if
-	 *         no version information is available.
-	 * @deprecated As of 1.2, replaced by {@link #getVersion}.
+	 * @return The version of this exported package, or {@code null} if no
+	 *         version information is available.
+	 * @deprecated As of 1.2, replaced by {@link #getVersion()}.
 	 */
 	public String getSpecificationVersion();
 
diff --git a/src/main/java/org/osgi/service/startlevel/StartLevel.java b/src/main/java/org/osgi/service/startlevel/StartLevel.java
index 5efb41c..b4b8816 100644
--- a/src/main/java/org/osgi/service/startlevel/StartLevel.java
+++ b/src/main/java/org/osgi/service/startlevel/StartLevel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2002, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2011). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -68,7 +68,7 @@ import org.osgi.framework.Bundle;
  * 
  * @ThreadSafe
  * @noimplement
- * @version $Id: bf1b71ed6c9f9d75785b26dccb34362017d93f4a $
+ * @version $Id: ec0295bdf246c0258261374b3ac0e4aef11f7315 $
  * @deprecated This service has been replaced by the
  *             <code>org.osgi.framework.startlevel</code> package.
  */
@@ -202,7 +202,7 @@ public interface StartLevel {
 	 * is first installed.
 	 * 
 	 * @return The initial start level value for Bundles.
-	 * @see #setInitialBundleStartLevel
+	 * @see #setInitialBundleStartLevel(int)
 	 */
 	public int getInitialBundleStartLevel();
 
diff --git a/src/main/java/org/osgi/service/url/AbstractURLStreamHandlerService.java b/src/main/java/org/osgi/service/url/AbstractURLStreamHandlerService.java
index c20a051..679583c 100644
--- a/src/main/java/org/osgi/service/url/AbstractURLStreamHandlerService.java
+++ b/src/main/java/org/osgi/service/url/AbstractURLStreamHandlerService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2002, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,43 +19,38 @@ package org.osgi.service.url;
 import java.net.*;
 
 /**
- * Abstract implementation of the {@code URLStreamHandlerService}
- * interface. All the methods simply invoke the corresponding methods on
- * {@code java.net.URLStreamHandler} except for {@code parseURL}
- * and {@code setURL}, which use the {@code URLStreamHandlerSetter}
- * parameter. Subclasses of this abstract class should not need to override the
- * {@code setURL} and {@code parseURL(URLStreamHandlerSetter,...)}
- * methods.
+ * Abstract implementation of the {@code URLStreamHandlerService} interface. All
+ * the methods simply invoke the corresponding methods on
+ * {@code java.net.URLStreamHandler} except for {@code parseURL} and
+ * {@code setURL}, which use the {@code URLStreamHandlerSetter} parameter.
+ * Subclasses of this abstract class should not need to override the
+ * {@code setURL} and {@code parseURL(URLStreamHandlerSetter,...)} methods.
  * 
  * @ThreadSafe
- * @version $Id: 465a0ed86f5d49b338ffc6a13bb68f60f04e54d6 $
+ * @version $Id: b86572a4f13b7bb4a343ac4d6b6fb3487e01bd31 $
  */
-public abstract class AbstractURLStreamHandlerService extends URLStreamHandler
-		implements URLStreamHandlerService {
+public abstract class AbstractURLStreamHandlerService extends URLStreamHandler implements URLStreamHandlerService {
 	/**
 	 * @see "java.net.URLStreamHandler.openConnection"
 	 */
-	public abstract URLConnection openConnection(URL u)
-			throws java.io.IOException;
+	public abstract URLConnection openConnection(URL u) throws java.io.IOException;
 
 	/**
-	 * The {@code URLStreamHandlerSetter} object passed to the parseURL
-	 * method.
+	 * The {@code URLStreamHandlerSetter} object passed to the parseURL method.
 	 */
 	protected volatile URLStreamHandlerSetter	realHandler;
 
 	/**
-	 * Parse a URL using the {@code URLStreamHandlerSetter} object. This
-	 * method sets the {@code realHandler} field with the specified
+	 * Parse a URL using the {@code URLStreamHandlerSetter} object. This method
+	 * sets the {@code realHandler} field with the specified
 	 * {@code URLStreamHandlerSetter} object and then calls
 	 * {@code parseURL(URL,String,int,int)}.
 	 * 
-	 * @param realHandler The object on which the {@code setURL} method
-	 *        must be invoked for the specified URL.
+	 * @param realHandler The object on which the {@code setURL} method must be
+	 *        invoked for the specified URL.
 	 * @see "java.net.URLStreamHandler.parseURL"
 	 */
-	public void parseURL(URLStreamHandlerSetter realHandler, URL u,
-			String spec, int start, int limit) {
+	public void parseURL(URLStreamHandlerSetter realHandler, URL u, String spec, int start, int limit) {
 		this.realHandler = realHandler;
 		parseURL(u, spec, start, limit);
 	}
@@ -131,19 +126,18 @@ public abstract class AbstractURLStreamHandlerService extends URLStreamHandler
 	 * @deprecated This method is only for compatibility with handlers written
 	 *             for JDK 1.1.
 	 */
-	protected void setURL(URL u, String proto, String host, int port,
-			String file, String ref) {
+	protected void setURL(URL u, String proto, String host, int port, String file, String ref) {
 		realHandler.setURL(u, proto, host, port, file, ref);
 	}
 
 	/**
 	 * This method calls
-	 * {@code realHandler.setURL(URL,String,String,int,String,String,String,String)}.
+	 * {@code realHandler.setURL(URL,String,String,int,String,String,String,String)}
+	 * .
 	 * 
 	 * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String,String,String)"
 	 */
-	protected void setURL(URL u, String proto, String host, int port,
-			String auth, String user, String path, String query, String ref) {
+	protected void setURL(URL u, String proto, String host, int port, String auth, String user, String path, String query, String ref) {
 		realHandler.setURL(u, proto, host, port, auth, user, path, query, ref);
 	}
 }
diff --git a/src/main/java/org/osgi/service/url/URLConstants.java b/src/main/java/org/osgi/service/url/URLConstants.java
index fbf768b..493f352 100644
--- a/src/main/java/org/osgi/service/url/URLConstants.java
+++ b/src/main/java/org/osgi/service/url/URLConstants.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2002, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,16 +18,14 @@ package org.osgi.service.url;
 
 /**
  * Defines standard names for property keys associated with
- * {@link URLStreamHandlerService} and {@code java.net.ContentHandler}
- * services.
+ * {@link URLStreamHandlerService} and {@code java.net.ContentHandler} services.
  * 
  * <p>
- * The values associated with these keys are of type
- * {@code java.lang.String[]} or {@code java.lang.String}, unless
- * otherwise indicated.
+ * The values associated with these keys are of type {@code java.lang.String[]}
+ * or {@code java.lang.String}, unless otherwise indicated.
  * 
  * @noimplement
- * @version $Id: 5ec8db316249f4b956fe083b986c11153d0fa8fe $
+ * @version $Id: ac2b9670972d6e41d989c51067219ff7be459831 $
  */
 public interface URLConstants {
 	/**
diff --git a/src/main/java/org/osgi/service/url/URLStreamHandlerService.java b/src/main/java/org/osgi/service/url/URLStreamHandlerService.java
index 7cc5d6e..e6dd098 100644
--- a/src/main/java/org/osgi/service/url/URLStreamHandlerService.java
+++ b/src/main/java/org/osgi/service/url/URLStreamHandlerService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2002, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,19 +23,17 @@ import java.net.*;
  * {@code java.net.URLStreamHandler} methods.
  * <p>
  * The important differences between this interface and the
- * {@code URLStreamHandler} class are that the {@code setURL}
- * method is absent and the {@code parseURL} method takes a
- * {@link URLStreamHandlerSetter} object as the first argument. Classes
- * implementing this interface must call the {@code setURL} method on the
- * {@code URLStreamHandlerSetter} object received in the
- * {@code parseURL} method instead of
- * {@code URLStreamHandler.setURL} to avoid a
- * {@code SecurityException}.
+ * {@code URLStreamHandler} class are that the {@code setURL} method is absent
+ * and the {@code parseURL} method takes a {@link URLStreamHandlerSetter} object
+ * as the first argument. Classes implementing this interface must call the
+ * {@code setURL} method on the {@code URLStreamHandlerSetter} object received
+ * in the {@code parseURL} method instead of {@code URLStreamHandler.setURL} to
+ * avoid a {@code SecurityException}.
  * 
  * @see AbstractURLStreamHandlerService
  * 
  * @ThreadSafe
- * @version $Id: 4982ef5b407669975afe2856a9702246d2d9c2ba $
+ * @version $Id: 4a453f61b9acdc6449df389b2a0538d0ccb33ed2 $
  */
 public interface URLStreamHandlerService {
 	/**
@@ -44,16 +42,15 @@ public interface URLStreamHandlerService {
 	public URLConnection openConnection(URL u) throws java.io.IOException;
 
 	/**
-	 * Parse a URL. This method is called by the {@code URLStreamHandler}
-	 * proxy, instead of {@code java.net.URLStreamHandler.parseURL},
-	 * passing a {@code URLStreamHandlerSetter} object.
+	 * Parse a URL. This method is called by the {@code URLStreamHandler} proxy,
+	 * instead of {@code java.net.URLStreamHandler.parseURL}, passing a
+	 * {@code URLStreamHandlerSetter} object.
 	 * 
-	 * @param realHandler The object on which {@code setURL} must be
-	 *        invoked for this URL.
+	 * @param realHandler The object on which {@code setURL} must be invoked for
+	 *        this URL.
 	 * @see "java.net.URLStreamHandler.parseURL"
 	 */
-	public void parseURL(URLStreamHandlerSetter realHandler, URL u,
-			String spec, int start, int limit);
+	public void parseURL(URLStreamHandlerSetter realHandler, URL u, String spec, int start, int limit);
 
 	/**
 	 * @see "java.net.URLStreamHandler.toExternalForm"
diff --git a/src/main/java/org/osgi/service/url/URLStreamHandlerSetter.java b/src/main/java/org/osgi/service/url/URLStreamHandlerSetter.java
index dd2e0c2..90feae6 100644
--- a/src/main/java/org/osgi/service/url/URLStreamHandlerSetter.java
+++ b/src/main/java/org/osgi/service/url/URLStreamHandlerSetter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2002, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,19 +20,18 @@ import java.net.URL;
 
 /**
  * Interface used by {@code URLStreamHandlerService} objects to call the
- * {@code setURL} method on the proxy {@code URLStreamHandler}
- * object.
+ * {@code setURL} method on the proxy {@code URLStreamHandler} object.
  * 
  * <p>
  * Objects of this type are passed to the
- * {@link URLStreamHandlerService#parseURL} method. Invoking the
- * {@code setURL} method on the {@code URLStreamHandlerSetter}
- * object will invoke the {@code setURL} method on the proxy
- * {@code URLStreamHandler} object that is actually registered with
+ * {@link URLStreamHandlerService#parseURL(URLStreamHandlerSetter, URL, String, int, int)}
+ * method. Invoking the {@code setURL} method on the
+ * {@code URLStreamHandlerSetter} object will invoke the {@code setURL} method
+ * on the proxy {@code URLStreamHandler} object that is actually registered with
  * {@code java.net.URL} for the protocol.
  * 
  * @ThreadSafe
- * @version $Id: f55d4c29678503c244f56dcb2b5621b3be11cc8d $
+ * @version $Id: 90f25e3961fea2150cfd31117a2237304f1518f9 $
  */
 public interface URLStreamHandlerSetter {
 	/**
@@ -41,13 +40,10 @@ public interface URLStreamHandlerSetter {
 	 * @deprecated This method is only for compatibility with handlers written
 	 *             for JDK 1.1.
 	 */
-	public void setURL(URL u, String protocol, String host, int port,
-			String file, String ref);
+	public void setURL(URL u, String protocol, String host, int port, String file, String ref);
 
 	/**
 	 * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String,String,String)"
 	 */
-	public void setURL(URL u, String protocol, String host, int port,
-			String authority, String userInfo, String path, String query,
-			String ref);
+	public void setURL(URL u, String protocol, String host, int port, String authority, String userInfo, String path, String query, String ref);
 }
diff --git a/src/main/java/org/osgi/util/tracker/AbstractTracked.java b/src/main/java/org/osgi/util/tracker/AbstractTracked.java
index 64a271a..f3ddddc 100644
--- a/src/main/java/org/osgi/util/tracker/AbstractTracked.java
+++ b/src/main/java/org/osgi/util/tracker/AbstractTracked.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2007, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2007, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@ import java.util.Map;
  * @param <T> The value mapped to the tracked item.
  * @param <R> The reason the tracked item is being tracked or untracked.
  * @ThreadSafe
- * @version $Id: 79452e6c28683021f2bcf11d3689ec75c6b5642f $
+ * @version $Id: 16340086b98d308c2d12f13bcd87fc6467a5a367 $
  * @since 1.4
  */
 abstract class AbstractTracked<S, T, R> {
@@ -117,8 +117,8 @@ abstract class AbstractTracked<S, T, R> {
 	 * This method must be called from Tracker's open method while synchronized
 	 * on this object in the same synchronized block as the add listener call.
 	 * 
-	 * @param list The initial list of items to be tracked. {@code null}
-	 *        entries in the list are ignored.
+	 * @param list The initial list of items to be tracked. {@code null} entries
+	 *        in the list are ignored.
 	 * @GuardedBy this
 	 */
 	void setInitial(S[] list) {
@@ -162,8 +162,7 @@ abstract class AbstractTracked<S, T, R> {
 				if (tracked.get(item) != null) {
 					/* if we are already tracking this item */
 					if (DEBUG) {
-						System.out
-								.println("AbstractTracked.trackInitial[already tracked]: " + item); //$NON-NLS-1$
+						System.out.println("AbstractTracked.trackInitial[already tracked]: " + item); //$NON-NLS-1$
 					}
 					continue; /* skip this item */
 				}
@@ -172,8 +171,7 @@ abstract class AbstractTracked<S, T, R> {
 					 * if this item is already in the process of being added.
 					 */
 					if (DEBUG) {
-						System.out
-								.println("AbstractTracked.trackInitial[already adding]: " + item); //$NON-NLS-1$
+						System.out.println("AbstractTracked.trackInitial[already adding]: " + item); //$NON-NLS-1$
 					}
 					continue; /* skip this item */
 				}
@@ -214,17 +212,14 @@ abstract class AbstractTracked<S, T, R> {
 				if (adding.contains(item)) {
 					/* if this item is already in the process of being added. */
 					if (DEBUG) {
-						System.out
-								.println("AbstractTracked.track[already adding]: " + item); //$NON-NLS-1$
+						System.out.println("AbstractTracked.track[already adding]: " + item); //$NON-NLS-1$
 					}
 					return;
 				}
 				adding.add(item); /* mark this item is being added */
-			}
-			else { /* we are currently tracking this item */
+			} else { /* we are currently tracking this item */
 				if (DEBUG) {
-					System.out
-							.println("AbstractTracked.track[modified]: " + item); //$NON-NLS-1$
+					System.out.println("AbstractTracked.track[modified]: " + item); //$NON-NLS-1$
 				}
 				modified(); /* increment modification count */
 			}
@@ -232,8 +227,7 @@ abstract class AbstractTracked<S, T, R> {
 
 		if (object == null) { /* we are not tracking the item */
 			trackAdding(item, related);
-		}
-		else {
+		} else {
 			/* Call customizer outside of synchronized region */
 			customizerModified(item, related, object);
 			/*
@@ -264,8 +258,7 @@ abstract class AbstractTracked<S, T, R> {
 			 * If the customizer throws an unchecked exception, it will
 			 * propagate after the finally
 			 */
-		}
-		finally {
+		} finally {
 			synchronized (this) {
 				if (adding.remove(item) && !closed) {
 					/*
@@ -277,8 +270,7 @@ abstract class AbstractTracked<S, T, R> {
 						modified(); /* increment modification count */
 						notifyAll(); /* notify any waiters */
 					}
-				}
-				else {
+				} else {
 					becameUntracked = true;
 				}
 			}
@@ -288,8 +280,7 @@ abstract class AbstractTracked<S, T, R> {
 		 */
 		if (becameUntracked && (object != null)) {
 			if (DEBUG) {
-				System.out
-						.println("AbstractTracked.trackAdding[removed]: " + item); //$NON-NLS-1$
+				System.out.println("AbstractTracked.trackAdding[removed]: " + item); //$NON-NLS-1$
 			}
 			/* Call customizer outside of synchronized region */
 			customizerRemoved(item, related, object);
@@ -314,8 +305,7 @@ abstract class AbstractTracked<S, T, R> {
 										 * of initial references to process
 										 */
 				if (DEBUG) {
-					System.out
-							.println("AbstractTracked.untrack[removed from initial]: " + item); //$NON-NLS-1$
+					System.out.println("AbstractTracked.untrack[removed from initial]: " + item); //$NON-NLS-1$
 				}
 				return; /*
 						 * we have removed it from the list and it will not be
@@ -328,8 +318,7 @@ abstract class AbstractTracked<S, T, R> {
 										 * being added
 										 */
 				if (DEBUG) {
-					System.out
-							.println("AbstractTracked.untrack[being added]: " + item); //$NON-NLS-1$
+					System.out.println("AbstractTracked.untrack[being added]: " + item); //$NON-NLS-1$
 				}
 				return; /*
 						 * in case the item is untracked while in the process of
@@ -430,8 +419,8 @@ abstract class AbstractTracked<S, T, R> {
 	/**
 	 * Copy the tracked items and associated values into the specified map.
 	 * 
-	 * @param <M> Type of {@code Map} to hold the tracked items and
-	 *        associated values.
+	 * @param <M> Type of {@code Map} to hold the tracked items and associated
+	 *        values.
 	 * @param map The map into which to copy the tracked items and associated
 	 *        values. This map must not be a user provided map so that user code
 	 *        is not executed while synchronized on this.
@@ -439,7 +428,7 @@ abstract class AbstractTracked<S, T, R> {
 	 * @GuardedBy this
 	 * @since 1.5
 	 */
-	<M extends Map< ? super S, ? super T>> M copyEntries(final M map) {
+	<M extends Map<? super S, ? super T>> M copyEntries(final M map) {
 		map.putAll(tracked);
 		return map;
 	}
@@ -450,8 +439,8 @@ abstract class AbstractTracked<S, T, R> {
 	 * 
 	 * @param item Item to be tracked.
 	 * @param related Action related object.
-	 * @return Customized object for the tracked item or {@code null} if
-	 *         the item is not to be tracked.
+	 * @return Customized object for the tracked item or {@code null} if the
+	 *         item is not to be tracked.
 	 */
 	abstract T customizerAdding(final S item, final R related);
 
@@ -463,8 +452,7 @@ abstract class AbstractTracked<S, T, R> {
 	 * @param related Action related object.
 	 * @param object Customized object for the tracked item.
 	 */
-	abstract void customizerModified(final S item, final R related,
-			final T object);
+	abstract void customizerModified(final S item, final R related, final T object);
 
 	/**
 	 * Call the specific customizer removed method. This method must not be
@@ -474,6 +462,5 @@ abstract class AbstractTracked<S, T, R> {
 	 * @param related Action related object.
 	 * @param object Customized object for the tracked item.
 	 */
-	abstract void customizerRemoved(final S item, final R related,
-			final T object);
+	abstract void customizerRemoved(final S item, final R related, final T object);
 }
diff --git a/src/main/java/org/osgi/util/tracker/BundleTracker.java b/src/main/java/org/osgi/util/tracker/BundleTracker.java
index 4973503..7e1bb53 100644
--- a/src/main/java/org/osgi/util/tracker/BundleTracker.java
+++ b/src/main/java/org/osgi/util/tracker/BundleTracker.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2007, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2007, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,36 +18,33 @@ package org.osgi.util.tracker;
 
 import java.util.HashMap;
 import java.util.Map;
-
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.SynchronousBundleListener;
 
 /**
- * The {@code BundleTracker} class simplifies tracking bundles much like
- * the {@code ServiceTracker} simplifies tracking services.
+ * The {@code BundleTracker} class simplifies tracking bundles much like the
+ * {@code ServiceTracker} simplifies tracking services.
  * <p>
  * A {@code BundleTracker} is constructed with state criteria and a
- * {@code BundleTrackerCustomizer} object. A {@code BundleTracker} can
- * use the {@code BundleTrackerCustomizer} to select which bundles are
- * tracked and to create a customized object to be tracked with the bundle. The
- * {@code BundleTracker} can then be opened to begin tracking all bundles
- * whose state matches the specified state criteria.
+ * {@code BundleTrackerCustomizer} object. A {@code BundleTracker} can use the
+ * {@code BundleTrackerCustomizer} to select which bundles are tracked and to
+ * create a customized object to be tracked with the bundle. The
+ * {@code BundleTracker} can then be opened to begin tracking all bundles whose
+ * state matches the specified state criteria.
  * <p>
- * The {@code getBundles} method can be called to get the
- * {@code Bundle} objects of the bundles being tracked. The
- * {@code getObject} method can be called to get the customized object for
- * a tracked bundle.
+ * The {@code getBundles} method can be called to get the {@code Bundle} objects
+ * of the bundles being tracked. The {@code getObject} method can be called to
+ * get the customized object for a tracked bundle.
  * <p>
  * The {@code BundleTracker} class is thread-safe. It does not call a
  * {@code BundleTrackerCustomizer} while holding any locks.
- * {@code BundleTrackerCustomizer} implementations must also be
- * thread-safe.
+ * {@code BundleTrackerCustomizer} implementations must also be thread-safe.
  * 
  * @param <T> The type of the tracked object.
  * @ThreadSafe
- * @version $Id: ebfd73a4e19f025d6ad9029d99c17944ee8c420a $
+ * @version $Id: f21db4fe54284d4810bd9b5fa2528957804e3a21 $
  * @since 1.4
  */
 public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
@@ -88,28 +85,25 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 	final int	mask;
 
 	/**
-	 * Create a {@code BundleTracker} for bundles whose state is present in
-	 * the specified state mask.
+	 * Create a {@code BundleTracker} for bundles whose state is present in the
+	 * specified state mask.
 	 * 
 	 * <p>
 	 * Bundles whose state is present on the specified state mask will be
 	 * tracked by this {@code BundleTracker}.
 	 * 
-	 * @param context The {@code BundleContext} against which the tracking
-	 *        is done.
-	 * @param stateMask The bit mask of the {@code OR}ing of the bundle
-	 *        states to be tracked.
+	 * @param context The {@code BundleContext} against which the tracking is
+	 *        done.
+	 * @param stateMask The bit mask of the {@code OR}ing of the bundle states
+	 *        to be tracked.
 	 * @param customizer The customizer object to call when bundles are added,
-	 *        modified, or removed in this {@code BundleTracker}. If
-	 *        customizer is {@code null}, then this
-	 *        {@code BundleTracker} will be used as the
-	 *        {@code BundleTrackerCustomizer} and this
-	 *        {@code BundleTracker} will call the
-	 *        {@code BundleTrackerCustomizer} methods on itself.
+	 *        modified, or removed in this {@code BundleTracker}. If customizer
+	 *        is {@code null}, then this {@code BundleTracker} will be used as
+	 *        the {@code BundleTrackerCustomizer} and this {@code BundleTracker}
+	 *        will call the {@code BundleTrackerCustomizer} methods on itself.
 	 * @see Bundle#getState()
 	 */
-	public BundleTracker(BundleContext context, int stateMask,
-			BundleTrackerCustomizer<T> customizer) {
+	public BundleTracker(BundleContext context, int stateMask, BundleTrackerCustomizer<T> customizer) {
 		this.context = context;
 		this.mask = stateMask;
 		this.customizer = (customizer == null) ? this : customizer;
@@ -123,13 +117,12 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 	 * {@code BundleTracker} was created are now tracked by this
 	 * {@code BundleTracker}.
 	 * 
-	 * @throws java.lang.IllegalStateException If the {@code BundleContext}
-	 *         with which this {@code BundleTracker} was created is no
-	 *         longer valid.
+	 * @throws java.lang.IllegalStateException If the {@code BundleContext} with
+	 *         which this {@code BundleTracker} was created is no longer valid.
 	 * @throws java.lang.SecurityException If the caller and this class do not
 	 *         have the appropriate
-	 *         {@code AdminPermission[context bundle,LISTENER]}, and the
-	 *         Java Runtime Environment supports permissions.
+	 *         {@code AdminPermission[context bundle,LISTENER]}, and the Java
+	 *         Runtime Environment supports permissions.
 	 */
 	public void open() {
 		final Tracked t;
@@ -167,8 +160,8 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 	 * Close this {@code BundleTracker}.
 	 * 
 	 * <p>
-	 * This method should be called when this {@code BundleTracker} should
-	 * end the tracking of bundles.
+	 * This method should be called when this {@code BundleTracker} should end
+	 * the tracking of bundles.
 	 * 
 	 * <p>
 	 * This implementation calls {@link #getBundles()} to get the list of
@@ -190,8 +183,7 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 			tracked = null;
 			try {
 				context.removeBundleListener(outgoing);
-			}
-			catch (IllegalStateException e) {
+			} catch (IllegalStateException e) {
 				/* In case the context was stopped. */
 			}
 		}
@@ -220,8 +212,8 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 	 * @param bundle The {@code Bundle} being added to this
 	 *        {@code BundleTracker} object.
 	 * @param event The bundle event which caused this customizer method to be
-	 *        called or {@code null} if there is no bundle event associated
-	 *        with the call to this method.
+	 *        called or {@code null} if there is no bundle event associated with
+	 *        the call to this method.
 	 * @return The specified bundle.
 	 * @see BundleTrackerCustomizer#addingBundle(Bundle, BundleEvent)
 	 */
@@ -243,8 +235,8 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 	 * 
 	 * @param bundle The {@code Bundle} whose state has been modified.
 	 * @param event The bundle event which caused this customizer method to be
-	 *        called or {@code null} if there is no bundle event associated
-	 *        with the call to this method.
+	 *        called or {@code null} if there is no bundle event associated with
+	 *        the call to this method.
 	 * @param object The customized object for the specified Bundle.
 	 * @see BundleTrackerCustomizer#modifiedBundle(Bundle, BundleEvent, Object)
 	 */
@@ -265,8 +257,8 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 	 * 
 	 * @param bundle The {@code Bundle} being removed.
 	 * @param event The bundle event which caused this customizer method to be
-	 *        called or {@code null} if there is no bundle event associated
-	 *        with the call to this method.
+	 *        called or {@code null} if there is no bundle event associated with
+	 *        the call to this method.
 	 * @param object The customized object for the specified bundle.
 	 * @see BundleTrackerCustomizer#removedBundle(Bundle, BundleEvent, Object)
 	 */
@@ -275,11 +267,11 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 	}
 
 	/**
-	 * Return an array of {@code Bundle}s for all bundles being tracked by
-	 * this {@code BundleTracker}.
+	 * Return an array of {@code Bundle}s for all bundles being tracked by this
+	 * {@code BundleTracker}.
 	 * 
-	 * @return An array of {@code Bundle}s or {@code null} if no
-	 *         bundles are being tracked.
+	 * @return An array of {@code Bundle}s or {@code null} if no bundles are
+	 *         being tracked.
 	 */
 	public Bundle[] getBundles() {
 		final Tracked t = tracked();
@@ -296,13 +288,13 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 	}
 
 	/**
-	 * Returns the customized object for the specified {@code Bundle} if
-	 * the specified bundle is being tracked by this {@code BundleTracker}.
+	 * Returns the customized object for the specified {@code Bundle} if the
+	 * specified bundle is being tracked by this {@code BundleTracker}.
 	 * 
 	 * @param bundle The {@code Bundle} being tracked.
 	 * @return The customized object for the specified {@code Bundle} or
-	 *         {@code null} if the specified {@code Bundle} is not
-	 *         being tracked.
+	 *         {@code null} if the specified {@code Bundle} is not being
+	 *         tracked.
 	 */
 	public T getObject(Bundle bundle) {
 		final Tracked t = tracked();
@@ -317,10 +309,10 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 	/**
 	 * Remove a bundle from this {@code BundleTracker}.
 	 * 
-	 * The specified bundle will be removed from this {@code BundleTracker}
-	 * . If the specified bundle was being tracked then the
-	 * {@code BundleTrackerCustomizer.removedBundle} method will be called
-	 * for that bundle.
+	 * The specified bundle will be removed from this {@code BundleTracker} . If
+	 * the specified bundle was being tracked then the
+	 * {@code BundleTrackerCustomizer.removedBundle} method will be called for
+	 * that bundle.
 	 * 
 	 * @param bundle The {@code Bundle} to be removed.
 	 */
@@ -333,8 +325,7 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 	}
 
 	/**
-	 * Return the number of bundles being tracked by this
-	 * {@code BundleTracker}.
+	 * Return the number of bundles being tracked by this {@code BundleTracker}.
 	 * 
 	 * @return The number of bundles being tracked.
 	 */
@@ -377,13 +368,12 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 	}
 
 	/**
-	 * Return a {@code Map} with the {@code Bundle}s and customized
-	 * objects for all bundles being tracked by this {@code BundleTracker}.
+	 * Return a {@code Map} with the {@code Bundle}s and customized objects for
+	 * all bundles being tracked by this {@code BundleTracker}.
 	 * 
-	 * @return A {@code Map} with the {@code Bundle}s and customized
-	 *         objects for all services being tracked by this
-	 *         {@code BundleTracker}. If no bundles are being tracked, then
-	 *         the returned map is empty.
+	 * @return A {@code Map} with the {@code Bundle}s and customized objects for
+	 *         all services being tracked by this {@code BundleTracker}. If no
+	 *         bundles are being tracked, then the returned map is empty.
 	 * @since 1.5
 	 */
 	public Map<Bundle, T> getTracked() {
@@ -421,9 +411,7 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 	 * @ThreadSafe
 	 * @since 1.4
 	 */
-	private final class Tracked extends AbstractTracked<Bundle, T, BundleEvent>
-			implements
-			SynchronousBundleListener {
+	private final class Tracked extends AbstractTracked<Bundle, T, BundleEvent> implements SynchronousBundleListener {
 		/**
 		 * Tracked constructor.
 		 */
@@ -432,9 +420,8 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 		}
 
 		/**
-		 * {@code BundleListener} method for the {@code BundleTracker}
-		 * class. This method must NOT be synchronized to avoid deadlock
-		 * potential.
+		 * {@code BundleListener} method for the {@code BundleTracker} class.
+		 * This method must NOT be synchronized to avoid deadlock potential.
 		 * 
 		 * @param event {@code BundleEvent} object from the framework.
 		 */
@@ -449,8 +436,7 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 			final Bundle bundle = event.getBundle();
 			final int state = bundle.getState();
 			if (DEBUG) {
-				System.out
-						.println("BundleTracker.Tracked.bundleChanged[" + state + "]: " + bundle); //$NON-NLS-1$ //$NON-NLS-2$
+				System.out.println("BundleTracker.Tracked.bundleChanged[" + state + "]: " + bundle); //$NON-NLS-1$ //$NON-NLS-2$
 			}
 
 			if ((state & mask) != 0) {
@@ -459,8 +445,7 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 				 * If the customizer throws an unchecked exception, it is safe
 				 * to let it propagate
 				 */
-			}
-			else {
+			} else {
 				untrack(bundle, event);
 				/*
 				 * If the customizer throws an unchecked exception, it is safe
@@ -475,8 +460,8 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 		 * 
 		 * @param item Item to be tracked.
 		 * @param related Action related object.
-		 * @return Customized object for the tracked item or {@code null}
-		 *         if the item is not to be tracked.
+		 * @return Customized object for the tracked item or {@code null} if the
+		 *         item is not to be tracked.
 		 */
 		T customizerAdding(final Bundle item, final BundleEvent related) {
 			return customizer.addingBundle(item, related);
@@ -490,8 +475,7 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 		 * @param related Action related object.
 		 * @param object Customized object for the tracked item.
 		 */
-		void customizerModified(final Bundle item, final BundleEvent related,
-				final T object) {
+		void customizerModified(final Bundle item, final BundleEvent related, final T object) {
 			customizer.modifiedBundle(item, related, object);
 		}
 
@@ -503,8 +487,7 @@ public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 		 * @param related Action related object.
 		 * @param object Customized object for the tracked item.
 		 */
-		void customizerRemoved(final Bundle item, final BundleEvent related,
-				final T object) {
+		void customizerRemoved(final Bundle item, final BundleEvent related, final T object) {
 			customizer.removedBundle(item, related, object);
 		}
 	}
diff --git a/src/main/java/org/osgi/util/tracker/BundleTrackerCustomizer.java b/src/main/java/org/osgi/util/tracker/BundleTrackerCustomizer.java
index a7c9a23..b0bb297 100644
--- a/src/main/java/org/osgi/util/tracker/BundleTrackerCustomizer.java
+++ b/src/main/java/org/osgi/util/tracker/BundleTrackerCustomizer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2007, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2007, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,32 +20,29 @@ import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleEvent;
 
 /**
- * The {@code BundleTrackerCustomizer} interface allows a
- * {@code BundleTracker} to customize the {@code Bundle}s that are
- * tracked. A {@code BundleTrackerCustomizer} is called when a bundle is
- * being added to a {@code BundleTracker}. The
- * {@code BundleTrackerCustomizer} can then return an object for the
- * tracked bundle. A {@code BundleTrackerCustomizer} is also called when a
- * tracked bundle is modified or has been removed from a
+ * The {@code BundleTrackerCustomizer} interface allows a {@code BundleTracker}
+ * to customize the {@code Bundle}s that are tracked. A
+ * {@code BundleTrackerCustomizer} is called when a bundle is being added to a
+ * {@code BundleTracker}. The {@code BundleTrackerCustomizer} can then return an
+ * object for the tracked bundle. A {@code BundleTrackerCustomizer} is also
+ * called when a tracked bundle is modified or has been removed from a
  * {@code BundleTracker}.
  * 
  * <p>
  * The methods in this interface may be called as the result of a
- * {@code BundleEvent} being received by a {@code BundleTracker}.
- * Since {@code BundleEvent}s are received synchronously by the
- * {@code BundleTracker}, it is highly recommended that implementations of
- * these methods do not alter bundle states while being synchronized on any
- * object.
+ * {@code BundleEvent} being received by a {@code BundleTracker}. Since
+ * {@code BundleEvent}s are received synchronously by the {@code BundleTracker},
+ * it is highly recommended that implementations of these methods do not alter
+ * bundle states while being synchronized on any object.
  * 
  * <p>
  * The {@code BundleTracker} class is thread-safe. It does not call a
  * {@code BundleTrackerCustomizer} while holding any locks.
- * {@code BundleTrackerCustomizer} implementations must also be
- * thread-safe.
+ * {@code BundleTrackerCustomizer} implementations must also be thread-safe.
  * 
  * @param <T> The type of the tracked object.
  * @ThreadSafe
- * @version $Id: 0e80f2555530b217faef57726a5938f0087a45c5 $
+ * @version $Id: 727e757d2fa2940c88c9b74c8d299de6b3a7d0d0 $
  * @since 1.4
  */
 public interface BundleTrackerCustomizer<T> {
@@ -54,20 +51,20 @@ public interface BundleTrackerCustomizer<T> {
 	 * 
 	 * <p>
 	 * This method is called before a bundle which matched the search parameters
-	 * of the {@code BundleTracker} is added to the
-	 * {@code BundleTracker}. This method should return the object to be
-	 * tracked for the specified {@code Bundle}. The returned object is
-	 * stored in the {@code BundleTracker} and is available from the
+	 * of the {@code BundleTracker} is added to the {@code BundleTracker}. This
+	 * method should return the object to be tracked for the specified
+	 * {@code Bundle}. The returned object is stored in the
+	 * {@code BundleTracker} and is available from the
 	 * {@link BundleTracker#getObject(Bundle) getObject} method.
 	 * 
-	 * @param bundle The {@code Bundle} being added to the
-	 *        {@code BundleTracker}.
+	 * @param bundle The {@code Bundle} being added to the {@code BundleTracker}
+	 *        .
 	 * @param event The bundle event which caused this customizer method to be
-	 *        called or {@code null} if there is no bundle event associated
-	 *        with the call to this method.
-	 * @return The object to be tracked for the specified {@code Bundle}
-	 *         object or {@code null} if the specified {@code Bundle}
-	 *         object should not be tracked.
+	 *        called or {@code null} if there is no bundle event associated with
+	 *        the call to this method.
+	 * @return The object to be tracked for the specified {@code Bundle} object
+	 *         or {@code null} if the specified {@code Bundle} object should not
+	 *         be tracked.
 	 */
 	public T addingBundle(Bundle bundle, BundleEvent event);
 
@@ -80,12 +77,11 @@ public interface BundleTrackerCustomizer<T> {
 	 * 
 	 * @param bundle The {@code Bundle} whose state has been modified.
 	 * @param event The bundle event which caused this customizer method to be
-	 *        called or {@code null} if there is no bundle event associated
-	 *        with the call to this method.
+	 *        called or {@code null} if there is no bundle event associated with
+	 *        the call to this method.
 	 * @param object The tracked object for the specified bundle.
 	 */
-	public void modifiedBundle(Bundle bundle, BundleEvent event,
-			T object);
+	public void modifiedBundle(Bundle bundle, BundleEvent event, T object);
 
 	/**
 	 * A bundle tracked by the {@code BundleTracker} has been removed.
@@ -96,10 +92,9 @@ public interface BundleTrackerCustomizer<T> {
 	 * 
 	 * @param bundle The {@code Bundle} that has been removed.
 	 * @param event The bundle event which caused this customizer method to be
-	 *        called or {@code null} if there is no bundle event associated
-	 *        with the call to this method.
+	 *        called or {@code null} if there is no bundle event associated with
+	 *        the call to this method.
 	 * @param object The tracked object for the specified bundle.
 	 */
-	public void removedBundle(Bundle bundle, BundleEvent event,
-			T object);
+	public void removedBundle(Bundle bundle, BundleEvent event, T object);
 }
diff --git a/src/main/java/org/osgi/util/tracker/ServiceTracker.java b/src/main/java/org/osgi/util/tracker/ServiceTracker.java
index f5cd086..0c8022d 100644
--- a/src/main/java/org/osgi/util/tracker/ServiceTracker.java
+++ b/src/main/java/org/osgi/util/tracker/ServiceTracker.java
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
- * 
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
@@ -20,7 +20,6 @@ import java.lang.reflect.Array;
 import java.util.Collections;
 import java.util.SortedMap;
 import java.util.TreeMap;
-
 import org.osgi.framework.AllServiceListener;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -34,29 +33,26 @@ import org.osgi.framework.ServiceReference;
  * The {@code ServiceTracker} class simplifies using services from the
  * Framework's service registry.
  * <p>
- * A {@code ServiceTracker} object is constructed with search criteria and
- * a {@code ServiceTrackerCustomizer} object. A {@code ServiceTracker}
- * can use a {@code ServiceTrackerCustomizer} to customize the service
- * objects to be tracked. The {@code ServiceTracker} can then be opened to
- * begin tracking all services in the Framework's service registry that match
- * the specified search criteria. The {@code ServiceTracker} correctly
- * handles all of the details of listening to {@code ServiceEvent}s and
- * getting and ungetting services.
+ * A {@code ServiceTracker} object is constructed with search criteria and a
+ * {@code ServiceTrackerCustomizer} object. A {@code ServiceTracker} can use a
+ * {@code ServiceTrackerCustomizer} to customize the service objects to be
+ * tracked. The {@code ServiceTracker} can then be opened to begin tracking all
+ * services in the Framework's service registry that match the specified search
+ * criteria. The {@code ServiceTracker} correctly handles all of the details of
+ * listening to {@code ServiceEvent}s and getting and ungetting services.
  * <p>
- * The {@code getServiceReferences} method can be called to get references
- * to the services being tracked. The {@code getService} and
- * {@code getServices} methods can be called to get the service objects for
- * the tracked service.
+ * The {@code getServiceReferences} method can be called to get references to
+ * the services being tracked. The {@code getService} and {@code getServices}
+ * methods can be called to get the service objects for the tracked service.
  * <p>
  * The {@code ServiceTracker} class is thread-safe. It does not call a
  * {@code ServiceTrackerCustomizer} while holding any locks.
- * {@code ServiceTrackerCustomizer} implementations must also be
- * thread-safe.
+ * {@code ServiceTrackerCustomizer} implementations must also be thread-safe.
  * 
  * @param <S> The type of the service being tracked.
  * @param <T> The type of the tracked object.
  * @ThreadSafe
- * @version $Id: df62459c90f49d06e89ff8f20915a9eec401217e $
+ * @version $Id: 21926ad8717a91633face6bbf570febfcd23b1c7 $
  */
 public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	/* set this to true to compile in debug messages */
@@ -66,8 +62,8 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	 */
 	protected final BundleContext			context;
 	/**
-	 * The Filter used by this {@code ServiceTracker} which specifies the
-	 * search criteria for the services to track.
+	 * The Filter used by this {@code ServiceTracker} which specifies the search
+	 * criteria for the services to track.
 	 * 
 	 * @since 1.1
 	 */
@@ -123,44 +119,38 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	private volatile T						cachedService;
 
 	/**
-	 * Create a {@code ServiceTracker} on the specified
-	 * {@code ServiceReference}.
+	 * Create a {@code ServiceTracker} on the specified {@code ServiceReference}
+	 * .
 	 * 
 	 * <p>
-	 * The service referenced by the specified {@code ServiceReference}
-	 * will be tracked by this {@code ServiceTracker}.
+	 * The service referenced by the specified {@code ServiceReference} will be
+	 * tracked by this {@code ServiceTracker}.
 	 * 
-	 * @param context The {@code BundleContext} against which the tracking
-	 *        is done.
+	 * @param context The {@code BundleContext} against which the tracking is
+	 *        done.
 	 * @param reference The {@code ServiceReference} for the service to be
 	 *        tracked.
 	 * @param customizer The customizer object to call when services are added,
-	 *        modified, or removed in this {@code ServiceTracker}. If
-	 *        customizer is {@code null}, then this
-	 *        {@code ServiceTracker} will be used as the
-	 *        {@code ServiceTrackerCustomizer} and this
+	 *        modified, or removed in this {@code ServiceTracker}. If customizer
+	 *        is {@code null}, then this {@code ServiceTracker} will be used as
+	 *        the {@code ServiceTrackerCustomizer} and this
 	 *        {@code ServiceTracker} will call the
 	 *        {@code ServiceTrackerCustomizer} methods on itself.
 	 */
-	public ServiceTracker(final BundleContext context,
-			final ServiceReference<S> reference,
-			final ServiceTrackerCustomizer<S, T> customizer) {
+	public ServiceTracker(final BundleContext context, final ServiceReference<S> reference, final ServiceTrackerCustomizer<S, T> customizer) {
 		this.context = context;
 		this.trackReference = reference;
 		this.trackClass = null;
 		this.customizer = (customizer == null) ? this : customizer;
-		this.listenerFilter = "(" + Constants.SERVICE_ID + "="
-				+ reference.getProperty(Constants.SERVICE_ID).toString() + ")";
+		this.listenerFilter = "(" + Constants.SERVICE_ID + "=" + reference.getProperty(Constants.SERVICE_ID).toString() + ")";
 		try {
 			this.filter = context.createFilter(listenerFilter);
-		}
-		catch (InvalidSyntaxException e) {
+		} catch (InvalidSyntaxException e) {
 			/*
 			 * we could only get this exception if the ServiceReference was
 			 * invalid
 			 */
-			IllegalArgumentException iae = new IllegalArgumentException(
-					"unexpected InvalidSyntaxException: " + e.getMessage());
+			IllegalArgumentException iae = new IllegalArgumentException("unexpected InvalidSyntaxException: " + e.getMessage());
 			iae.initCause(e);
 			throw iae;
 		}
@@ -173,63 +163,54 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	 * Services registered under the specified class name will be tracked by
 	 * this {@code ServiceTracker}.
 	 * 
-	 * @param context The {@code BundleContext} against which the tracking
-	 *        is done.
+	 * @param context The {@code BundleContext} against which the tracking is
+	 *        done.
 	 * @param clazz The class name of the services to be tracked.
 	 * @param customizer The customizer object to call when services are added,
-	 *        modified, or removed in this {@code ServiceTracker}. If
-	 *        customizer is {@code null}, then this
-	 *        {@code ServiceTracker} will be used as the
-	 *        {@code ServiceTrackerCustomizer} and this
+	 *        modified, or removed in this {@code ServiceTracker}. If customizer
+	 *        is {@code null}, then this {@code ServiceTracker} will be used as
+	 *        the {@code ServiceTrackerCustomizer} and this
 	 *        {@code ServiceTracker} will call the
 	 *        {@code ServiceTrackerCustomizer} methods on itself.
 	 */
-	public ServiceTracker(final BundleContext context, final String clazz,
-			final ServiceTrackerCustomizer<S, T> customizer) {
+	public ServiceTracker(final BundleContext context, final String clazz, final ServiceTrackerCustomizer<S, T> customizer) {
 		this.context = context;
 		this.trackReference = null;
 		this.trackClass = clazz;
 		this.customizer = (customizer == null) ? this : customizer;
 		// we call clazz.toString to verify clazz is non-null!
-		this.listenerFilter = "(" + Constants.OBJECTCLASS + "="
-				+ clazz.toString() + ")";
+		this.listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz.toString() + ")";
 		try {
 			this.filter = context.createFilter(listenerFilter);
-		}
-		catch (InvalidSyntaxException e) {
+		} catch (InvalidSyntaxException e) {
 			/*
 			 * we could only get this exception if the clazz argument was
 			 * malformed
 			 */
-			IllegalArgumentException iae = new IllegalArgumentException(
-					"unexpected InvalidSyntaxException: " + e.getMessage());
+			IllegalArgumentException iae = new IllegalArgumentException("unexpected InvalidSyntaxException: " + e.getMessage());
 			iae.initCause(e);
 			throw iae;
 		}
 	}
 
 	/**
-	 * Create a {@code ServiceTracker} on the specified {@code Filter}
-	 * object.
+	 * Create a {@code ServiceTracker} on the specified {@code Filter} object.
 	 * 
 	 * <p>
-	 * Services which match the specified {@code Filter} object will be
-	 * tracked by this {@code ServiceTracker}.
+	 * Services which match the specified {@code Filter} object will be tracked
+	 * by this {@code ServiceTracker}.
 	 * 
-	 * @param context The {@code BundleContext} against which the tracking
-	 *        is done.
-	 * @param filter The {@code Filter} to select the services to be
-	 *        tracked.
+	 * @param context The {@code BundleContext} against which the tracking is
+	 *        done.
+	 * @param filter The {@code Filter} to select the services to be tracked.
 	 * @param customizer The customizer object to call when services are added,
-	 *        modified, or removed in this {@code ServiceTracker}. If
-	 *        customizer is null, then this {@code ServiceTracker} will be
-	 *        used as the {@code ServiceTrackerCustomizer} and this
-	 *        {@code ServiceTracker} will call the
-	 *        {@code ServiceTrackerCustomizer} methods on itself.
+	 *        modified, or removed in this {@code ServiceTracker}. If customizer
+	 *        is null, then this {@code ServiceTracker} will be used as the
+	 *        {@code ServiceTrackerCustomizer} and this {@code ServiceTracker}
+	 *        will call the {@code ServiceTrackerCustomizer} methods on itself.
 	 * @since 1.1
 	 */
-	public ServiceTracker(final BundleContext context, final Filter filter,
-			final ServiceTrackerCustomizer<S, T> customizer) {
+	public ServiceTracker(final BundleContext context, final Filter filter, final ServiceTrackerCustomizer<S, T> customizer) {
 		this.context = context;
 		this.trackReference = null;
 		this.trackClass = null;
@@ -251,20 +232,18 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	 * Services registered under the name of the specified class will be tracked
 	 * by this {@code ServiceTracker}.
 	 * 
-	 * @param context The {@code BundleContext} against which the tracking
-	 *        is done.
+	 * @param context The {@code BundleContext} against which the tracking is
+	 *        done.
 	 * @param clazz The class of the services to be tracked.
 	 * @param customizer The customizer object to call when services are added,
-	 *        modified, or removed in this {@code ServiceTracker}. If
-	 *        customizer is {@code null}, then this
-	 *        {@code ServiceTracker} will be used as the
-	 *        {@code ServiceTrackerCustomizer} and this
+	 *        modified, or removed in this {@code ServiceTracker}. If customizer
+	 *        is {@code null}, then this {@code ServiceTracker} will be used as
+	 *        the {@code ServiceTrackerCustomizer} and this
 	 *        {@code ServiceTracker} will call the
 	 *        {@code ServiceTrackerCustomizer} methods on itself.
 	 * @since 1.5
 	 */
-	public ServiceTracker(final BundleContext context, final Class<S> clazz,
-			final ServiceTrackerCustomizer<S, T> customizer) {
+	public ServiceTracker(final BundleContext context, final Class<S> clazz, final ServiceTrackerCustomizer<S, T> customizer) {
 		this(context, clazz.getName(), customizer);
 	}
 
@@ -274,9 +253,8 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	 * <p>
 	 * This implementation calls {@code open(false)}.
 	 * 
-	 * @throws java.lang.IllegalStateException If the {@code BundleContext}
-	 *         with which this {@code ServiceTracker} was created is no
-	 *         longer valid.
+	 * @throws java.lang.IllegalStateException If the {@code BundleContext} with
+	 *         which this {@code ServiceTracker} was created is no longer valid.
 	 * @see #open(boolean)
 	 */
 	public void open() {
@@ -291,16 +269,14 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	 * {@code ServiceTracker} was created are now tracked by this
 	 * {@code ServiceTracker}.
 	 * 
-	 * @param trackAllServices If {@code true}, then this
-	 *        {@code ServiceTracker} will track all matching services
-	 *        regardless of class loader accessibility. If {@code false},
-	 *        then this {@code ServiceTracker} will only track matching
-	 *        services which are class loader accessible to the bundle whose
-	 *        {@code BundleContext} is used by this
-	 *        {@code ServiceTracker}.
-	 * @throws java.lang.IllegalStateException If the {@code BundleContext}
-	 *         with which this {@code ServiceTracker} was created is no
-	 *         longer valid.
+	 * @param trackAllServices If {@code true}, then this {@code ServiceTracker}
+	 *        will track all matching services regardless of class loader
+	 *        accessibility. If {@code false}, then this {@code ServiceTracker}
+	 *        will only track matching services which are class loader
+	 *        accessible to the bundle whose {@code BundleContext} is used by
+	 *        this {@code ServiceTracker}.
+	 * @throws java.lang.IllegalStateException If the {@code BundleContext} with
+	 *         which this {@code ServiceTracker} was created is no longer valid.
 	 * @since 1.3
 	 */
 	public void open(boolean trackAllServices) {
@@ -318,28 +294,21 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 					context.addServiceListener(t, listenerFilter);
 					ServiceReference<S>[] references = null;
 					if (trackClass != null) {
-						references = getInitialReferences(trackAllServices,
-								trackClass, null);
-					}
-					else {
+						references = getInitialReferences(trackAllServices, trackClass, null);
+					} else {
 						if (trackReference != null) {
 							if (trackReference.getBundle() != null) {
 								ServiceReference<S>[] single = new ServiceReference[] {trackReference};
 								references = single;
 							}
-						}
-						else { /* user supplied filter */
-							references = getInitialReferences(trackAllServices,
-									null, listenerFilter);
+						} else { /* user supplied filter */
+							references = getInitialReferences(trackAllServices, null, listenerFilter);
 						}
 					}
 					/* set tracked with the initial references */
 					t.setInitial(references);
-				}
-				catch (InvalidSyntaxException e) {
-					throw new RuntimeException(
-							"unexpected InvalidSyntaxException: "
-									+ e.getMessage(), e);
+				} catch (InvalidSyntaxException e) {
+					throw new RuntimeException("unexpected InvalidSyntaxException: " + e.getMessage(), e);
 				}
 			}
 			tracked = t;
@@ -356,18 +325,13 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	 *        {@code getAllServiceReferences}.
 	 * @param className The class name with which the service was registered, or
 	 *        {@code null} for all services.
-	 * @param filterString The filter criteria or {@code null} for all
-	 *        services.
+	 * @param filterString The filter criteria or {@code null} for all services.
 	 * @return The list of initial {@code ServiceReference}s.
 	 * @throws InvalidSyntaxException If the specified filterString has an
 	 *         invalid syntax.
 	 */
-	private ServiceReference<S>[] getInitialReferences(
-			boolean trackAllServices, String className, String filterString)
-			throws InvalidSyntaxException {
-		ServiceReference<S>[] result = (ServiceReference<S>[]) ((trackAllServices) ? context
-				.getAllServiceReferences(className, filterString)
-				: context.getServiceReferences(className, filterString));
+	private ServiceReference<S>[] getInitialReferences(boolean trackAllServices, String className, String filterString) throws InvalidSyntaxException {
+		ServiceReference<S>[] result = (ServiceReference<S>[]) ((trackAllServices) ? context.getAllServiceReferences(className, filterString) : context.getServiceReferences(className, filterString));
 		return result;
 	}
 
@@ -375,8 +339,8 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	 * Close this {@code ServiceTracker}.
 	 * 
 	 * <p>
-	 * This method should be called when this {@code ServiceTracker} should
-	 * end the tracking of services.
+	 * This method should be called when this {@code ServiceTracker} should end
+	 * the tracking of services.
 	 * 
 	 * <p>
 	 * This implementation calls {@link #getServiceReferences()} to get the list
@@ -398,8 +362,7 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 			tracked = null;
 			try {
 				context.removeServiceListener(outgoing);
-			}
-			catch (IllegalStateException e) {
+			} catch (IllegalStateException e) {
 				/* In case the context was stopped. */
 			}
 		}
@@ -414,8 +377,7 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 		}
 		if (DEBUG) {
 			if ((cachedReference == null) && (cachedService == null)) {
-				System.out.println("ServiceTracker.close[cached cleared]: "
-						+ filter);
+				System.out.println("ServiceTracker.close[cached cleared]: " + filter);
 			}
 		}
 	}
@@ -429,10 +391,9 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	 * constructed with a {@code null ServiceTrackerCustomizer} argument.
 	 * 
 	 * <p>
-	 * This implementation returns the result of calling {@code getService}
-	 * on the {@code BundleContext} with which this
-	 * {@code ServiceTracker} was created passing the specified
-	 * {@code ServiceReference}.
+	 * This implementation returns the result of calling {@code getService} on
+	 * the {@code BundleContext} with which this {@code ServiceTracker} was
+	 * created passing the specified {@code ServiceReference}.
 	 * <p>
 	 * This method can be overridden in a subclass to customize the service
 	 * object to be tracked for the service being added. In that case, take care
@@ -480,8 +441,8 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	 * 
 	 * <p>
 	 * This implementation calls {@code ungetService}, on the
-	 * {@code BundleContext} with which this {@code ServiceTracker}
-	 * was created, passing the specified {@code ServiceReference}.
+	 * {@code BundleContext} with which this {@code ServiceTracker} was created,
+	 * passing the specified {@code ServiceReference}.
 	 * <p>
 	 * This method can be overridden in a subclass. If the default
 	 * implementation of {@link #addingService(ServiceReference) addingService}
@@ -501,8 +462,8 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	 * {@code ServiceTracker} is closed.
 	 * 
 	 * <p>
-	 * It is strongly recommended that {@code waitForService} is not used
-	 * during the calling of the {@code BundleActivator} methods.
+	 * It is strongly recommended that {@code waitForService} is not used during
+	 * the calling of the {@code BundleActivator} methods.
 	 * {@code BundleActivator} methods are expected to complete in a short
 	 * period of time.
 	 * 
@@ -521,8 +482,14 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 		if (timeout < 0) {
 			throw new IllegalArgumentException("timeout value is negative");
 		}
+
 		T object = getService();
-		while (object == null) {
+		if (object != null) {
+			return object;
+		}
+
+		final long endTime = (timeout == 0) ? 0 : (System.currentTimeMillis() + timeout);
+		do {
 			final Tracked t = tracked();
 			if (t == null) { /* if ServiceTracker is not open */
 				return null;
@@ -533,10 +500,13 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 				}
 			}
 			object = getService();
-			if (timeout > 0) {
-				return object;
+			if (endTime > 0) { // if we have a timeout
+				timeout = endTime - System.currentTimeMillis();
+				if (timeout <= 0) { // that has expired
+					break;
+				}
 			}
-		}
+		} while (object == null);
 		return object;
 	}
 
@@ -544,8 +514,8 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	 * Return an array of {@code ServiceReference}s for all services being
 	 * tracked by this {@code ServiceTracker}.
 	 * 
-	 * @return Array of {@code ServiceReference}s or {@code null} if
-	 *         no services are being tracked.
+	 * @return Array of {@code ServiceReference}s or {@code null} if no services
+	 *         are being tracked.
 	 */
 	public ServiceReference<S>[] getServiceReferences() {
 		final Tracked t = tracked();
@@ -563,32 +533,30 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	}
 
 	/**
-	 * Returns a {@code ServiceReference} for one of the services being
-	 * tracked by this {@code ServiceTracker}.
+	 * Returns a {@code ServiceReference} for one of the services being tracked
+	 * by this {@code ServiceTracker}.
 	 * 
 	 * <p>
 	 * If multiple services are being tracked, the service with the highest
 	 * ranking (as specified in its {@code service.ranking} property) is
 	 * returned. If there is a tie in ranking, the service with the lowest
-	 * service ID (as specified in its {@code service.id} property); that
-	 * is, the service that was registered first is returned. This is the same
+	 * service ID (as specified in its {@code service.id} property); that is,
+	 * the service that was registered first is returned. This is the same
 	 * algorithm used by {@code BundleContext.getServiceReference}.
 	 * 
 	 * <p>
 	 * This implementation calls {@link #getServiceReferences()} to get the list
 	 * of references for the tracked services.
 	 * 
-	 * @return A {@code ServiceReference} or {@code null} if no
-	 *         services are being tracked.
+	 * @return A {@code ServiceReference} or {@code null} if no services are
+	 *         being tracked.
 	 * @since 1.1
 	 */
 	public ServiceReference<S> getServiceReference() {
 		ServiceReference<S> reference = cachedReference;
 		if (reference != null) {
 			if (DEBUG) {
-				System.out
-						.println("ServiceTracker.getServiceReference[cached]: "
-								+ filter);
+				System.out.println("ServiceTracker.getServiceReference[cached]: " + filter);
 			}
 			return reference;
 		}
@@ -606,18 +574,14 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 			int count = 0;
 			int maxRanking = Integer.MIN_VALUE;
 			for (int i = 0; i < length; i++) {
-				Object property = references[i]
-						.getProperty(Constants.SERVICE_RANKING);
-				int ranking = (property instanceof Integer) ? ((Integer) property)
-						.intValue()
-						: 0;
+				Object property = references[i].getProperty(Constants.SERVICE_RANKING);
+				int ranking = (property instanceof Integer) ? ((Integer) property).intValue() : 0;
 				rankings[i] = ranking;
 				if (ranking > maxRanking) {
 					index = i;
 					maxRanking = ranking;
 					count = 1;
-				}
-				else {
+				} else {
 					if (ranking == maxRanking) {
 						count++;
 					}
@@ -627,9 +591,7 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 				long minId = Long.MAX_VALUE;
 				for (int i = 0; i < length; i++) {
 					if (rankings[i] == maxRanking) {
-						long id = ((Long) (references[i]
-								.getProperty(Constants.SERVICE_ID)))
-								.longValue();
+						long id = ((Long) (references[i].getProperty(Constants.SERVICE_ID))).longValue();
 						if (id < minId) {
 							index = i;
 							minId = id;
@@ -642,14 +604,13 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	}
 
 	/**
-	 * Returns the service object for the specified
-	 * {@code ServiceReference} if the specified referenced service is
-	 * being tracked by this {@code ServiceTracker}.
+	 * Returns the service object for the specified {@code ServiceReference} if
+	 * the specified referenced service is being tracked by this
+	 * {@code ServiceTracker}.
 	 * 
 	 * @param reference The reference to the desired service.
-	 * @return A service object or {@code null} if the service referenced
-	 *         by the specified {@code ServiceReference} is not being
-	 *         tracked.
+	 * @return A service object or {@code null} if the service referenced by the
+	 *         specified {@code ServiceReference} is not being tracked.
 	 */
 	public T getService(ServiceReference<S> reference) {
 		final Tracked t = tracked();
@@ -671,8 +632,8 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	 * {@link #getService(ServiceReference)} for each reference to get the
 	 * tracked service object.
 	 * 
-	 * @return An array of service objects or {@code null} if no services
-	 *         are being tracked.
+	 * @return An array of service objects or {@code null} if no services are
+	 *         being tracked.
 	 */
 	public Object[] getServices() {
 		final Tracked t = tracked();
@@ -708,8 +669,7 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 		T service = cachedService;
 		if (service != null) {
 			if (DEBUG) {
-				System.out.println("ServiceTracker.getService[cached]: "
-						+ filter);
+				System.out.println("ServiceTracker.getService[cached]: " + filter);
 			}
 			return service;
 		}
@@ -726,10 +686,10 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	/**
 	 * Remove a service from this {@code ServiceTracker}.
 	 * 
-	 * The specified service will be removed from this
-	 * {@code ServiceTracker}. If the specified service was being tracked
-	 * then the {@code ServiceTrackerCustomizer.removedService} method will
-	 * be called for that service.
+	 * The specified service will be removed from this {@code ServiceTracker}.
+	 * If the specified service was being tracked then the
+	 * {@code ServiceTrackerCustomizer.removedService} method will be called for
+	 * that service.
 	 * 
 	 * @param reference The reference to the service to be removed.
 	 */
@@ -804,21 +764,20 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	}
 
 	/**
-	 * Return a {@code SortedMap} of the {@code ServiceReference}s and
-	 * service objects for all services being tracked by this
-	 * {@code ServiceTracker}. The map is sorted in reverse natural order
-	 * of {@code ServiceReference}. That is, the first entry is the service
-	 * with the highest ranking and the lowest service id.
+	 * Return a {@code SortedMap} of the {@code ServiceReference}s and service
+	 * objects for all services being tracked by this {@code ServiceTracker}.
+	 * The map is sorted in reverse natural order of {@code ServiceReference}.
+	 * That is, the first entry is the service with the highest ranking and the
+	 * lowest service id.
 	 * 
-	 * @return A {@code SortedMap} with the {@code ServiceReference}s
-	 *         and service objects for all services being tracked by this
-	 *         {@code ServiceTracker}. If no services are being tracked,
-	 *         then the returned map is empty.
+	 * @return A {@code SortedMap} with the {@code ServiceReference}s and
+	 *         service objects for all services being tracked by this
+	 *         {@code ServiceTracker}. If no services are being tracked, then
+	 *         the returned map is empty.
 	 * @since 1.5
 	 */
 	public SortedMap<ServiceReference<S>, T> getTracked() {
-		SortedMap<ServiceReference<S>, T> map = new TreeMap<ServiceReference<S>, T>(
-				Collections.reverseOrder());
+		SortedMap<ServiceReference<S>, T> map = new TreeMap<ServiceReference<S>, T>(Collections.reverseOrder());
 		final Tracked t = tracked();
 		if (t == null) { /* if ServiceTracker is not open */
 			return map;
@@ -884,8 +843,7 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 				return array;
 			}
 			if (length > array.length) {
-				array = (T[]) Array.newInstance(array.getClass()
-						.getComponentType(), length);
+				array = (T[]) Array.newInstance(array.getClass().getComponentType(), length);
 			}
 			for (int i = 0; i < length; i++) {
 				array[i] = getService(references[i]);
@@ -903,9 +861,7 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	 * 
 	 * @ThreadSafe
 	 */
-	private class Tracked extends
-			AbstractTracked<ServiceReference<S>, T, ServiceEvent>
-			implements ServiceListener {
+	private class Tracked extends AbstractTracked<ServiceReference<S>, T, ServiceEvent> implements ServiceListener {
 		/**
 		 * Tracked constructor.
 		 */
@@ -914,9 +870,8 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 		}
 
 		/**
-		 * {@code ServiceListener} method for the
-		 * {@code ServiceTracker} class. This method must NOT be
-		 * synchronized to avoid deadlock potential.
+		 * {@code ServiceListener} method for the {@code ServiceTracker} class.
+		 * This method must NOT be synchronized to avoid deadlock potential.
 		 * 
 		 * @param event {@code ServiceEvent} object from the framework.
 		 */
@@ -928,11 +883,9 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 			if (closed) {
 				return;
 			}
-			final ServiceReference<S> reference = (ServiceReference<S>) event
-					.getServiceReference();
+			final ServiceReference<S> reference = (ServiceReference<S>) event.getServiceReference();
 			if (DEBUG) {
-				System.out.println("ServiceTracker.Tracked.serviceChanged["
-						+ event.getType() + "]: " + reference);
+				System.out.println("ServiceTracker.Tracked.serviceChanged[" + event.getType() + "]: " + reference);
 			}
 
 			switch (event.getType()) {
@@ -972,11 +925,10 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 		 * 
 		 * @param item Item to be tracked.
 		 * @param related Action related object.
-		 * @return Customized object for the tracked item or {@code null}
-		 *         if the item is not to be tracked.
+		 * @return Customized object for the tracked item or {@code null} if the
+		 *         item is not to be tracked.
 		 */
-		final T customizerAdding(final ServiceReference<S> item,
-				final ServiceEvent related) {
+		final T customizerAdding(final ServiceReference<S> item, final ServiceEvent related) {
 			return customizer.addingService(item);
 		}
 
@@ -988,8 +940,7 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 		 * @param related Action related object.
 		 * @param object Customized object for the tracked item.
 		 */
-		final void customizerModified(final ServiceReference<S> item,
-				final ServiceEvent related, final T object) {
+		final void customizerModified(final ServiceReference<S> item, final ServiceEvent related, final T object) {
 			customizer.modifiedService(item, object);
 		}
 
@@ -1001,8 +952,7 @@ public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 		 * @param related Action related object.
 		 * @param object Customized object for the tracked item.
 		 */
-		final void customizerRemoved(final ServiceReference<S> item,
-				final ServiceEvent related, final T object) {
+		final void customizerRemoved(final ServiceReference<S> item, final ServiceEvent related, final T object) {
 			customizer.removedService(item, object);
 		}
 	}
diff --git a/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java b/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
index b2caddc..72bec7a 100644
--- a/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
+++ b/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2012). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,34 +20,32 @@ import org.osgi.framework.ServiceReference;
 
 /**
  * The {@code ServiceTrackerCustomizer} interface allows a
- * {@code ServiceTracker} to customize the service objects that are
- * tracked. A {@code ServiceTrackerCustomizer} is called when a service is
- * being added to a {@code ServiceTracker}. The
- * {@code ServiceTrackerCustomizer} can then return an object for the
- * tracked service. A {@code ServiceTrackerCustomizer} is also called when
- * a tracked service is modified or has been removed from a
+ * {@code ServiceTracker} to customize the service objects that are tracked. A
+ * {@code ServiceTrackerCustomizer} is called when a service is being added to a
+ * {@code ServiceTracker}. The {@code ServiceTrackerCustomizer} can then return
+ * an object for the tracked service. A {@code ServiceTrackerCustomizer} is also
+ * called when a tracked service is modified or has been removed from a
  * {@code ServiceTracker}.
  * 
  * <p>
  * The methods in this interface may be called as the result of a
- * {@code ServiceEvent} being received by a {@code ServiceTracker}.
- * Since {@code ServiceEvent}s are synchronously delivered by the
- * Framework, it is highly recommended that implementations of these methods do
- * not register ({@code BundleContext.registerService}), modify (
+ * {@code ServiceEvent} being received by a {@code ServiceTracker}. Since
+ * {@code ServiceEvent}s are synchronously delivered by the Framework, it is
+ * highly recommended that implementations of these methods do not register (
+ * {@code BundleContext.registerService}), modify (
  * {@code ServiceRegistration.setProperties}) or unregister (
- * {@code ServiceRegistration.unregister}) a service while being
- * synchronized on any object.
+ * {@code ServiceRegistration.unregister}) a service while being synchronized on
+ * any object.
  * 
  * <p>
  * The {@code ServiceTracker} class is thread-safe. It does not call a
  * {@code ServiceTrackerCustomizer} while holding any locks.
- * {@code ServiceTrackerCustomizer} implementations must also be
- * thread-safe.
+ * {@code ServiceTrackerCustomizer} implementations must also be thread-safe.
  * 
  * @param <S> The type of the service being tracked.
  * @param <T> The type of the tracked object.
  * @ThreadSafe
- * @version $Id: c654a963336cee74762b8f54c8cef8d5774f8b4d $
+ * @version $Id: c14b8d47026b6bd4ba1f2db7bf7e755d00fc6f6a $
  */
 public interface ServiceTrackerCustomizer<S, T> {
 	/**
@@ -56,11 +54,10 @@ public interface ServiceTrackerCustomizer<S, T> {
 	 * <p>
 	 * This method is called before a service which matched the search
 	 * parameters of the {@code ServiceTracker} is added to the
-	 * {@code ServiceTracker}. This method should return the service object
-	 * to be tracked for the specified {@code ServiceReference}. The
-	 * returned service object is stored in the {@code ServiceTracker} and
-	 * is available from the {@code getService} and
-	 * {@code getServices} methods.
+	 * {@code ServiceTracker}. This method should return the service object to
+	 * be tracked for the specified {@code ServiceReference}. The returned
+	 * service object is stored in the {@code ServiceTracker} and is available
+	 * from the {@code getService} and {@code getServices} methods.
 	 * 
 	 * @param reference The reference to the service being added to the
 	 *        {@code ServiceTracker}.
diff --git a/src/main/resources/default.properties b/src/main/resources/default.properties
index 9d3b179..dd2f6ad 100644
--- a/src/main/resources/default.properties
+++ b/src/main/resources/default.properties
@@ -23,6 +23,8 @@
 org.osgi.framework.system.capabilities= \
  ${dollar}{eecap-${dollar}{java.specification.version}}
 
+eecap-1.8= osgi.ee; osgi.ee="OSGi/Minimum"; version:List<Version>="1.0,1.1,1.2", \
+ osgi.ee; osgi.ee="JavaSE"; version:List<Version>="1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8"
 eecap-1.7= osgi.ee; osgi.ee="OSGi/Minimum"; version:List<Version>="1.0,1.1,1.2", \
  osgi.ee; osgi.ee="JavaSE"; version:List<Version>="1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7"
 eecap-1.6= osgi.ee; osgi.ee="OSGi/Minimum"; version:List<Version>="1.0,1.1,1.2", \
@@ -40,6 +42,9 @@ eecap-1.2= osgi.ee; osgi.ee="OSGi/Minimum"; version:List<Version>="1.0,1.1", \
 org.osgi.framework.executionenvironment= \
  ${dollar}{ee-${dollar}{java.specification.version}}
 
+ee-1.8=JavaSE-1.8,JavaSE-1.7,JavaSE-1.6,J2SE-1.5,J2SE-1.4,J2SE-1.3, \
+ J2SE-1.2,JRE-1.1,JRE-1.0,OSGi/Minimum-1.2,OSGi/Minimum-1.1, \
+ OSGi/Minimum-1.0
 ee-1.7=JavaSE-1.7,JavaSE-1.6,J2SE-1.5,J2SE-1.4,J2SE-1.3, \
  J2SE-1.2,JRE-1.1,JRE-1.0,OSGi/Minimum-1.2,OSGi/Minimum-1.1, \
  OSGi/Minimum-1.0
@@ -53,18 +58,20 @@ ee-1.3=J2SE-1.3,J2SE-1.2,JRE-1.1,JRE-1.0,OSGi/Minimum-1.1,OSGi/Minimum-1.0
 ee-1.2=J2SE-1.2,JRE-1.1,JRE-1.0,OSGi/Minimum-1.1,OSGi/Minimum-1.0
 
 # Default packages exported by system bundle.
-org.osgi.framework.system.packages=org.osgi.framework; version=1.6.0, \
- org.osgi.framework.launch; version=1.0.0, \
- org.osgi.framework.wiring; version=1.0.0, \
- org.osgi.framework.startlevel; version=1.0.0, \
- org.osgi.framework.hooks.bundle; version=1.0.0, \
+org.osgi.framework.system.packages=org.osgi.framework; version=1.7.0, \
+ org.osgi.framework.hooks.bundle; version=1.1.0, \
  org.osgi.framework.hooks.resolver; version=1.0.0, \
  org.osgi.framework.hooks.service; version=1.1.0, \
  org.osgi.framework.hooks.weaving; version=1.0.0, \
+ org.osgi.framework.launch; version=1.1.0, \
+ org.osgi.framework.namespace; version=1.0.0, \
+ org.osgi.framework.startlevel; version=1.0.0, \
+ org.osgi.framework.wiring; version=1.1.0, \
+ org.osgi.resource; version=1.0.0, \
  org.osgi.service.packageadmin; version=1.2.0, \
  org.osgi.service.startlevel; version=1.1.0, \
  org.osgi.service.url; version=1.0.0, \
- org.osgi.util.tracker; version=1.5.0 \
+ org.osgi.util.tracker; version=1.5.1 \
  ${dollar}{jre-${dollar}{java.specification.version}}
 
 #
@@ -630,3 +637,158 @@ jre-1.7=, \
  org.xml.sax.ext;uses:="org.xml.sax,org.xml.sax.helpers";version="0.0.0.1_007_JavaSE", \
  org.xml.sax.helpers;uses:="org.xml.sax";version="0.0.0.1_007_JavaSE", \
  org.xml.sax;version="0.0.0.1_007_JavaSE"
+ 
+jre-1.8=, \
+ javax.accessibility;uses:="javax.swing.text";version="0.0.0.1_008_JavaSE", \
+ javax.activation;version="0.0.0.1_008_JavaSE", \
+ javax.activity;version="0.0.0.1_008_JavaSE", \
+ javax.annotation.processing;uses:="javax.tools,javax.lang.model,javax.lang.model.element,javax.lang.model.util";version="0.0.0.1_008_JavaSE", \
+ javax.annotation;version="0.0.0.1_008_JavaSE", \
+ javax.crypto.interfaces;uses:="javax.crypto.spec,javax.crypto";version="0.0.0.1_008_JavaSE", \
+ javax.crypto.spec;uses:="javax.crypto";version="0.0.0.1_008_JavaSE", \
+ javax.crypto;uses:="javax.crypto.spec";version="0.0.0.1_008_JavaSE", \
+ javax.imageio.event;uses:="javax.imageio";version="0.0.0.1_008_JavaSE", \
+ javax.imageio.metadata;uses:="org.w3c.dom,javax.imageio";version="0.0.0.1_008_JavaSE", \
+ javax.imageio.plugins.bmp;uses:="javax.imageio";version="0.0.0.1_008_JavaSE", \
+ javax.imageio.plugins.jpeg;uses:="javax.imageio";version="0.0.0.1_008_JavaSE", \
+ javax.imageio.spi;uses:="javax.imageio.stream,javax.imageio,javax.imageio.metadata";version="0.0.0.1_008_JavaSE", \
+ javax.imageio.stream;uses:="javax.imageio";version="0.0.0.1_008_JavaSE", \
+ javax.imageio;uses:="javax.imageio.metadata,javax.imageio.stream,javax.imageio.spi,javax.imageio.event";version="0.0.0.1_008_JavaSE", \
+ javax.jws.soap;version="0.0.0.1_008_JavaSE", \
+ javax.jws;version="0.0.0.1_008_JavaSE", \
+ javax.lang.model.element;uses:="javax.lang.model.type,javax.lang.model";version="0.0.0.1_008_JavaSE", \
+ javax.lang.model.type;uses:="javax.lang.model.element,javax.lang.model";version="0.0.0.1_008_JavaSE", \
+ javax.lang.model.util;uses:="javax.lang.model,javax.lang.model.element,javax.annotation.processing,javax.lang.model.type";version="0.0.0.1_008_JavaSE", \
+ javax.lang.model;version="0.0.0.1_008_JavaSE", \
+ javax.management.loading;uses:="javax.management";version="0.0.0.1_008_JavaSE", \
+ javax.management.modelmbean;uses:="javax.management,javax.management.loading";version="0.0.0.1_008_JavaSE", \
+ javax.management.monitor;uses:="javax.management";version="0.0.0.1_008_JavaSE", \
+ javax.management.openmbean;uses:="javax.management";version="0.0.0.1_008_JavaSE", \
+ javax.management.relation;uses:="javax.management";version="0.0.0.1_008_JavaSE", \
+ javax.management.remote.rmi;uses:="javax.management.remote,javax.security.auth,javax.management,javax.management.loading,javax.naming,javax.rmi.ssl,org.omg.CORBA,org.omg.CORBA_2_3.portable,org.omg.CORBA.portable,javax.rmi.CORBA,javax.rmi";version="0.0.0.1_008_JavaSE", \
+ javax.management.remote;uses:="javax.security.auth,javax.management";version="0.0.0.1_008_JavaSE", \
+ javax.management.timer;uses:="javax.management";version="0.0.0.1_008_JavaSE", \
+ javax.management;uses:="javax.management.loading,javax.management.openmbean";version="0.0.0.1_008_JavaSE", \
+ javax.naming.directory;uses:="javax.naming";version="0.0.0.1_008_JavaSE", \
+ javax.naming.event;uses:="javax.naming,javax.naming.directory";version="0.0.0.1_008_JavaSE", \
+ javax.naming.ldap;uses:="javax.naming,javax.naming.directory,javax.net.ssl,javax.naming.event";version="0.0.0.1_008_JavaSE", \
+ javax.naming.spi;uses:="javax.naming,javax.naming.directory";version="0.0.0.1_008_JavaSE", \
+ javax.naming;uses:="javax.naming.spi";version="0.0.0.1_008_JavaSE", \
+ javax.net.ssl;uses:="javax.security.cert,javax.security.auth.x500,javax.net";version="0.0.0.1_008_JavaSE", \
+ javax.net;version="0.0.0.1_008_JavaSE", \
+ javax.print.attribute.standard;uses:="javax.print.attribute";version="0.0.0.1_008_JavaSE", \
+ javax.print.attribute;version="0.0.0.1_008_JavaSE", \
+ javax.print.event;uses:="javax.print,javax.print.attribute";version="0.0.0.1_008_JavaSE", \
+ javax.print;uses:="javax.print.attribute,javax.print.event,javax.print.attribute.standard";version="0.0.0.1_008_JavaSE", \
+ javax.rmi.CORBA;uses:="org.omg.CORBA,org.omg.CORBA_2_3.portable,org.omg.CORBA.portable,org.omg.SendingContext";version="0.0.0.1_008_JavaSE", \
+ javax.rmi.ssl;uses:="javax.net,javax.net.ssl";version="0.0.0.1_008_JavaSE", \
+ javax.rmi;uses:="org.omg.CORBA,javax.rmi.CORBA";version="0.0.0.1_008_JavaSE", \
+ javax.script;version="0.0.0.1_008_JavaSE", \
+ javax.security.auth.callback;version="0.0.0.1_008_JavaSE", \
+ javax.security.auth.kerberos;uses:="javax.security.auth,javax.crypto";version="0.0.0.1_008_JavaSE", \
+ javax.security.auth.login;uses:="javax.security.auth,javax.security.auth.callback";version="0.0.0.1_008_JavaSE", \
+ javax.security.auth.spi;uses:="javax.security.auth.callback,javax.security.auth.login,javax.security.auth";version="0.0.0.1_008_JavaSE", \
+ javax.security.auth.x500;uses:="javax.security.auth";version="0.0.0.1_008_JavaSE", \
+ javax.security.auth;version="0.0.0.1_008_JavaSE", \
+ javax.security.cert;version="0.0.0.1_008_JavaSE", \
+ javax.security.sasl;uses:="javax.security.auth.callback";version="0.0.0.1_008_JavaSE", \
+ javax.sound.midi.spi;uses:="javax.sound.midi";version="0.0.0.1_008_JavaSE", \
+ javax.sound.midi;uses:="javax.sound.midi.spi";version="0.0.0.1_008_JavaSE", \
+ javax.sound.sampled.spi;uses:="javax.sound.sampled";version="0.0.0.1_008_JavaSE", \
+ javax.sound.sampled;uses:="javax.sound.sampled.spi";version="0.0.0.1_008_JavaSE", \
+ javax.sql.rowset.serial;uses:="javax.sql.rowset";version="0.0.0.1_008_JavaSE", \
+ javax.sql.rowset.spi;uses:="javax.sql,javax.naming,javax.sql.rowset";version="0.0.0.1_008_JavaSE", \
+ javax.sql.rowset;uses:="javax.sql,javax.sql.rowset.serial,javax.sql.rowset.spi";version="0.0.0.1_008_JavaSE", \
+ javax.sql;uses:="javax.transaction.xa";version="0.0.0.1_008_JavaSE", \
+ javax.swing.border;uses:="javax.swing";version="0.0.0.1_008_JavaSE", \
+ javax.swing.colorchooser;uses:="javax.swing,javax.swing.border,javax.swing.event,javax.swing.text";version="0.0.0.1_008_JavaSE", \
+ javax.swing.event;uses:="javax.swing,javax.swing.text,javax.swing.table,javax.swing.tree,javax.swing.undo";version="0.0.0.1_008_JavaSE", \
+ javax.swing.filechooser;uses:="javax.swing";version="0.0.0.1_008_JavaSE", \
+ javax.swing.plaf.basic;uses:="javax.swing.border,javax.swing,javax.swing.plaf,javax.swing.text,javax.swing.event,javax.swing.colorchooser,javax.accessibility,javax.swing.filechooser,javax.swing.text.html,javax.sound.sampled,javax.swing.table,javax.swing.plaf.synth,javax.swing.tree";version="0.0.0.1_008_JavaSE", \
+ javax.swing.plaf.metal;uses:="javax.swing.plaf,javax.swing,javax.swing.border,javax.swing.text,javax.swing.plaf.basic,javax.swing.filechooser,javax.swing.event,javax.swing.tree";version="0.0.0.1_008_JavaSE", \
+ javax.swing.plaf.multi;uses:="javax.accessibility,javax.swing,javax.swing.plaf,javax.swing.filechooser,javax.swing.text,javax.swing.tree";version="0.0.0.1_008_JavaSE", \
+ javax.swing.plaf.nimbus;uses:="javax.swing,javax.swing.plaf,javax.swing.border,javax.swing.plaf.synth";version="0.0.0.1_008_JavaSE", \
+ javax.swing.plaf.synth;uses:="javax.swing,javax.swing.plaf,javax.swing.text,javax.swing.border,javax.swing.plaf.basic,javax.swing.colorchooser,javax.swing.event,javax.xml.parsers,org.xml.sax,org.xml.sax.helpers,javax.swing.table,javax.swing.tree";version="0.0.0.1_008_JavaSE", \
+ javax.swing.plaf;uses:="javax.swing,javax.swing.border,javax.accessibility,javax.swing.filechooser,javax.swing.text,javax.swing.tree";version="0.0.0.1_008_JavaSE", \
+ javax.swing.table;uses:="javax.swing.event,javax.swing.plaf,javax.swing.border,javax.swing,javax.accessibility";version="0.0.0.1_008_JavaSE", \
+ javax.swing.text.html.parser;uses:="javax.swing.text,javax.swing.text.html";version="0.0.0.1_008_JavaSE", \
+ javax.swing.text.html;uses:="javax.swing.event,javax.swing.text,javax.accessibility,javax.swing,javax.swing.plaf,javax.swing.border,javax.swing.undo";version="0.0.0.1_008_JavaSE", \
+ javax.swing.text.rtf;uses:="javax.swing.text";version="0.0.0.1_008_JavaSE", \
+ javax.swing.text;uses:="javax.swing.event,javax.swing.tree,javax.swing.undo,javax.swing,javax.swing.plaf,javax.swing.plaf.basic,javax.print,javax.print.attribute,javax.accessibility,javax.swing.text.html";version="0.0.0.1_008_JavaSE", \
+ javax.swing.tree;uses:="javax.swing.event,javax.swing,javax.swing.border,javax.swing.plaf,javax.swing.plaf.basic";version="0.0.0.1_008_JavaSE", \
+ javax.swing.undo;uses:="javax.swing,javax.swing.event";version="0.0.0.1_008_JavaSE", \
+ javax.swing;uses:="javax.swing.event,javax.accessibility,javax.swing.text,javax.swing.plaf,javax.swing.border,javax.swing.tree,javax.swing.table,javax.swing.colorchooser,javax.swing.plaf.basic,javax.swing.text.html,javax.swing.filechooser,javax.print,javax.print.attribute,javax.swing.plaf.metal";version="0.0.0.1_008_JavaSE", \
+ javax.tools;uses:="javax.lang.model.element,javax.annotation.processing,javax.lang.model";version="0.0.0.1_008_JavaSE", \
+ javax.transaction.xa;version="0.0.0.1_008_JavaSE", \
+ javax.transaction;version="0.0.0.1_008_JavaSE", \
+ javax.xml.bind.annotation.adapters;uses:="javax.xml.bind";version="0.0.0.1_008_JavaSE", \
+ javax.xml.bind.annotation;uses:="javax.xml.transform,javax.xml.bind,javax.xml.parsers,javax.xml.transform.dom,org.w3c.dom";version="0.0.0.1_008_JavaSE", \
+ javax.xml.bind.attachment;uses:="javax.activation";version="0.0.0.1_008_JavaSE", \
+ javax.xml.bind.helpers;uses:="javax.xml.bind.annotation.adapters,javax.xml.transform.dom,org.w3c.dom,org.xml.sax,javax.xml.bind.attachment,javax.xml.stream,javax.xml.transform,javax.xml.transform.stream,javax.xml.validation,javax.xml.transform.sax,javax.xml.bind,javax.xml.parsers";version="0.0.0.1_008_JavaSE", \
+ javax.xml.bind.util;uses:="javax.xml.transform.sax,javax.xml.bind,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers";version="0.0.0.1_008_JavaSE", \
+ javax.xml.bind;uses:="javax.xml.validation,javax.xml.namespace,javax.xml.datatype,javax.xml.transform,javax.xml.bind.annotation,javax.xml.transform.stream,org.w3c.dom,javax.xml.bind.attachment,javax.xml.stream,javax.xml.bind.annotation.adapters,org.xml.sax";version="0.0.0.1_008_JavaSE", \
+ javax.xml.crypto.dom;uses:="javax.xml.crypto,org.w3c.dom";version="0.0.0.1_008_JavaSE", \
+ javax.xml.crypto.dsig.dom;uses:="javax.xml.crypto.dsig,javax.xml.crypto,org.w3c.dom,javax.xml.crypto.dom";version="0.0.0.1_008_JavaSE", \
+ javax.xml.crypto.dsig.keyinfo;uses:="javax.xml.crypto";version="0.0.0.1_008_JavaSE", \
+ javax.xml.crypto.dsig.spec;uses:="javax.xml.crypto";version="0.0.0.1_008_JavaSE", \
+ javax.xml.crypto.dsig;uses:="javax.xml.crypto,javax.xml.crypto.dsig.spec,javax.xml.crypto.dsig.keyinfo";version="0.0.0.1_008_JavaSE", \
+ javax.xml.crypto;uses:="javax.xml.crypto.dsig.keyinfo";version="0.0.0.1_008_JavaSE", \
+ javax.xml.datatype;uses:="javax.xml.namespace";version="0.0.0.1_008_JavaSE", \
+ javax.xml.namespace;version="0.0.0.1_008_JavaSE", \
+ javax.xml.parsers;uses:="javax.xml.validation,org.w3c.dom,org.xml.sax,org.xml.sax.helpers";version="0.0.0.1_008_JavaSE", \
+ javax.xml.soap;uses:="javax.activation,javax.xml.namespace,org.w3c.dom,javax.xml.transform.dom,javax.xml.transform";version="0.0.0.1_008_JavaSE", \
+ javax.xml.stream.events;uses:="javax.xml.namespace,javax.xml.stream";version="0.0.0.1_008_JavaSE", \
+ javax.xml.stream.util;uses:="javax.xml.stream,javax.xml.stream.events,javax.xml.namespace";version="0.0.0.1_008_JavaSE", \
+ javax.xml.stream;uses:="javax.xml.stream.events,javax.xml.namespace,javax.xml.stream.util,javax.xml.transform";version="0.0.0.1_008_JavaSE", \
+ javax.xml.transform.dom;uses:="javax.xml.transform,org.w3c.dom";version="0.0.0.1_008_JavaSE", \
+ javax.xml.transform.sax;uses:="org.xml.sax.ext,javax.xml.transform,org.xml.sax,javax.xml.transform.stream";version="0.0.0.1_008_JavaSE", \
+ javax.xml.transform.stax;uses:="javax.xml.stream,javax.xml.transform,javax.xml.stream.events";version="0.0.0.1_008_JavaSE", \
+ javax.xml.transform.stream;uses:="javax.xml.transform";version="0.0.0.1_008_JavaSE", \
+ javax.xml.transform;version="0.0.0.1_008_JavaSE", \
+ javax.xml.validation;uses:="org.w3c.dom.ls,javax.xml.transform,javax.xml.transform.stream,org.xml.sax,org.w3c.dom";version="0.0.0.1_008_JavaSE", \
+ javax.xml.ws.handler.soap;uses:="javax.xml.ws.handler,javax.xml.namespace,javax.xml.soap,javax.xml.bind";version="0.0.0.1_008_JavaSE", \
+ javax.xml.ws.handler;uses:="javax.xml.ws,javax.xml.namespace";version="0.0.0.1_008_JavaSE", \
+ javax.xml.ws.http;uses:="javax.xml.ws";version="0.0.0.1_008_JavaSE", \
+ javax.xml.ws.soap;uses:="javax.xml.ws.spi,javax.xml.ws,javax.xml.soap";version="0.0.0.1_008_JavaSE", \
+ javax.xml.ws.spi.http;version="0.0.0.1_008_JavaSE", \
+ javax.xml.ws.spi;uses:="javax.xml.ws,javax.xml.ws.wsaddressing,javax.xml.transform,org.w3c.dom,javax.xml.namespace,javax.xml.ws.handler,javax.xml.bind";version="0.0.0.1_008_JavaSE", \
+ javax.xml.ws.wsaddressing;uses:="javax.xml.bind.annotation,javax.xml.namespace,org.w3c.dom,javax.xml.transform,javax.xml.bind,javax.xml.ws,javax.xml.ws.spi";version="0.0.0.1_008_JavaSE", \
+ javax.xml.ws;uses:="javax.xml.ws.handler,javax.xml.ws.spi,javax.xml.ws.spi.http,javax.xml.transform,org.w3c.dom,javax.xml.bind.annotation,javax.xml.transform.stream,javax.xml.bind,javax.xml.namespace";version="0.0.0.1_008_JavaSE", \
+ javax.xml.xpath;uses:="org.xml.sax,javax.xml.namespace";version="0.0.0.1_008_JavaSE", \
+ javax.xml;version="0.0.0.1_008_JavaSE", \
+ org.ietf.jgss;version="0.0.0.1_008_JavaSE", \
+ org.omg.CORBA.DynAnyPackage;uses:="org.omg.CORBA";version="0.0.0.1_008_JavaSE", \
+ org.omg.CORBA.ORBPackage;uses:="org.omg.CORBA";version="0.0.0.1_008_JavaSE", \
+ org.omg.CORBA.TypeCodePackage;uses:="org.omg.CORBA";version="0.0.0.1_008_JavaSE", \
+ org.omg.CORBA.portable;uses:="org.omg.CORBA,org.omg.CORBA_2_3.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.CORBA;uses:="org.omg.CORBA.portable,org.omg.CORBA.DynAnyPackage,org.omg.CORBA.ORBPackage,org.omg.CORBA_2_3.portable,org.omg.CORBA.TypeCodePackage";version="0.0.0.1_008_JavaSE", \
+ org.omg.CORBA_2_3.portable;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.CORBA_2_3;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.CosNaming.NamingContextExtPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.CosNaming.NamingContextPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.CosNaming";version="0.0.0.1_008_JavaSE", \
+ org.omg.CosNaming;uses:="org.omg.CORBA.portable,org.omg.CORBA,org.omg.PortableServer,org.omg.CosNaming.NamingContextPackage,org.omg.CosNaming.NamingContextExtPackage";version="0.0.0.1_008_JavaSE", \
+ org.omg.Dynamic;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.DynamicAny.DynAnyFactoryPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.DynamicAny.DynAnyPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.DynamicAny;uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.DynamicAny.DynAnyFactoryPackage,org.omg.DynamicAny.DynAnyPackage";version="0.0.0.1_008_JavaSE", \
+ org.omg.IOP.CodecFactoryPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.IOP.CodecPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.IOP;uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.IOP.CodecFactoryPackage,org.omg.IOP.CodecPackage";version="0.0.0.1_008_JavaSE", \
+ org.omg.Messaging;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.PortableInterceptor.ORBInitInfoPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.PortableInterceptor;uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.IOP,org.omg.PortableInterceptor.ORBInitInfoPackage,org.omg.CORBA_2_3.portable,org.omg.Dynamic";version="0.0.0.1_008_JavaSE", \
+ org.omg.PortableServer.CurrentPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.PortableServer.POAManagerPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.PortableServer.POAPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.PortableServer.ServantLocatorPackage;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.PortableServer.portable;uses:="org.omg.CORBA,org.omg.PortableServer";version="0.0.0.1_008_JavaSE", \
+ org.omg.PortableServer;uses:="org.omg.CORBA,org.omg.CORBA.portable,org.omg.PortableServer.CurrentPackage,org.omg.PortableServer.POAManagerPackage,org.omg.PortableServer.POAPackage,org.omg.PortableServer.portable,org.omg.CORBA_2_3,org.omg.PortableServer.ServantLocatorPackage";version="0.0.0.1_008_JavaSE", \
+ org.omg.SendingContext;uses:="org.omg.CORBA,org.omg.CORBA.portable";version="0.0.0.1_008_JavaSE", \
+ org.omg.stub.java.rmi;uses:="javax.rmi.CORBA";version="0.0.0.1_008_JavaSE", \
+ org.w3c.dom.bootstrap;uses:="org.w3c.dom";version="0.0.0.1_008_JavaSE", \
+ org.w3c.dom.events;uses:="org.w3c.dom,org.w3c.dom.views";version="0.0.0.1_008_JavaSE", \
+ org.w3c.dom.ls;uses:="org.w3c.dom,org.w3c.dom.events,org.w3c.dom.traversal";version="0.0.0.1_008_JavaSE", \
+ org.w3c.dom;version="0.0.0.1_008_JavaSE", \
+ org.xml.sax.ext;uses:="org.xml.sax,org.xml.sax.helpers";version="0.0.0.1_008_JavaSE", \
+ org.xml.sax.helpers;uses:="org.xml.sax";version="0.0.0.1_008_JavaSE", \
+ org.xml.sax;version="0.0.0.1_008_JavaSE"
diff --git a/src/main/resources/org/osgi/framework/hooks/bundle/packageinfo b/src/main/resources/org/osgi/framework/hooks/bundle/packageinfo
index 7c8de03..3987f9c 100644
--- a/src/main/resources/org/osgi/framework/hooks/bundle/packageinfo
+++ b/src/main/resources/org/osgi/framework/hooks/bundle/packageinfo
@@ -1 +1 @@
-version 1.0
+version 1.1
diff --git a/src/main/resources/org/osgi/framework/launch/packageinfo b/src/main/resources/org/osgi/framework/launch/packageinfo
index 7c8de03..3987f9c 100644
--- a/src/main/resources/org/osgi/framework/launch/packageinfo
+++ b/src/main/resources/org/osgi/framework/launch/packageinfo
@@ -1 +1 @@
-version 1.0
+version 1.1
diff --git a/src/main/resources/org/osgi/framework/hooks/bundle/packageinfo b/src/main/resources/org/osgi/framework/namespace/packageinfo
similarity index 100%
copy from src/main/resources/org/osgi/framework/hooks/bundle/packageinfo
copy to src/main/resources/org/osgi/framework/namespace/packageinfo
diff --git a/src/main/resources/org/osgi/framework/packageinfo b/src/main/resources/org/osgi/framework/packageinfo
index fec6063..5d21e63 100644
--- a/src/main/resources/org/osgi/framework/packageinfo
+++ b/src/main/resources/org/osgi/framework/packageinfo
@@ -1 +1 @@
-version 1.6
+version 1.7
diff --git a/src/main/resources/org/osgi/framework/wiring/packageinfo b/src/main/resources/org/osgi/framework/wiring/packageinfo
index 7c8de03..3987f9c 100644
--- a/src/main/resources/org/osgi/framework/wiring/packageinfo
+++ b/src/main/resources/org/osgi/framework/wiring/packageinfo
@@ -1 +1 @@
-version 1.0
+version 1.1
diff --git a/src/main/resources/org/osgi/framework/hooks/bundle/packageinfo b/src/main/resources/org/osgi/resource/packageinfo
similarity index 100%
copy from src/main/resources/org/osgi/framework/hooks/bundle/packageinfo
copy to src/main/resources/org/osgi/resource/packageinfo
diff --git a/src/main/resources/org/osgi/util/tracker/packageinfo b/src/main/resources/org/osgi/util/tracker/packageinfo
index ccee95e..1213efd 100644
--- a/src/main/resources/org/osgi/util/tracker/packageinfo
+++ b/src/main/resources/org/osgi/util/tracker/packageinfo
@@ -1 +1 @@
-version 1.5
+version 1.5.1
diff --git a/src/test/java/org/apache/felix/framework/CollisionHookTest.java b/src/test/java/org/apache/felix/framework/CollisionHookTest.java
new file mode 100644
index 0000000..31eafd0
--- /dev/null
+++ b/src/test/java/org/apache/felix/framework/CollisionHookTest.java
@@ -0,0 +1,297 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.felix.framework.cache.BundleArchive;
+import org.apache.felix.framework.cache.BundleArchiveRevision;
+import org.mockito.Mockito;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.framework.hooks.bundle.CollisionHook;
+
+public class CollisionHookTest extends TestCase
+{
+    public void testCollisionHookInstall() throws Exception
+    {
+        BundleImpl identicalBundle = mockBundleImpl(1L, "foo", "1.2.1.a");
+        BundleImpl differentBundle = mockBundleImpl(2L, "bar", "1.2.1.a");
+        BundleImpl originatingBundle = mockBundleImpl(4L, "xyz", "1.0.0");
+
+        CollisionHook testCollisionHook = new CollisionHook()
+        {
+            public void filterCollisions(int operationType, Bundle target, Collection<Bundle> collisionCandidates)
+            {
+                if ((target.getBundleId() == 4L) && (operationType == CollisionHook.INSTALLING))
+                {
+                    collisionCandidates.clear();
+                }
+            }
+        };
+
+        @SuppressWarnings("unchecked")
+        ServiceReference<CollisionHook> chRef = Mockito.mock(ServiceReference.class);
+
+        // Mock the framework
+        StatefulResolver mockResolver = Mockito.mock(StatefulResolver.class);
+        Felix felixMock = Mockito.mock(Felix.class);
+        Mockito.when(felixMock.getHooks(CollisionHook.class)).thenReturn(Collections.singleton(chRef));
+        Mockito.when(felixMock.getResolver()).thenReturn(mockResolver);
+        Mockito.when(felixMock.getBundles()).thenReturn(new Bundle[]
+        {
+            differentBundle, identicalBundle
+        });
+        Mockito.when(felixMock.getService(felixMock, chRef)).thenReturn(testCollisionHook);
+
+        // Mock the archive of the bundle being installed
+        Map<String, String> headerMap = new HashMap<String, String>();
+        headerMap.put(Constants.BUNDLE_SYMBOLICNAME, "foo");
+        headerMap.put(Constants.BUNDLE_VERSION, "1.2.1.a");
+        headerMap.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+
+        BundleArchiveRevision archiveRevision = Mockito.mock(BundleArchiveRevision.class);
+        Mockito.when(archiveRevision.getManifestHeader()).thenReturn(headerMap);
+
+        BundleArchive archive = Mockito.mock(BundleArchive.class);
+        Mockito.when(archive.getCurrentRevision()).thenReturn(archiveRevision);
+        Mockito.when(archive.getId()).thenReturn(3L);
+
+        BundleImpl bi = new BundleImpl(felixMock, originatingBundle, archive);
+        assertEquals(3L, bi.getBundleId());
+
+        // Do the revise operation.
+        try
+        {
+            bi.revise(null, null);
+            fail("Should have thrown a BundleException because the installed bundle is not unique");
+        }
+        catch (BundleException be)
+        {
+            // good
+            assertTrue(be.getMessage().contains("not unique"));
+        }
+    }
+
+    public void testCollisionHookUpdate() throws Exception
+    {
+        BundleImpl identicalBundle = mockBundleImpl(1L, "foo", "1.2.1.a");
+        BundleImpl differentBundle = mockBundleImpl(2L, "foo", "1.2.1");
+
+        CollisionHook testCollisionHook = new CollisionHook()
+        {
+            public void filterCollisions(int operationType, Bundle target, Collection<Bundle> collisionCandidates)
+            {
+                if ((target.getBundleId() == 3L) && (operationType == CollisionHook.UPDATING))
+                {
+                    collisionCandidates.clear();
+                }
+            }
+        };
+
+        @SuppressWarnings("unchecked")
+        ServiceReference<CollisionHook> chRef = Mockito.mock(ServiceReference.class);
+
+        Map<String, String> config = new HashMap<String, String>();
+        config.put(Constants.FRAMEWORK_BSNVERSION, Constants.FRAMEWORK_BSNVERSION_MANAGED);
+
+        // Mock the framework
+        StatefulResolver mockResolver = Mockito.mock(StatefulResolver.class);
+        Felix felixMock = Mockito.mock(Felix.class);
+        Mockito.when(felixMock.getConfig()).thenReturn(config);
+        Mockito.when(felixMock.getHooks(CollisionHook.class)).thenReturn(Collections.singleton(chRef));
+        Mockito.when(felixMock.getResolver()).thenReturn(mockResolver);
+        Mockito.when(felixMock.getBundles()).thenReturn(new Bundle[]
+        {
+            differentBundle, identicalBundle
+        });
+        Mockito.when(felixMock.getService(felixMock, chRef)).thenReturn(testCollisionHook);
+
+        // Mock the archive of the bundle being installed
+        Map<String, String> headerMap = new HashMap<String, String>();
+        headerMap.put(Constants.BUNDLE_SYMBOLICNAME, "zar");
+        headerMap.put(Constants.BUNDLE_VERSION, "1.2.1.a");
+        headerMap.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+
+        BundleArchiveRevision archiveRevision = Mockito.mock(BundleArchiveRevision.class);
+        Mockito.when(archiveRevision.getManifestHeader()).thenReturn(headerMap);
+
+        BundleArchive archive = Mockito.mock(BundleArchive.class);
+        Mockito.when(archive.getCurrentRevision()).thenReturn(archiveRevision);
+        Mockito.when(archive.getId()).thenReturn(3L);
+
+        BundleImpl bi = new BundleImpl(felixMock, null, archive);
+        assertEquals("zar", bi.getSymbolicName());
+
+        // Do the revise operation, change the bsn to foo
+        headerMap.put(Constants.BUNDLE_SYMBOLICNAME, "foo");
+        bi.revise(null, null);
+        assertEquals("foo", bi.getSymbolicName());
+    }
+
+    public void testCollisionNotEnabled() throws Exception
+    {
+        BundleImpl identicalBundle = mockBundleImpl(1L, "foo", "1.2.1.a");
+        BundleImpl differentBundle = mockBundleImpl(2L, "bar", "1.2.1.a");
+
+        CollisionHook testCollisionHook = new CollisionHook()
+        {
+            public void filterCollisions(int operationType, Bundle target, Collection<Bundle> collisionCandidates)
+            {
+                if ((target.getBundleId() == 3L) && (operationType == CollisionHook.INSTALLING))
+                {
+                    collisionCandidates.clear();
+                }
+            }
+        };
+
+        @SuppressWarnings("unchecked")
+        ServiceReference<CollisionHook> chRef = Mockito.mock(ServiceReference.class);
+
+        Map<String, String> config = new HashMap<String, String>();
+        config.put(Constants.FRAMEWORK_BSNVERSION, Constants.FRAMEWORK_BSNVERSION_SINGLE);
+
+        // Mock the framework
+        StatefulResolver mockResolver = Mockito.mock(StatefulResolver.class);
+        Felix felixMock = Mockito.mock(Felix.class);
+        Mockito.when(felixMock.getConfig()).thenReturn(config);
+        Mockito.when(felixMock.getHooks(CollisionHook.class)).thenReturn(Collections.singleton(chRef));
+        Mockito.when(felixMock.getResolver()).thenReturn(mockResolver);
+        Mockito.when(felixMock.getBundles()).thenReturn(new Bundle[]
+        {
+            differentBundle, identicalBundle
+        });
+        Mockito.when(felixMock.getService(felixMock, chRef)).thenReturn(testCollisionHook);
+
+        // Mock the archive of the bundle being installed
+        Map<String, String> headerMap = new HashMap<String, String>();
+        headerMap.put(Constants.BUNDLE_SYMBOLICNAME, "foo");
+        headerMap.put(Constants.BUNDLE_VERSION, "1.2.1.a");
+        headerMap.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+
+        BundleArchiveRevision archiveRevision = Mockito.mock(BundleArchiveRevision.class);
+        Mockito.when(archiveRevision.getManifestHeader()).thenReturn(headerMap);
+
+        BundleArchive archive = Mockito.mock(BundleArchive.class);
+        Mockito.when(archive.getCurrentRevision()).thenReturn(archiveRevision);
+        Mockito.when(archive.getId()).thenReturn(3L);
+
+        try
+        {
+            new BundleImpl(felixMock, null, archive);
+            fail("Should have thrown a BundleException because the collision hook is not enabled");
+        }
+        catch (BundleException be)
+        {
+            // good
+            assertTrue(be.getMessage().contains("not unique"));
+        }
+    }
+
+    public void testAllowMultiple() throws Exception
+    {
+        BundleImpl identicalBundle = mockBundleImpl(1L, "foo", "1.2.1.a");
+        BundleImpl differentBundle = mockBundleImpl(2L, "bar", "1.2.1.a");
+
+        Map<String, String> config = new HashMap<String, String>();
+        config.put(Constants.FRAMEWORK_BSNVERSION, Constants.FRAMEWORK_BSNVERSION_MULTIPLE);
+
+        // Mock the framework
+        StatefulResolver mockResolver = Mockito.mock(StatefulResolver.class);
+        Felix felixMock = Mockito.mock(Felix.class);
+        Mockito.when(felixMock.getConfig()).thenReturn(config);
+        Mockito.when(felixMock.getResolver()).thenReturn(mockResolver);
+        Mockito.when(felixMock.getBundles()).thenReturn(new Bundle[]
+        {
+            differentBundle, identicalBundle
+        });
+
+        // Mock the archive of the bundle being installed
+        Map<String, String> headerMap = new HashMap<String, String>();
+        headerMap.put(Constants.BUNDLE_SYMBOLICNAME, "foo");
+        headerMap.put(Constants.BUNDLE_VERSION, "1.2.1.a");
+        headerMap.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+
+        BundleArchiveRevision archiveRevision = Mockito.mock(BundleArchiveRevision.class);
+        Mockito.when(archiveRevision.getManifestHeader()).thenReturn(headerMap);
+
+        BundleArchive archive = Mockito.mock(BundleArchive.class);
+        Mockito.when(archive.getCurrentRevision()).thenReturn(archiveRevision);
+        Mockito.when(archive.getId()).thenReturn(3L);
+
+        BundleImpl bi = new BundleImpl(felixMock, null, archive);
+        assertEquals(3L, bi.getBundleId());
+    }
+
+    public void testNoCollisionHook() throws Exception
+    {
+        BundleImpl identicalBundle = mockBundleImpl(1L, "foo", "1.2.1.a");
+        BundleImpl differentBundle = mockBundleImpl(2L, "bar", "1.2.1.a");
+
+        // Mock the framework
+        StatefulResolver mockResolver = Mockito.mock(StatefulResolver.class);
+        Felix felixMock = Mockito.mock(Felix.class);
+        Mockito.when(felixMock.getResolver()).thenReturn(mockResolver);
+        Mockito.when(felixMock.getBundles()).thenReturn(new Bundle[]
+        {
+            differentBundle, identicalBundle
+        });
+
+        // Mock the archive of the bundle being installed
+        Map<String, String> headerMap = new HashMap<String, String>();
+        headerMap.put(Constants.BUNDLE_SYMBOLICNAME, "foo");
+        headerMap.put(Constants.BUNDLE_VERSION, "1.2.1.a");
+        headerMap.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+
+        BundleArchiveRevision archiveRevision = Mockito.mock(BundleArchiveRevision.class);
+        Mockito.when(archiveRevision.getManifestHeader()).thenReturn(headerMap);
+
+        BundleArchive archive = Mockito.mock(BundleArchive.class);
+        Mockito.when(archive.getCurrentRevision()).thenReturn(archiveRevision);
+        Mockito.when(archive.getId()).thenReturn(3L);
+
+        try
+        {
+            new BundleImpl(felixMock, null, archive);
+            fail("Should have thrown a BundleException because the installed bundle is not unique");
+        }
+        catch (BundleException be)
+        {
+            // good
+            assertTrue(be.getMessage().contains("not unique"));
+        }
+    }
+
+    private BundleImpl mockBundleImpl(long id, String bsn, String version)
+    {
+        BundleImpl identicalBundle = Mockito.mock(BundleImpl.class);
+        Mockito.when(identicalBundle.getSymbolicName()).thenReturn(bsn);
+        Mockito.when(identicalBundle.getVersion()).thenReturn(Version.parseVersion(version));
+        Mockito.when(identicalBundle.getBundleId()).thenReturn(id);
+        return identicalBundle;
+    }
+}
diff --git a/src/test/java/org/apache/felix/framework/RequirementsCapabilitiesTest.java b/src/test/java/org/apache/felix/framework/RequirementsCapabilitiesTest.java
new file mode 100644
index 0000000..8cc34e6
--- /dev/null
+++ b/src/test/java/org/apache/felix/framework/RequirementsCapabilitiesTest.java
@@ -0,0 +1,267 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import junit.framework.TestCase;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+
+public class RequirementsCapabilitiesTest extends TestCase
+{
+    private File tempDir;
+    private Framework felix;
+    private File cacheDir;
+
+    @Override
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        tempDir = File.createTempFile("felix-temp", ".dir");
+        assertTrue("precondition", tempDir.delete());
+        assertTrue("precondition", tempDir.mkdirs());
+
+        cacheDir = new File(tempDir, "felix-cache");
+        assertTrue("precondition", cacheDir.mkdir());
+
+        String cache = cacheDir.getPath();
+
+        Map<String,String> params = new HashMap<String, String>();
+        params.put("felix.cache.profiledir", cache);
+        params.put("felix.cache.dir", cache);
+        params.put(Constants.FRAMEWORK_STORAGE, cache);
+
+        felix = new Felix(params);
+        felix.init();
+        felix.start();
+    }
+
+    @Override
+    protected void tearDown() throws Exception
+    {
+        super.tearDown();
+
+        felix.stop(); // Note that this method is async
+        felix = null;
+
+        deleteDir(tempDir);
+        tempDir = null;
+        cacheDir = null;
+    }
+
+    public void testIdentityCapabilityBundleFragment() throws Exception
+    {
+        String bmf = "Bundle-SymbolicName: cap.bundle\n"
+                + "Bundle-Version: 1.2.3.Blah\n"
+                + "Bundle-ManifestVersion: 2\n"
+                + "Import-Package: org.osgi.framework\n";
+        File bundleFile = createBundle(bmf);
+
+        String fmf = "Bundle-SymbolicName: cap.frag\n"
+                + "Bundle-Version: 1.0.0\n"
+                + "Fragment-Host: cap.bundle\n"
+                + "Bundle-ManifestVersion: 2\n"
+                + "Export-Package: org.foo.bar;version=\"2.0.0\"\n"
+                + "Import-Package: org.osgi.util.tracker\n";
+        File fragFile = createBundle(fmf);
+
+        Bundle b = felix.getBundleContext().installBundle(bundleFile.toURI().toASCIIString());
+        Bundle f = felix.getBundleContext().installBundle(fragFile.toURI().toASCIIString());
+
+        // Check the bundle capabilities.
+        // First check the capabilities on the Bundle Revision, which is available on installed bundles
+        BundleRevision bbr = b.adapt(BundleRevision.class);
+        List<Capability> bwbCaps = bbr.getCapabilities("osgi.wiring.bundle");
+        assertEquals(1, bwbCaps.size());
+
+        Map<String, Object> expectedBWBAttrs = new HashMap<String, Object>();
+        expectedBWBAttrs.put("osgi.wiring.bundle", "cap.bundle");
+        expectedBWBAttrs.put("bundle-version", Version.parseVersion("1.2.3.Blah"));
+        Capability expectedBWBCap = new TestCapability("osgi.wiring.bundle",
+                expectedBWBAttrs, Collections.<String, String>emptyMap());
+        assertCapsEquals(expectedBWBCap, bwbCaps.get(0));
+
+        List<Capability> bwhCaps = bbr.getCapabilities("osgi.wiring.host");
+        assertEquals(1, bwhCaps.size());
+
+        Map<String, Object> expectedBWHAttrs = new HashMap<String, Object>();
+        expectedBWHAttrs.put("osgi.wiring.host", "cap.bundle");
+        expectedBWHAttrs.put("bundle-version", Version.parseVersion("1.2.3.Blah"));
+        Capability expectedBWHCap = new TestCapability("osgi.wiring.host",
+                expectedBWHAttrs, Collections.<String, String>emptyMap());
+        assertCapsEquals(expectedBWHCap, bwhCaps.get(0));
+
+        List<Capability> bwiCaps = bbr.getCapabilities("osgi.identity");
+        assertEquals(1, bwiCaps.size());
+
+        Map<String, Object> expectedBWIAttrs = new HashMap<String, Object>();
+        expectedBWIAttrs.put("osgi.identity", "cap.bundle");
+        expectedBWIAttrs.put("type", "osgi.bundle");
+        expectedBWIAttrs.put("version", Version.parseVersion("1.2.3.Blah"));
+        Capability expectedBWICap = new TestCapability("osgi.identity",
+                expectedBWIAttrs, Collections.<String, String>emptyMap());
+        assertCapsEquals(expectedBWICap, bwiCaps.get(0));
+
+        assertEquals("The Bundle should not directly expose osgi.wiring.package",
+                0, bbr.getCapabilities("osgi.wiring.package").size());
+
+        // Check the fragment's capabilities.
+        // First check the capabilities on the Bundle Revision, which is available on installed fragments
+        BundleRevision fbr = f.adapt(BundleRevision.class);
+        List<Capability> fwpCaps = fbr.getCapabilities("osgi.wiring.package");
+        assertEquals(1, fwpCaps.size());
+
+        Map<String, Object> expectedFWAttrs = new HashMap<String, Object>();
+        expectedFWAttrs.put("osgi.wiring.package", "org.foo.bar");
+        expectedFWAttrs.put("version", Version.parseVersion("2"));
+        expectedFWAttrs.put("bundle-symbolic-name", "cap.frag");
+        expectedFWAttrs.put("bundle-version", Version.parseVersion("1.0.0"));
+        Capability expectedFWCap = new TestCapability("osgi.wiring.package",
+                expectedFWAttrs, Collections.<String, String>emptyMap());
+        assertCapsEquals(expectedFWCap, fwpCaps.get(0));
+
+        List<Capability> fiCaps = fbr.getCapabilities("osgi.identity");
+        assertEquals(1, fiCaps.size());
+        Map<String, Object> expectedFIAttrs = new HashMap<String, Object>();
+        expectedFIAttrs.put("osgi.identity", "cap.frag");
+        expectedFIAttrs.put("type", "osgi.fragment");
+        expectedFIAttrs.put("version", Version.parseVersion("1.0.0"));
+        Capability expectedFICap = new TestCapability("osgi.identity",
+                expectedFIAttrs, Collections.<String, String>emptyMap());
+        assertCapsEquals(expectedFICap, fiCaps.get(0));
+
+        // Start the bundle. This will make the BundleWiring available on both the bundle and the fragment
+        b.start();
+
+        // Check the Bundle Wiring on the fragment. It should only contain the osgi.identity capability
+        // All the other capabilities should have migrated to the bundle's BundleWiring.
+        BundleWiring fbw = f.adapt(BundleWiring.class);
+        List<BundleCapability> fbwCaps = fbw.getCapabilities(null);
+        assertEquals("Fragment should only have 1 capability: it's osgi.identity", 1, fbwCaps.size());
+        assertCapsEquals(expectedFICap, fbwCaps.get(0));
+
+        // Check the Bundle Wiring on the bundle. It should contain all the capabilities originally on the
+        // bundle and also contain the osgi.wiring.package capability from the fragment.
+        BundleWiring bbw = b.adapt(BundleWiring.class);
+        List<BundleCapability> bwbCaps2 = bbw.getCapabilities("osgi.wiring.bundle");
+        assertEquals(1, bwbCaps2.size());
+        assertCapsEquals(expectedBWBCap, bwbCaps2.get(0));
+        List<BundleCapability> bwhCaps2 = bbw.getCapabilities("osgi.wiring.host");
+        assertEquals(1, bwhCaps2.size());
+        assertCapsEquals(expectedBWHCap, bwhCaps2.get(0));
+        List<BundleCapability> bwiCaps2 = bbw.getCapabilities("osgi.identity");
+        assertEquals(1, bwiCaps2.size());
+        assertCapsEquals(expectedBWICap, bwiCaps2.get(0));
+        List<BundleCapability> bwpCaps2 = bbw.getCapabilities("osgi.wiring.package");
+        assertEquals("Bundle should have inherited the osgi.wiring.package capability from the fragment",
+                1, bwpCaps2.size());
+        assertCapsEquals(expectedFWCap, bwpCaps2.get(0));
+    }
+
+    private File createBundle(String manifest) throws IOException
+    {
+        File f = File.createTempFile("felix-bundle", ".jar", tempDir);
+
+        Manifest mf = new Manifest(new ByteArrayInputStream(manifest.getBytes("utf-8")));
+        mf.getMainAttributes().putValue("Manifest-Version", "1.0");
+        JarOutputStream os = new JarOutputStream(new FileOutputStream(f), mf);
+        os.close();
+        return f;
+    }
+
+    private static void assertCapsEquals(Capability expected, Capability actual)
+    {
+        assertEquals(expected.getNamespace(), actual.getNamespace());
+        assertSubMap(expected.getAttributes(), actual.getAttributes());
+        assertSubMap(expected.getDirectives(), actual.getDirectives());
+        // We ignore the resource in the comparison
+    }
+
+    private static void assertSubMap(Map<?,?> subMap, Map<?,?> fullMap)
+    {
+        for (Map.Entry<?,?> entry : subMap.entrySet())
+        {
+            assertEquals(entry.getValue(), fullMap.get(entry.getKey()));
+        }
+    }
+
+    private static void deleteDir(File root) throws IOException
+    {
+        if (root.isDirectory())
+        {
+            for (File file : root.listFiles())
+            {
+                deleteDir(file);
+            }
+        }
+        assertTrue(root.delete());
+    }
+
+    static class TestCapability implements Capability
+    {
+        private final String namespace;
+        private final Map<String, Object> attributes;
+        private final Map<String, String> directives;
+
+        TestCapability(String ns, Map<String,Object> attrs, Map<String,String> dirs)
+        {
+            namespace = ns;
+            attributes = attrs;
+            directives = dirs;
+        }
+
+        public String getNamespace()
+        {
+            return namespace;
+        }
+
+        public Map<String, Object> getAttributes()
+        {
+            return attributes;
+        }
+
+        public Map<String, String> getDirectives()
+        {
+            return directives;
+        }
+
+        public Resource getResource()
+        {
+            return null;
+        }
+    }
+}
diff --git a/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java b/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
index c8c8a9e..6f3b92f 100644
--- a/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
+++ b/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
@@ -42,6 +42,11 @@ public class ServiceRegistryTest extends TestCase
         Bundle b = (Bundle) control.getMock();
         control.replay();
 
+        MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+        BundleContext c = (BundleContext) controlContext.getMock();
+        controlContext.expectAndReturn(c.getBundle(), b);
+        controlContext.replay();
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
         EventHook hook = new EventHook()
         {
@@ -53,7 +58,7 @@ public class ServiceRegistryTest extends TestCase
         assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
-        ServiceRegistration reg = sr.registerService(b, new String [] {EventHook.class.getName()}, hook, new Hashtable());
+        ServiceRegistration reg = sr.registerService(c, new String [] {EventHook.class.getName()}, hook, new Hashtable());
         assertEquals(1, sr.getHooks(EventHook.class).size());
         assertTrue(sr.getHooks(EventHook.class).iterator().next() instanceof ServiceReference);
         assertSame(reg.getReference(), sr.getHooks(EventHook.class).iterator().next());
@@ -73,6 +78,11 @@ public class ServiceRegistryTest extends TestCase
         Bundle b = (Bundle) control.getMock();
         control.replay();
 
+        MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+        BundleContext c = (BundleContext) controlContext.getMock();
+        controlContext.expectAndReturn(c.getBundle(), b);
+        controlContext.replay();
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
         MockControl sfControl = MockControl.createNiceControl(ServiceFactory.class);
         sfControl.replay();
@@ -81,7 +91,7 @@ public class ServiceRegistryTest extends TestCase
         assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
-        ServiceRegistration reg = sr.registerService(b, new String [] {EventHook.class.getName()}, sf, new Hashtable());
+        ServiceRegistration reg = sr.registerService(c, new String [] {EventHook.class.getName()}, sf, new Hashtable());
         assertEquals(1, sr.getHooks(EventHook.class).size());
         assertSame(reg.getReference(), sr.getHooks(EventHook.class).iterator().next());
         assertSame(sf, ((ServiceRegistrationImpl) reg).getService());
@@ -100,6 +110,11 @@ public class ServiceRegistryTest extends TestCase
         Bundle b = (Bundle) control.getMock();
         control.replay();
 
+        MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+        BundleContext c = (BundleContext) controlContext.getMock();
+        controlContext.expectAndReturn(c.getBundle(), b);
+        controlContext.replay();
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
         FindHook hook = new FindHook()
         {
@@ -112,7 +127,7 @@ public class ServiceRegistryTest extends TestCase
         assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
-        ServiceRegistration reg = sr.registerService(b, new String [] {FindHook.class.getName()}, hook, new Hashtable());
+        ServiceRegistration reg = sr.registerService(c, new String [] {FindHook.class.getName()}, hook, new Hashtable());
         assertEquals(1, sr.getHooks(FindHook.class).size());
         assertSame(reg.getReference(), sr.getHooks(FindHook.class).iterator().next());
         assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
@@ -131,6 +146,11 @@ public class ServiceRegistryTest extends TestCase
         Bundle b = (Bundle) control.getMock();
         control.replay();
 
+        MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+        BundleContext c = (BundleContext) controlContext.getMock();
+        controlContext.expectAndReturn(c.getBundle(), b);
+        controlContext.replay();
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
         MockControl sfControl = MockControl.createNiceControl(ServiceFactory.class);
         sfControl.replay();
@@ -139,7 +159,7 @@ public class ServiceRegistryTest extends TestCase
         assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
-        ServiceRegistration reg = sr.registerService(b, new String [] {FindHook.class.getName()}, sf, new Hashtable());
+        ServiceRegistration reg = sr.registerService(c, new String [] {FindHook.class.getName()}, sf, new Hashtable());
         assertEquals(1, sr.getHooks(FindHook.class).size());
         assertSame(reg.getReference(), sr.getHooks(FindHook.class).iterator().next());
         assertSame(sf, ((ServiceRegistrationImpl) reg).getService());
@@ -158,6 +178,11 @@ public class ServiceRegistryTest extends TestCase
         Bundle b = (Bundle) control.getMock();
         control.replay();
 
+        MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+        BundleContext c = (BundleContext) controlContext.getMock();
+        controlContext.expectAndReturn(c.getBundle(), b);
+        controlContext.replay();
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
         ListenerHook hook = new ListenerHook()
         {
@@ -173,7 +198,7 @@ public class ServiceRegistryTest extends TestCase
         assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
-        ServiceRegistration reg = sr.registerService(b, new String [] {ListenerHook.class.getName()}, hook, new Hashtable());
+        ServiceRegistration reg = sr.registerService(c, new String [] {ListenerHook.class.getName()}, hook, new Hashtable());
         assertEquals(1, sr.getHooks(ListenerHook.class).size());
         assertSame(reg.getReference(), sr.getHooks(ListenerHook.class).iterator().next());
         assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
@@ -192,6 +217,11 @@ public class ServiceRegistryTest extends TestCase
         Bundle b = (Bundle) control.getMock();
         control.replay();
 
+        MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+        BundleContext c = (BundleContext) controlContext.getMock();
+        controlContext.expectAndReturn(c.getBundle(), b);
+        controlContext.replay();
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
         MockControl sfControl = MockControl.createNiceControl(ServiceFactory.class);
         sfControl.replay();
@@ -200,7 +230,7 @@ public class ServiceRegistryTest extends TestCase
         assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
-        ServiceRegistration reg = sr.registerService(b, new String [] {ListenerHook.class.getName()}, sf, new Hashtable());
+        ServiceRegistration reg = sr.registerService(c, new String [] {ListenerHook.class.getName()}, sf, new Hashtable());
         assertEquals(1, sr.getHooks(ListenerHook.class).size());
         assertSame(reg.getReference(), sr.getHooks(ListenerHook.class).iterator().next());
         assertSame(sf, ((ServiceRegistrationImpl) reg).getService());
@@ -219,6 +249,11 @@ public class ServiceRegistryTest extends TestCase
         Bundle b = (Bundle) control.getMock();
         control.replay();
 
+        MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+        BundleContext c = (BundleContext) controlContext.getMock();
+        controlContext.expectAndReturn(c.getBundle(), b);
+        controlContext.replay();
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
         class CombinedService implements ListenerHook, FindHook, EventHook, Runnable
         {
@@ -249,7 +284,7 @@ public class ServiceRegistryTest extends TestCase
         assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
-        ServiceRegistration reg = sr.registerService(b, new String [] {
+        ServiceRegistration reg = sr.registerService(c, new String [] {
             Runnable.class.getName(),
             ListenerHook.class.getName(),
             FindHook.class.getName(),
@@ -276,12 +311,17 @@ public class ServiceRegistryTest extends TestCase
         Bundle b = (Bundle) control.getMock();
         control.replay();
 
+        MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+        BundleContext c = (BundleContext) controlContext.getMock();
+        controlContext.expectAndReturn(c.getBundle(), b);
+        controlContext.replay();
+
         ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
         String svcObj = "hello";
         assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
         assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
-        ServiceRegistration reg = sr.registerService(b, new String [] {String.class.getName()}, svcObj, new Hashtable());
+        ServiceRegistration reg = sr.registerService(c, new String [] {String.class.getName()}, svcObj, new Hashtable());
         assertEquals("Postcondition failed", 0, sr.getHooks(EventHook.class).size());
         assertEquals("Postcondition failed", 0, sr.getHooks(FindHook.class).size());
         assertEquals("Postcondition failed", 0, sr.getHooks(ListenerHook.class).size());
diff --git a/src/test/java/org/apache/felix/framework/StartStopBundleTest.java b/src/test/java/org/apache/felix/framework/StartStopBundleTest.java
index af50734..315606c 100644
--- a/src/test/java/org/apache/felix/framework/StartStopBundleTest.java
+++ b/src/test/java/org/apache/felix/framework/StartStopBundleTest.java
@@ -25,12 +25,12 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.concurrent.CountDownLatch;
 import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
 import java.util.zip.ZipEntry;
 
 import junit.framework.TestCase;
+
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
@@ -41,7 +41,6 @@ import org.osgi.framework.launch.Framework;
 public class StartStopBundleTest extends TestCase
 {
     public static final int DELAY = 1000;
-    private File cacheDir;
 
     public void testStartStopBundle() throws Exception
     {
@@ -52,7 +51,7 @@ public class StartStopBundleTest extends TestCase
             + "org.osgi.service.startlevel; version=1.1.0,"
             + "org.osgi.util.tracker; version=1.3.3,"
             + "org.osgi.service.url; version=1.0.0");
-        cacheDir = File.createTempFile("felix-cache", ".dir");
+        File cacheDir = File.createTempFile("felix-cache", ".dir");
         cacheDir.delete();
         cacheDir.mkdirs();
         String cache = cacheDir.getPath();
@@ -64,66 +63,69 @@ public class StartStopBundleTest extends TestCase
             + "Bundle-Version: 1.1.0\n"
             + "Bundle-ManifestVersion: 2\n"
             + "Import-Package: org.osgi.framework\n";
-        File bundleFile = createBundle(mf);
+        File bundleFile = createBundle(mf, cacheDir);
 
         Framework f = new Felix(params);
         f.init();
         f.start();
 
-        final Bundle bundle = f.getBundleContext().installBundle(bundleFile.toURI().toString());
-        final CountDownLatch latch = new CountDownLatch(1);
+        try {
+            final Bundle bundle = f.getBundleContext().installBundle(bundleFile.toURI().toString());
 
-        new Thread()
-        {
-            public void run()
+            new Thread()
             {
-                try
-                {
-                    bundle.start();
-                }
-                catch (BundleException e)
+                public void run()
                 {
-                    e.printStackTrace();
+                    try
+                    {
+                        bundle.start();
+                    }
+                    catch (BundleException e)
+                    {
+                        e.printStackTrace();
+                    }
                 }
-            }
-        }.start();
-        Thread.sleep(DELAY / 4);
-        long t0 = System.currentTimeMillis();
-        bundle.stop();
-        long t1 = System.currentTimeMillis();
+            }.start();
+            Thread.sleep(DELAY / 4);
+            long t0 = System.currentTimeMillis();
+            bundle.stop();
+            long t1 = System.currentTimeMillis();
 
-        assertEquals(Bundle.RESOLVED, bundle.getState());
-        assertTrue((t1 - t0) > DELAY / 2);
+            assertEquals(Bundle.RESOLVED, bundle.getState());
+            assertTrue((t1 - t0) > DELAY / 2);
 
-        bundle.start();
+            bundle.start();
 
-        new Thread()
-        {
-            public void run()
+            new Thread()
             {
-                try
-                {
-                    bundle.stop();
-                }
-                catch (BundleException e)
+                public void run()
                 {
-                    e.printStackTrace();
+                    try
+                    {
+                        bundle.stop();
+                    }
+                    catch (BundleException e)
+                    {
+                        e.printStackTrace();
+                    }
                 }
-            }
-        }.start();
-        Thread.sleep(DELAY / 4);
-        t0 = System.currentTimeMillis();
-        bundle.start();
-        t1 = System.currentTimeMillis();
-
-        assertEquals(Bundle.ACTIVE, bundle.getState());
-        assertTrue((t1 - t0) > DELAY / 2);
+            }.start();
+            Thread.sleep(DELAY / 4);
+            t0 = System.currentTimeMillis();
+            bundle.start();
+            t1 = System.currentTimeMillis();
+
+            assertEquals(Bundle.ACTIVE, bundle.getState());
+            assertTrue((t1 - t0) > DELAY / 2);
+        } finally {
+            f.stop();
+            deleteDir(cacheDir);
+        }
     }
 
-    private static File createBundle(String manifest) throws IOException
+    private static File createBundle(String manifest, File tempDir) throws IOException
     {
-        File f = File.createTempFile("felix-bundle", ".jar");
-        f.deleteOnExit();
+        File f = File.createTempFile("felix-bundle", ".jar", tempDir);
 
         Manifest mf = new Manifest(new ByteArrayInputStream(manifest.getBytes("utf-8")));
         mf.getMainAttributes().putValue("Manifest-Version", "1.0");
@@ -143,7 +145,18 @@ public class StartStopBundleTest extends TestCase
         return f;
     }
 
-    public static class TestBundleActivator implements BundleActivator
+    private static void deleteDir(File root) throws IOException
+    {
+        if (root.isDirectory())
+        {
+            for (File file : root.listFiles())
+            {
+                deleteDir(file);
+            }
+        }
+        assertTrue(root.delete());
+    }
+   public static class TestBundleActivator implements BundleActivator
     {
         public void start(BundleContext context) throws Exception
         {
diff --git a/src/test/java/org/apache/felix/framework/URLHandlersTest.java b/src/test/java/org/apache/felix/framework/URLHandlersTest.java
new file mode 100644
index 0000000..42f45e4
--- /dev/null
+++ b/src/test/java/org/apache/felix/framework/URLHandlersTest.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright 2013 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.framework;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import junit.framework.TestCase;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.launch.Framework;
+import org.osgi.service.url.URLConstants;
+import org.osgi.service.url.URLStreamHandlerService;
+import org.osgi.service.url.URLStreamHandlerSetter;
+
+/**
+ *
+ * @author pauls
+ */
+public class URLHandlersTest extends TestCase
+{
+    public void testURLHandlers() throws Exception
+    {
+        String mf = "Bundle-SymbolicName: url.test\n"
+            + "Bundle-Version: 1.0.0\n"
+            + "Bundle-ManifestVersion: 2\n"
+            + "Import-Package: org.osgi.framework,org.osgi.service.url\n"
+            + "Manifest-Version: 1.0\n"
+            + Constants.BUNDLE_ACTIVATOR + ": " + TestURLHandlersActivator.class.getName() + "\n\n";
+
+        File bundleFile = createBundle(mf, TestURLHandlersActivator.class);
+
+        Framework f = createFramework();
+        f.init();
+        f.start();
+
+        try
+        {
+            final Bundle bundle = f.getBundleContext().installBundle(bundleFile.toURI().toString());
+            bundle.start();
+        }
+        finally
+        {
+            try
+            {
+                f.stop();
+            }
+            catch (Throwable t)
+            {
+            }
+        }
+    }
+
+    public void testURLHandlersWithClassLoaderIsolation() throws Exception
+    {
+        DelegatingClassLoader cl1 = new DelegatingClassLoader(this.getClass().getClassLoader());
+        DelegatingClassLoader cl2 = new DelegatingClassLoader(this.getClass().getClassLoader());
+
+        Framework f = createFramework();
+        f.init();
+        f.start();
+
+        String mf = "Bundle-SymbolicName: url.test\n"
+            + "Bundle-Version: 1.0.0\n"
+            + "Bundle-ManifestVersion: 2\n"
+            + "Import-Package: org.osgi.framework\n"
+            + "Manifest-Version: 1.0\n"
+            + Constants.BUNDLE_ACTIVATOR + ": " + TestURLHandlersActivator.class.getName();
+
+        File bundleFile = createBundle(mf, TestURLHandlersActivator.class);
+
+        final Bundle bundle = f.getBundleContext().installBundle(bundleFile.toURI().toString());
+        bundle.start();
+
+        Class clazz1 = cl1.loadClass(URLHandlersTest.class.getName());
+
+        clazz1.getMethod("testURLHandlers").invoke(clazz1.newInstance());
+
+        bundle.stop();
+        bundle.start();
+        Class clazz2 = cl2.loadClass(URLHandlersTest.class.getName());
+
+        clazz2.getMethod("testURLHandlers").invoke(clazz2.newInstance());
+        bundle.stop();
+        bundle.start();
+        f.stop();
+    }
+
+    public static class DelegatingClassLoader extends ClassLoader
+    {
+        private final Object m_lock = new Object();
+        private final ClassLoader m_source;
+
+        public DelegatingClassLoader(ClassLoader source)
+        {
+            m_source = source;
+        }
+
+        @Override
+        public Class<?> loadClass(String name) throws ClassNotFoundException
+        {
+            synchronized (m_lock)
+            {
+                Class<?> result = findLoadedClass(name);
+                if (result != null)
+                {
+                    return result;
+                }
+            }
+            if (!name.startsWith("org.apache.felix") && !name.startsWith("org.osgi."))
+            {
+                return m_source.loadClass(name);
+            }
+            byte[] buffer = new byte[8 * 1024];
+            try
+            {
+                InputStream is = m_source.getResourceAsStream(name.replace('.', '/') + ".class");
+                ByteArrayOutputStream os = new ByteArrayOutputStream();
+                for (int i = is.read(buffer); i != -1; i = is.read(buffer))
+                {
+                    os.write(buffer, 0, i);
+
+                }
+                is.close();
+                os.close();
+                buffer = os.toByteArray();
+            }
+            catch (Exception ex)
+            {
+                throw new ClassNotFoundException("Unable to load class: " + name + " with cl: " + System.identityHashCode(this), ex);
+            }
+            return super.defineClass(name, buffer, 0, buffer.length, null);
+        }
+    }
+
+    public static class TestURLHandlersActivator implements BundleActivator, URLStreamHandlerService
+    {
+        private volatile ServiceRegistration m_reg = null;
+
+        public URLConnection openConnection(URL u) throws IOException
+        {
+            return null;//throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public void parseURL(URLStreamHandlerSetter realHandler, URL u, String spec, int start, int limit)
+        {
+            realHandler.setURL(u, spec, spec, start, spec, spec, spec, spec, spec);
+            //throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public String toExternalForm(URL u)
+        {
+            return u.toString();//throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public boolean equals(URL u1, URL u2)
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public int getDefaultPort()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public InetAddress getHostAddress(URL u)
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public int hashCode(URL u)
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public boolean hostsEqual(URL u1, URL u2)
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public boolean sameFile(URL u1, URL u2)
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public void start(final BundleContext context) throws Exception
+        {
+            try
+            {
+                new URL("test" + System.identityHashCode(TestURLHandlersActivator.this) + ":").openConnection();
+                throw new Exception("Unexpected url resolve");
+            }
+            catch (Exception ex)
+            {
+                // pass
+            }
+
+            Hashtable props = new Hashtable<String, String>();
+            props.put(URLConstants.URL_HANDLER_PROTOCOL, "test" + System.identityHashCode(TestURLHandlersActivator.this));
+
+            ServiceRegistration reg = context.registerService(URLStreamHandlerService.class, this, props);
+
+            new URL("test" + System.identityHashCode(TestURLHandlersActivator.this) + ":").openConnection();
+
+            reg.unregister();
+
+            try
+            {
+                new URL("test" + System.identityHashCode(TestURLHandlersActivator.this) + ":").openConnection();
+                throw new Exception("Unexpected url resolve");
+            }
+            catch (Exception ex)
+            {
+                // pass
+            }
+
+            Bundle bundle2 = null;
+            if (context.getBundle().getSymbolicName().equals("url.test"))
+            {
+
+                String mf = "Bundle-SymbolicName: url.test2\n"
+                    + "Bundle-Version: 1.0.0\n"
+                    + "Bundle-ManifestVersion: 2\n"
+                    + "Import-Package: org.osgi.framework,org.osgi.service.url\n"
+                    + "Manifest-Version: 1.0\n"
+                    + Constants.BUNDLE_ACTIVATOR + ": " + TestURLHandlersActivator.class.getName() + "\n\n";
+
+                File bundleFile = createBundle(mf, TestURLHandlersActivator.class);
+
+                bundle2 = context.installBundle(bundleFile.toURI().toURL().toString());
+            }
+            if (bundle2 != null)
+            {
+                try
+                {
+                    new URL("test" + System.identityHashCode(bundle2) + ":").openConnection();
+                    throw new Exception("Unexpected url2 resolve");
+                }
+                catch (Exception ex)
+                {
+                }
+                bundle2.start();
+                new URL("test" + System.identityHashCode(bundle2) + ":").openConnection();
+                bundle2.stop();
+                try
+                {
+                    new URL("test" + System.identityHashCode(bundle2) + ":").openConnection();
+                    throw new Exception("Unexpected url2 resolve");
+                }
+                catch (Exception ex)
+                {
+                }
+            }
+            else
+            {
+                try
+                {
+                    new URL("test" + System.identityHashCode(context.getBundle()) + ":").openConnection();
+                    throw new Exception("Unexpected url2 resolve");
+                }
+                catch (Exception ex)
+                {
+                }
+                props = new Hashtable();
+                props.put(URLConstants.URL_HANDLER_PROTOCOL, "test" + System.identityHashCode(context.getBundle()));
+                m_reg = context.registerService(URLStreamHandlerService.class, this, props);
+                new URL("test" + System.identityHashCode(context.getBundle()) + ":").openConnection();
+            }
+        }
+
+        private static File createBundle(String manifest, Class... classes) throws IOException
+        {
+            File f = File.createTempFile("felix-bundle", ".jar");
+            f.deleteOnExit();
+
+            Manifest mf = new Manifest(new ByteArrayInputStream(manifest.getBytes("utf-8")));
+            JarOutputStream os = new JarOutputStream(new FileOutputStream(f), mf);
+
+            for (Class clazz : classes)
+            {
+                String path = clazz.getName().replace('.', '/') + ".class";
+                os.putNextEntry(new ZipEntry(path));
+
+                InputStream is = clazz.getClassLoader().getResourceAsStream(path);
+                byte[] buffer = new byte[8 * 1024];
+                for (int i = is.read(buffer); i != -1; i = is.read(buffer))
+                {
+                    os.write(buffer, 0, i);
+                }
+                is.close();
+                os.closeEntry();
+            }
+            os.close();
+            return f;
+        }
+
+        public void stop(BundleContext context) throws Exception
+        {
+            if (m_reg != null)
+            {
+                m_reg.unregister();
+            }
+        }
+    }
+
+    private static File createBundle(String manifest, Class... classes) throws IOException
+    {
+        File f = File.createTempFile("felix-bundle", ".jar");
+        f.deleteOnExit();
+
+        Manifest mf = new Manifest(new ByteArrayInputStream(manifest.getBytes("utf-8")));
+        JarOutputStream os = new JarOutputStream(new FileOutputStream(f), mf);
+
+        for (Class clazz : classes)
+        {
+            String path = clazz.getName().replace('.', '/') + ".class";
+            os.putNextEntry(new ZipEntry(path));
+
+            InputStream is = clazz.getClassLoader().getResourceAsStream(path);
+            byte[] buffer = new byte[8 * 1024];
+            for (int i = is.read(buffer); i != -1; i = is.read(buffer))
+            {
+                os.write(buffer, 0, i);
+            }
+            is.close();
+            os.closeEntry();
+        }
+        os.close();
+        return f;
+    }
+
+    private static Felix createFramework() throws Exception
+    {
+        Map params = new HashMap();
+        params.put(Constants.FRAMEWORK_SYSTEMPACKAGES,
+            "org.osgi.framework; version=1.4.0,"
+            + "org.osgi.service.packageadmin; version=1.2.0,"
+            + "org.osgi.service.startlevel; version=1.1.0,"
+            + "org.osgi.util.tracker; version=1.3.3,"
+            + "org.osgi.service.url; version=1.0.0");
+        File cacheDir = File.createTempFile("felix-cache", ".dir");
+        if (!cacheDir.delete() || !cacheDir.mkdirs())
+        {
+            fail("Unable to set-up cache dir");
+        }
+        String cache = cacheDir.getPath();
+        params.put("felix.cache.profiledir", cache);
+        params.put("felix.cache.dir", cache);
+        params.put(Constants.FRAMEWORK_STORAGE, cache);
+
+        return new Felix(params);
+    }
+}
diff --git a/src/test/java/org/apache/felix/framework/capabilityset/SimpleFilterTest.java b/src/test/java/org/apache/felix/framework/capabilityset/SimpleFilterTest.java
index d7e85a6..b498a73 100644
--- a/src/test/java/org/apache/felix/framework/capabilityset/SimpleFilterTest.java
+++ b/src/test/java/org/apache/felix/framework/capabilityset/SimpleFilterTest.java
@@ -73,5 +73,14 @@ public class SimpleFilterTest extends TestCase
 
         pieces = SimpleFilter.parseSubstring("*foo(*bar*");
         assertTrue("Should match!", SimpleFilter.compareSubstring(pieces, "foo()bar"));
+
+        pieces = SimpleFilter.parseSubstring("*foo*bar*bar");
+        assertFalse("Should not match!", SimpleFilter.compareSubstring(pieces, "foobar"));
+
+        pieces = SimpleFilter.parseSubstring("aaaa*aaaa");
+        assertFalse("Should not match!", SimpleFilter.compareSubstring(pieces, "aaaaaaa"));
+
+        pieces = SimpleFilter.parseSubstring("aaa**aaa");
+        assertTrue("Should match!", SimpleFilter.compareSubstring(pieces, "aaaaaa"));
     }
 }
diff --git a/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java b/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java
index c4622a7..a6eda11 100644
--- a/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java
+++ b/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java
@@ -48,6 +48,7 @@ public class EventDispatcherTest extends TestCase
         final Bundle b1 = getMockBundle();
         final Bundle b2 = getMockBundle();
         final Bundle b3 = getMockBundle();
+        final Bundle b4 = getMockBundle();
 
         final Set calledHooks = new HashSet();
         final EventHook eh1 = new EventHook()
@@ -79,8 +80,8 @@ public class EventDispatcherTest extends TestCase
 
         Logger logger = new Logger();
         ServiceRegistry registry = new ServiceRegistry(logger, null);
-        registry.registerService(null, new String [] {EventHook.class.getName()}, eh1, new Hashtable());
-        registry.registerService(null, new String [] {EventHook.class.getName()}, eh2, new Hashtable());
+        registry.registerService(b4.getBundleContext(), new String [] {EventHook.class.getName()}, eh1, new Hashtable());
+        registry.registerService(b4.getBundleContext(), new String [] {EventHook.class.getName()}, eh2, new Hashtable());
 
         // -- Set up event dispatcher
         EventDispatcher ed = new EventDispatcher(logger, registry);
@@ -92,7 +93,6 @@ public class EventDispatcherTest extends TestCase
             public void serviceChanged(ServiceEvent arg0)
             {
                 fired.add(this);
-                System.out.println("*** sl1");
             }
         };
         ed.addListener(b1.getBundleContext(), ServiceListener.class, sl1, null);
@@ -102,7 +102,6 @@ public class EventDispatcherTest extends TestCase
             public void serviceChanged(ServiceEvent arg0)
             {
                 fired.add(this);
-                System.out.println("*** sl2");
             }
         };
         ed.addListener(b2.getBundleContext(), ServiceListener.class, sl2, null);
@@ -112,13 +111,12 @@ public class EventDispatcherTest extends TestCase
             public void serviceChanged(ServiceEvent arg0)
             {
                 fired.add(this);
-                System.out.println("*** sl3");
             }
         };
         ed.addListener(b3.getBundleContext(), ServiceListener.class, sl3, null);
 
         // --- make the invocation
-        ServiceReference sr = (ServiceReference) EasyMock.createNiceMock(ServiceReference.class);
+        ServiceReference sr = EasyMock.createNiceMock(ServiceReference.class);
         EasyMock.expect(sr.getProperty(Constants.OBJECTCLASS)).andReturn(new String[]
             {
                 "java.lang.String"
@@ -138,7 +136,7 @@ public class EventDispatcherTest extends TestCase
 
         assertEquals("Precondition failed", 0, fired.size());
 
-        Framework framework = (Framework) EasyMock.createNiceMock(Framework.class);
+        Framework framework = EasyMock.createNiceMock(Framework.class);
         EasyMock.replay(new Object[]
             {
                 framework
@@ -155,8 +153,8 @@ public class EventDispatcherTest extends TestCase
 
     private Bundle getMockBundle()
     {
-        BundleContext bc = (BundleContext) EasyMock.createNiceMock(BundleContext.class);
-        Bundle b = (Bundle) EasyMock.createNiceMock(Bundle.class);
+        BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
+        Bundle b = EasyMock.createNiceMock(Bundle.class);
         EasyMock.expect(b.getBundleContext()).andReturn(bc).anyTimes();
         b.getState();
         EasyMock.expectLastCall().andReturn(Integer.valueOf(Bundle.ACTIVE)).anyTimes();
diff --git a/src/test/java/org/apache/felix/framework/util/manifestparser/ManifestParserTest.java b/src/test/java/org/apache/felix/framework/util/manifestparser/ManifestParserTest.java
new file mode 100644
index 0000000..1373f8c
--- /dev/null
+++ b/src/test/java/org/apache/felix/framework/util/manifestparser/ManifestParserTest.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.util.manifestparser;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+
+public class ManifestParserTest extends TestCase
+{
+    public void testIdentityCapabilityMinimal() throws BundleException
+    {
+        Map<String, String> headers = new HashMap<String, String>();
+        headers.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+        headers.put(Constants.BUNDLE_SYMBOLICNAME, "foo.bar");
+        ManifestParser mp = new ManifestParser(null, null, null, headers);
+
+        BundleCapability ic = findCapability(mp.getCapabilities(), IdentityNamespace.IDENTITY_NAMESPACE);
+        assertEquals("foo.bar", ic.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE));
+        assertEquals(IdentityNamespace.TYPE_BUNDLE, ic.getAttributes().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE));
+        assertEquals(0, ic.getDirectives().size());
+    }
+
+    public void testIdentityCapabilityFull() throws BundleException
+    {
+        Map<String, String> headers = new HashMap<String, String>();
+        headers.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+        headers.put(Constants.BUNDLE_SYMBOLICNAME, "abc;singleton:=true");
+        headers.put(Constants.BUNDLE_VERSION, "1.2.3.something");
+        String copyright = "(c) 2013 Apache Software Foundation";
+        headers.put(Constants.BUNDLE_COPYRIGHT, copyright);
+        String description = "A bundle description";
+        headers.put(Constants.BUNDLE_DESCRIPTION, description);
+        String docurl = "http://felix.apache.org/";
+        headers.put(Constants.BUNDLE_DOCURL, docurl);
+        String license = "http://www.apache.org/licenses/LICENSE-2.0";
+        headers.put("Bundle-License", license);
+        ManifestParser mp = new ManifestParser(null, null, null, headers);
+
+        BundleCapability ic = findCapability(mp.getCapabilities(), IdentityNamespace.IDENTITY_NAMESPACE);
+        assertEquals("abc", ic.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE));
+        assertEquals(new Version("1.2.3.something"), ic.getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE));
+        assertEquals(IdentityNamespace.TYPE_BUNDLE, ic.getAttributes().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE));
+        assertEquals(copyright, ic.getAttributes().get(IdentityNamespace.CAPABILITY_COPYRIGHT_ATTRIBUTE));
+        assertEquals(description, ic.getAttributes().get(IdentityNamespace.CAPABILITY_DESCRIPTION_ATTRIBUTE));
+        assertEquals(docurl, ic.getAttributes().get(IdentityNamespace.CAPABILITY_DOCUMENTATION_ATTRIBUTE));
+        assertEquals(license, ic.getAttributes().get(IdentityNamespace.CAPABILITY_LICENSE_ATTRIBUTE));
+
+        assertEquals(1, ic.getDirectives().size());
+        assertEquals("true", ic.getDirectives().get(IdentityNamespace.CAPABILITY_SINGLETON_DIRECTIVE));
+    }
+
+    private BundleCapability findCapability(Collection<BundleCapability> capabilities, String namespace)
+    {
+        for (BundleCapability capability : capabilities)
+        {
+            if (namespace.equals(capability.getNamespace()))
+            {
+                return capability;
+            }
+        }
+        return null;
+    }
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/felix-framework.git



More information about the pkg-java-commits mailing list