You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2014/04/07 10:53:04 UTC

[13/13] git commit: [KARAF-2888] New FeaturesService based on the real OSGi resolver

[KARAF-2888] New FeaturesService based on the real OSGi resolver


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/38502e41
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/38502e41
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/38502e41

Branch: refs/heads/master
Commit: 38502e41540de3443b2d7f8215d43bb33db5e1c0
Parents: 9605df3
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Mon Apr 7 09:25:51 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Mon Apr 7 10:52:37 2014 +0200

----------------------------------------------------------------------
 .../enterprise/src/main/feature/feature.xml     |   17 +-
 .../standard/src/main/feature/feature.xml       |    9 +-
 features/core/pom.xml                           |   19 +-
 .../org/apache/karaf/features/Capability.java   |   23 +
 .../java/org/apache/karaf/features/Feature.java |    5 +
 .../karaf/features/FeaturesNamespaces.java      |    6 +-
 .../org/apache/karaf/features/Requirement.java  |   23 +
 .../karaf/features/internal/Artifact.java       |   56 -
 .../internal/BootFeaturesInstaller.java         |  171 ---
 .../karaf/features/internal/BundleManager.java  |  498 -------
 .../features/internal/EventAdminListener.java   |   92 --
 .../internal/FeatureConfigInstaller.java        |  166 ---
 .../karaf/features/internal/FeatureFinder.java  |   59 -
 .../internal/FeatureValidationUtil.java         |  110 --
 .../features/internal/FeaturesServiceImpl.java  | 1192 ---------------
 .../features/internal/InstallationState.java    |   35 -
 .../karaf/features/internal/Overrides.java      |  230 ---
 .../karaf/features/internal/RepositoryImpl.java |   99 --
 .../internal/deployment/DeploymentBuilder.java  |  330 +++++
 .../internal/deployment/Downloader.java         |   35 +
 .../internal/deployment/StreamProvider.java     |   26 +
 .../management/FeaturesServiceMBeanImpl.java    |  274 ++++
 .../management/StandardEmitterMBean.java        |   65 +
 .../features/internal/model/Capability.java     |   91 ++
 .../karaf/features/internal/model/Feature.java  |   36 +-
 .../features/internal/model/Requirement.java    |   87 ++
 .../karaf/features/internal/osgi/Activator.java |  114 +-
 .../repository/AggregateRepository.java         |   55 +
 .../internal/repository/BaseRepository.java     |   86 ++
 .../internal/repository/CacheRepository.java    |   59 +
 .../repository/HttpMetadataProvider.java        |   88 ++
 .../internal/repository/MetadataProvider.java   |   29 +
 .../internal/repository/MetadataRepository.java |   43 +
 .../internal/repository/StaticRepository.java   |   33 +
 .../features/internal/resolver/BaseClause.java  |  114 ++
 .../internal/resolver/CandidateComparator.java  |  129 ++
 .../internal/resolver/CapabilityImpl.java       |  165 +++
 .../internal/resolver/CapabilitySet.java        |  612 ++++++++
 .../internal/resolver/FeatureNamespace.java     |   72 +
 .../internal/resolver/FeatureResource.java      |  101 ++
 .../internal/resolver/IdentityCapability.java   |   63 +
 .../internal/resolver/RequirementImpl.java      |   80 +
 .../internal/resolver/ResolveContextImpl.java   |  102 ++
 .../internal/resolver/ResourceBuilder.java      | 1129 ++++++++++++++
 .../internal/resolver/ResourceImpl.java         |  110 ++
 .../internal/resolver/ServiceNamespace.java     |   30 +
 .../internal/resolver/SimpleFilter.java         |  649 +++++++++
 .../internal/resolver/Slf4jResolverLog.java     |   49 +
 .../internal/resolver/UriNamespace.java         |   47 +
 .../features/internal/service/Artifact.java     |   56 +
 .../internal/service/BootFeaturesInstaller.java |  193 +++
 .../internal/service/EventAdminListener.java    |   91 ++
 .../service/FeatureConfigInstaller.java         |  167 +++
 .../internal/service/FeatureFinder.java         |   68 +
 .../internal/service/FeatureValidationUtil.java |  113 ++
 .../internal/service/FeaturesServiceImpl.java   | 1378 ++++++++++++++++++
 .../features/internal/service/Overrides.java    |  132 ++
 .../internal/service/RepositoryImpl.java        |  103 ++
 .../internal/service/RequirementSort.java       |  107 ++
 .../internal/service/SimpleDownloader.java      |   51 +
 .../karaf/features/internal/service/State.java  |   34 +
 .../features/internal/service/StateStorage.java |  175 +++
 .../features/internal/util/ChecksumUtils.java   |   56 +
 .../features/internal/util/JsonReader.java      |  343 +++++
 .../features/internal/util/JsonWriter.java      |  120 ++
 .../karaf/features/internal/util/Macro.java     |  142 ++
 .../features/internal/util/MultiException.java  |   95 ++
 .../management/FeaturesServiceMBean.java        |    2 +-
 .../management/codec/JmxRepositoryEvent.java    |   13 +-
 .../internal/FeaturesServiceMBeanImpl.java      |  274 ----
 .../internal/StandardEmitterMBean.java          |   65 -
 .../karaf/features/karaf-features-1.3.0.xsd     |  280 ++++
 .../apache/karaf/features/ConditionalTest.java  |    5 +-
 .../karaf/features/FeaturesServiceTest.java     |  165 +--
 .../apache/karaf/features/RepositoryTest.java   |   24 +-
 .../org/apache/karaf/features/TestBase.java     |  105 ++
 .../internal/BootFeaturesInstallerTest.java     |  103 --
 .../features/internal/BundleManagerTest.java    |   74 -
 .../internal/FeaturesServiceImplTest.java       |  178 ---
 .../internal/FeaturesValidationTest.java        |   60 -
 .../karaf/features/internal/OverridesTest.java  |  243 ---
 .../karaf/features/internal/TestBase.java       |  108 --
 .../service/BootFeaturesInstallerTest.java      |  128 ++
 .../internal/service/BundleManagerTest.java     |   64 +
 .../service/FeaturesServiceImplTest.java        |  167 +++
 .../service/FeaturesValidationTest.java         |   65 +
 .../internal/service/OverridesTest.java         |  208 +++
 .../org/apache/karaf/features/internal/f01.xml  |   92 --
 .../org/apache/karaf/features/internal/f02.xml  |  164 ---
 .../org/apache/karaf/features/internal/f03.xml  |   27 -
 .../org/apache/karaf/features/internal/f04.xml  |   28 -
 .../org/apache/karaf/features/internal/f05.xml  |   28 -
 .../org/apache/karaf/features/internal/f06.xml  |   32 -
 .../features/internal/overrides.properties      |   23 -
 .../apache/karaf/features/internal/repo2.xml    |   41 -
 .../karaf/features/internal/service/f01.xml     |   92 ++
 .../karaf/features/internal/service/f02.xml     |  164 +++
 .../karaf/features/internal/service/f03.xml     |   27 +
 .../karaf/features/internal/service/f04.xml     |   28 +
 .../karaf/features/internal/service/f05.xml     |   28 +
 .../karaf/features/internal/service/f06.xml     |   32 +
 .../karaf/features/internal/service/f07.xml     |   35 +
 .../internal/service/overrides.properties       |   23 +
 .../karaf/features/internal/service/repo2.xml   |   41 +
 .../org/apache/karaf/features/repo3.xml         |   27 +
 features/obr/NOTICE                             |   71 -
 features/obr/pom.xml                            |  100 --
 .../features/obr/internal/BundleInfoImpl.java   |   95 --
 .../features/obr/internal/ObrResolver.java      |  199 ---
 .../OSGI-INF/blueprint/features-obr.xml         |   50 -
 .../obr/src/main/resources/OSGI-INF/bundle.info |   18 -
 .../features/obr/internal/ObrResolverTest.java  |  174 ---
 features/pom.xml                                |    1 -
 instance/core/pom.xml                           |    3 +
 .../karaf/itests/ConditionalFeaturesTest.java   |    2 +-
 .../itests/FeatureSshCommandSecurityTest.java   |   29 +-
 .../org/apache/karaf/itests/FeatureTest.java    |   12 +-
 .../java/org/apache/karaf/itests/HttpTest.java  |    2 +
 .../apache/karaf/itests/KarafTestSupport.java   |   44 +-
 .../itests/features/Spring3FeaturesTest.java    |    4 +
 management/server/pom.xml                       |    3 +
 pom.xml                                         |    6 +
 shell/console/pom.xml                           |   42 +-
 shell/core/pom.xml                              |    3 +
 .../src/it/test-aggregate-features/control.xml  |    2 +-
 .../src/it/test-basic-generation/control.xml    |    2 +-
 .../test-check-dependencies-failure/control.xml |    2 +-
 .../src/it/test-check-dependencies/control.xml  |    2 +-
 .../src/it/test-input-file/control.xml          |    2 +-
 .../src/it/test-type-classifier/control.xml     |    2 +-
 .../features/ValidateDescriptorMojo.java        |    4 +-
 .../karaf/util/tracker/BaseActivator.java       |   12 +-
 webconsole/branding/pom.xml                     |    2 +-
 .../webconsole/features/ExtendedFeature.java    |   12 +
 .../webconsole/features/FeaturesPlugin.java     |    2 -
 135 files changed, 10070 insertions(+), 5232 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/38502e41/assemblies/features/enterprise/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/enterprise/src/main/feature/feature.xml b/assemblies/features/enterprise/src/main/feature/feature.xml
index 06905e4..69065ba 100644
--- a/assemblies/features/enterprise/src/main/feature/feature.xml
+++ b/assemblies/features/enterprise/src/main/feature/feature.xml
@@ -33,8 +33,11 @@
             aries.transaction.howl.bufferSizeKBytes = 4
         </config>
         <bundle dependency="true" start-level="30">mvn:org.apache.geronimo.specs/geronimo-jta_1.1_spec/${geronimo.jta-spec.version}</bundle>
-        <bundle start-level="30">mvn:org.apache.aries.transaction/org.apache.aries.transaction.blueprint/${aries.transaction.blueprint.version}</bundle>
         <bundle start-level="30">mvn:org.apache.aries.transaction/org.apache.aries.transaction.manager/${aries.transaction.manager.version}</bundle>
+        <conditional>
+            <condition>aries-blueprint</condition>
+            <bundle start-level="30">mvn:org.apache.aries.transaction/org.apache.aries.transaction.blueprint/${aries.transaction.blueprint.version}</bundle>
+        </conditional>
     </feature>
 
     <feature name="jpa" description="OSGi Persistence Container" version="${aries.jpa.version}" resolver="(obr)">
@@ -42,9 +45,12 @@
         <bundle dependency="true" start-level="30">mvn:org.apache.geronimo.specs/geronimo-jta_1.1_spec/${geronimo.jta-spec.version}</bundle>
         <bundle dependency="true" start-level="30">mvn:org.apache.geronimo.specs/geronimo-jpa_2.0_spec/${geronimo.jpa-spec.version}</bundle>
         <bundle start-level="30">mvn:org.apache.aries.jpa/org.apache.aries.jpa.api/${aries.jpa.api.version}</bundle>
-        <bundle start-level="30">mvn:org.apache.aries.jpa/org.apache.aries.jpa.blueprint.aries/${aries.jpa.blueprint.aries.version}</bundle>
         <bundle start-level="30">mvn:org.apache.aries.jpa/org.apache.aries.jpa.container/${aries.jpa.container.version}</bundle>
         <bundle start-level="30">mvn:org.apache.aries.jpa/org.apache.aries.jpa.container.context/${aries.jpa.container.context.version}</bundle>
+        <conditional>
+            <condition>aries-blueprint</condition>
+            <bundle start-level="30">mvn:org.apache.aries.jpa/org.apache.aries.jpa.blueprint.aries/${aries.jpa.blueprint.aries.version}</bundle>
+        </conditional>
     </feature>
 
     <feature name="openjpa" description="Apache OpenJPA 2.2.x persistence engine support" version="2.2.2" resolver="(obr)">
@@ -161,12 +167,14 @@
         <bundle dependency="true">mvn:com.fasterxml/classmate/1.0.0</bundle>
         <bundle dependency="true">mvn:javax.el/javax.el-api/2.2.4</bundle>
         <bundle dependency="true">mvn:org.glassfish.web/javax.el/2.2.4</bundle>
-        <bundle dependency="true">mvn:org.hibernate/hibernate-validator/${hibernate.validator.version}</bundle>
         <bundle dependency="true">mvn:org.jboss.logging/jboss-logging/3.1.4.GA</bundle>
+        <bundle>mvn:org.hibernate/hibernate-validator/${hibernate.validator.version}</bundle>
     </feature>
 
     <feature name="jndi" description="OSGi Service Registry JNDI access" version="${project.version}" resolver="(obr)">
         <details>JNDI support provided by Apache Aries JNDI ${aries.jndi.version}, including additional service, commands, and MBean.</details>
+        <feature>aries-proxy</feature>
+        <feature>aries-blueprint</feature>
         <bundle start-level="30">mvn:org.apache.xbean/xbean-naming/${xbean.version}</bundle>
         <bundle start-level="30">mvn:org.apache.karaf.jndi/org.apache.karaf.jndi.core/${project.version}</bundle>
         <bundle start-level="30">mvn:org.apache.aries.jndi/org.apache.aries.jndi.api/${aries.jndi.api.version}</bundle>
@@ -180,6 +188,7 @@
     <feature name="jdbc" description="JDBC service and commands" version="${project.version}" resolver="(obr)">
         <details>JDBC support providing service, commands, and MBean.</details>
         <feature>transaction</feature>
+        <feature>aries-blueprint</feature>
         <bundle>mvn:commons-pool/commons-pool/${commons-pool.version}</bundle>
         <bundle>mvn:commons-dbcp/commons-dbcp/${commons-dbcp.version}</bundle>
         <bundle>mvn:org.apache.karaf.jdbc/org.apache.karaf.jdbc.core/${project.version}</bundle>
@@ -189,6 +198,7 @@
     <feature name="jms" description="JMS service and commands" version="${project.version}" resolver="(obr)">
         <details>JMS support provinding service, commands, and MBean.</details>
         <feature>transaction</feature>
+        <feature>aries-blueprint</feature>
         <bundle>mvn:org.apache.geronimo.specs/geronimo-jms_1.1_spec/${geronimo.jms-spec.version}</bundle>
         <bundle>mvn:org.apache.karaf.jms/org.apache.karaf.jms.core/${project.version}</bundle>
         <bundle>mvn:org.apache.karaf.jms/org.apache.karaf.jms.command/${project.version}</bundle>
@@ -212,6 +222,7 @@
         <details>Support of the Aries EBA archives</details>
         <!-- pre-requisites-->
         <feature version="${project.version}">obr</feature>
+        <feature>aries-blueprint</feature>
         <!-- common -->
         <bundle start-level="30">mvn:org.apache.aries.application/org.apache.aries.application.resolver.obr/${aries.application.version}</bundle>
         <bundle start-level="30">mvn:org.apache.aries.application/org.apache.aries.application.install/${aries.application.version}</bundle>

http://git-wip-us.apache.org/repos/asf/karaf/blob/38502e41/assemblies/features/standard/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/standard/src/main/feature/feature.xml b/assemblies/features/standard/src/main/feature/feature.xml
index 3fae4aa..49028d2 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -16,7 +16,7 @@
       See the License for the specific language governing permissions and
       limitations under the License.
 -->
-<features name="standard-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+<features name="standard-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.3.0 http://karaf.apache.org/xmlns/features/v1.3.0">
 
 	<repository>mvn:org.ops4j.pax.web/pax-web-features/${pax.web.version}/xml/features</repository>
 
@@ -35,6 +35,9 @@
         <bundle dependency="true" start-level="20">mvn:org.apache.aries/org.apache.aries.util/${aries.util.version}</bundle>
         <bundle start-level="20">mvn:org.apache.aries.proxy/org.apache.aries.proxy.api/${aries.proxy.api.version}</bundle>
         <bundle start-level="20">mvn:org.apache.aries.proxy/org.apache.aries.proxy.impl/${aries.proxy.version}</bundle>
+        <capability>
+            service-reference;effective:=active;objectClass=org.apache.aries.proxy.ProxyManager
+        </capability>
     </feature>
 
     <feature name="aries-blueprint" description="Aries Blueprint" version="${project.version}">
@@ -47,6 +50,9 @@
             <condition>bundle</condition>
             <bundle start-level="30">mvn:org.apache.karaf.bundle/org.apache.karaf.bundle.blueprintstate/${project.version}</bundle>
         </conditional>
+        <capability>
+            service-reference;effective:=active;objectClass=org.apache.aries.blueprint.services.ParserService
+        </capability>
     </feature>
 
     <feature name="aries-annotation" description="Aries Annotations" version="${project.version}">
@@ -202,6 +208,7 @@
             realm=karaf
         </config>
         <feature>http</feature>
+        <feature>aries-blueprint</feature>
         <bundle start-level="30">mvn:org.apache.felix/org.apache.felix.metatype/${felix.metatype.version}</bundle>
         <bundle start-level="30">mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.branding/${project.version}</bundle>
         <bundle start-level="30">mvn:org.apache.karaf.webconsole/org.apache.karaf.webconsole.console/${project.version}</bundle>

http://git-wip-us.apache.org/repos/asf/karaf/blob/38502e41/features/core/pom.xml
----------------------------------------------------------------------
diff --git a/features/core/pom.xml b/features/core/pom.xml
index 8459b3d..fc9f9ce 100644
--- a/features/core/pom.xml
+++ b/features/core/pom.xml
@@ -65,6 +65,11 @@
             <artifactId>org.apache.karaf.util</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.resolver</artifactId>
+            <scope>provided</scope>
+        </dependency>
 
         <dependency>
             <groupId>org.slf4j</groupId>
@@ -107,15 +112,19 @@
                             org.apache.karaf.features.management.codec;
                                 -noimport:=true
                         </Export-Package>
+                        <Provide-Capability>
+                            service-reference;effective:=active;objectClass=org.apache.karaf.features.FeaturesService
+                        </Provide-Capability>
                         <Private-Package>
-                            org.apache.karaf.features.internal,
-                            org.apache.karaf.features.internal.model,
-                            org.apache.karaf.features.internal.osgi,
-                            org.apache.karaf.features.management.internal,
+                            org.apache.karaf.features.internal.*,
+                            org.apache.felix.resolver,
                             org.apache.felix.utils.version,
                             org.apache.felix.utils.manifest,
                             org.apache.karaf.util.collections,
-                            org.apache.karaf.util.tracker
+                            org.apache.karaf.util.json,
+                            org.apache.karaf.util.tracker,
+                            org.osgi.service.resolver,
+                            org.osgi.service.repository
                         </Private-Package>
                         <Bundle-Activator>
                             org.apache.karaf.features.internal.osgi.Activator

http://git-wip-us.apache.org/repos/asf/karaf/blob/38502e41/features/core/src/main/java/org/apache/karaf/features/Capability.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/Capability.java b/features/core/src/main/java/org/apache/karaf/features/Capability.java
new file mode 100644
index 0000000..d329708
--- /dev/null
+++ b/features/core/src/main/java/org/apache/karaf/features/Capability.java
@@ -0,0 +1,23 @@
+/*
+ * 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.karaf.features;
+
+public interface Capability {
+
+    String getValue();
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/38502e41/features/core/src/main/java/org/apache/karaf/features/Feature.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/Feature.java b/features/core/src/main/java/org/apache/karaf/features/Feature.java
index 4dfb624..2f9f001 100644
--- a/features/core/src/main/java/org/apache/karaf/features/Feature.java
+++ b/features/core/src/main/java/org/apache/karaf/features/Feature.java
@@ -55,4 +55,9 @@ public interface Feature {
     int getStartLevel();
 
     String getRegion();
+
+    List<? extends Capability> getCapabilities();
+
+    List<? extends Requirement> getRequirements();
+
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/38502e41/features/core/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java b/features/core/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java
index 8e09748..282ff71 100644
--- a/features/core/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java
+++ b/features/core/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java
@@ -26,14 +26,16 @@ public interface FeaturesNamespaces {
     String URI_1_0_0 = "http://karaf.apache.org/xmlns/features/v1.0.0";
     String URI_1_1_0 = "http://karaf.apache.org/xmlns/features/v1.1.0";
     String URI_1_2_0 = "http://karaf.apache.org/xmlns/features/v1.2.0";
+    String URI_1_3_0 = "http://karaf.apache.org/xmlns/features/v1.3.0";
 
-    String URI_CURRENT = URI_1_2_0;
+    String URI_CURRENT = URI_1_3_0;
 
     QName FEATURES_0_0_0 = new QName("features");
     QName FEATURES_1_0_0 = new QName(URI_1_0_0, "features");
     QName FEATURES_1_1_0 = new QName(URI_1_1_0, "features");
     QName FEATURES_1_2_0 = new QName(URI_1_2_0, "features");
+    QName FEATURES_1_3_0 = new QName(URI_1_3_0, "features");
 
-    QName FEATURES_CURRENT = FEATURES_1_2_0;
+    QName FEATURES_CURRENT = FEATURES_1_3_0;
 
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/38502e41/features/core/src/main/java/org/apache/karaf/features/Requirement.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/Requirement.java b/features/core/src/main/java/org/apache/karaf/features/Requirement.java
new file mode 100644
index 0000000..4446335
--- /dev/null
+++ b/features/core/src/main/java/org/apache/karaf/features/Requirement.java
@@ -0,0 +1,23 @@
+/*
+ * 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.karaf.features;
+
+public interface Requirement {
+
+    String getValue();
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/38502e41/features/core/src/main/java/org/apache/karaf/features/internal/Artifact.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/Artifact.java b/features/core/src/main/java/org/apache/karaf/features/internal/Artifact.java
deleted file mode 100644
index 94e72e3..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/Artifact.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.features.internal;
-
-import java.net.URI;
-
-/**
- * Simple abstraction of a maven artifact to avoid external deps
- */
-public class Artifact {
-    String groupId;
-    String artifactId;
-    String version;
-    String extension;
-    String classifier;
-    
-    public Artifact(String coords) {
-        String[] coordsAr = coords.split(":");
-        if (coordsAr.length != 5) {
-            throw new IllegalArgumentException("Maven URL " + coords + " is malformed or not complete");
-        }
-        this.groupId = coordsAr[0];
-        this.artifactId = coordsAr[1];
-        this.version = coordsAr[4];
-        this.extension = coordsAr[2];
-        this.classifier = coordsAr[3];
-    }
-    
-    public Artifact(String coords, String version) {
-        this(coords);
-        this.version = version;
-    }
-    
-    public URI getPaxUrlForArtifact(String version) {
-        String uriSt = "mvn:" + this.groupId + "/" + this.artifactId + "/" + version + "/" + this.extension + "/" + this.classifier;
-        try {
-            return new URI(uriSt);
-        } catch (Exception e) {
-            return null;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/38502e41/features/core/src/main/java/org/apache/karaf/features/internal/BootFeaturesInstaller.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/BootFeaturesInstaller.java b/features/core/src/main/java/org/apache/karaf/features/internal/BootFeaturesInstaller.java
deleted file mode 100644
index 1b4fa9d..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/BootFeaturesInstaller.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.features.internal;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.karaf.features.BootFinished;
-import org.apache.karaf.features.Feature;
-import org.apache.karaf.features.FeaturesService;
-import org.apache.karaf.features.FeaturesService.Option;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Manages installation of the boot features in the background
- */
-public class BootFeaturesInstaller {
-	private static final Logger LOGGER = LoggerFactory.getLogger(BootFeaturesInstaller.class);
-
-    public static String VERSION_PREFIX = "version=";
-
-    private final BundleContext bundleContext;
-    private final FeaturesService featuresService;
-    private final String boot;
-    private final boolean bootAsynchronous;
-
-    /**
-     * 
-     * @param featuresService
-     * @param boot list of boot features separated by comma. Optionally contains ;version=x.x.x to specify a specific feature version
-     */
-    public BootFeaturesInstaller(BundleContext bundleContext, FeaturesService featuresService, String boot, boolean bootAsynchronous) {
-		this.bundleContext = bundleContext;
-        this.featuresService = featuresService;
-		this.boot = boot;
-        this.bootAsynchronous = bootAsynchronous;
-	}
-    
-    /**
-     * Install boot features
-     * @throws Exception
-     */
-    public void start() {
-        if (boot != null) {
-            if (bootAsynchronous) {
-                new Thread() {
-                    public void run() {
-                        installBootFeatures();
-                        publishBootFinished();
-                    }
-                }.start();
-            } else {
-                installBootFeatures();
-                publishBootFinished();
-            }
-        } else {
-            publishBootFinished();
-        }
-    }
-    
-	void installBootFeatures() {
-        try {
-            List<Feature> installedFeatures = Arrays.asList(featuresService.listInstalledFeatures());
-            List<Set<String>> stagedFeatureNames = parseBootFeatures(boot);
-            List<Set<Feature>> stagedFeatures = toFeatureSetList(stagedFeatureNames);
-
-            for (Set<Feature> features : stagedFeatures) {
-                features.removeAll(installedFeatures);
-                featuresService.installFeatures(features, EnumSet.of(Option.NoCleanIfFailure, Option.ContinueBatchOnFailure));                
-            }
-        } catch (Exception e) {
-            LOGGER.error("Error installing boot features", e);
-        }
-	}
-	
-	private List<Set<Feature>> toFeatureSetList(List<Set<String>> stagedFeatures) {
-	    ArrayList<Set<Feature>> result = new ArrayList<Set<Feature>>();
-	    for (Set<String> features : stagedFeatures) {
-	        HashSet<Feature> featureSet = new HashSet<Feature>();
-            for (String featureName : features) {
-                try {
-                    Feature feature = getFeature(featureName);
-                    if (feature == null) {
-                        LOGGER.error("Error Boot feature " + featureName + " not found");
-                    } else {
-                        featureSet.add(feature);
-                    }
-                } catch (Exception e) {
-                    LOGGER.error("Error getting feature for feature string " + featureName, e);
-                }
-            }
-            result.add(featureSet);
-        }
-        return result;
-	}
-	
-	/**
-	 * 
-	 * @param featureSt either feature name or <featurename>;version=<version>
-	 * @return feature matching the feature string
-	 * @throws Exception
-	 */
-    private Feature getFeature(String featureSt) throws Exception {
-        String[] parts = featureSt.trim().split(";");
-        String featureName = parts[0];
-        String featureVersion = null;
-        for (String part : parts) {
-            // if the part starts with "version=" it contains the version info
-            if (part.startsWith(VERSION_PREFIX)) {
-                featureVersion = part.substring(VERSION_PREFIX.length());
-            }
-        }
-        if (featureVersion == null) {
-            // no version specified - use default version
-            featureVersion = org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION;
-        }
-        return featuresService.getFeature(featureName, featureVersion);
-    }
-    
-    protected List<Set<String>> parseBootFeatures(String bootFeatures) {
-        Pattern pattern = Pattern.compile("(\\((.+))\\),|.+");
-        Matcher matcher = pattern.matcher(bootFeatures);
-        List<Set<String>> result = new ArrayList<Set<String>>();
-        while (matcher.find()) {
-            String group = matcher.group(2) != null ? matcher.group(2) : matcher.group();
-            result.add(parseFeatureList(group));
-        }
-        return result;
-    }
-
-    private Set<String> parseFeatureList(String group) {
-        HashSet<String> features = new HashSet<String>();
-        for (String feature : Arrays.asList(group.trim().split("\\s*,\\s*"))) {
-            if (feature.length() > 0) {
-                features.add(feature);
-            }
-        }
-        return features;
-    }
-
-    private void publishBootFinished() {
-        if (bundleContext != null) {
-            BootFinished bootFinished = new BootFinished() {};
-            bundleContext.registerService(BootFinished.class, bootFinished, new Hashtable<String, String>());
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/38502e41/features/core/src/main/java/org/apache/karaf/features/internal/BundleManager.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/BundleManager.java b/features/core/src/main/java/org/apache/karaf/features/internal/BundleManager.java
deleted file mode 100644
index be4fca7..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/BundleManager.java
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.features.internal;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InterruptedIOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.jar.JarInputStream;
-import java.util.jar.Manifest;
-
-import org.apache.felix.utils.manifest.Clause;
-import org.apache.felix.utils.manifest.Parser;
-import org.apache.felix.utils.version.VersionRange;
-import org.apache.karaf.features.FeaturesService.Option;
-import org.apache.karaf.features.RegionsPersistence;
-import org.apache.karaf.features.Resolver;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.framework.FrameworkEvent;
-import org.osgi.framework.FrameworkListener;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.Version;
-import org.osgi.framework.startlevel.BundleStartLevel;
-import org.osgi.framework.wiring.FrameworkWiring;
-import org.osgi.service.url.URLStreamHandlerService;
-import org.osgi.util.tracker.ServiceTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class BundleManager {
-
-    private static final Logger LOGGER = LoggerFactory.getLogger(BundleManager.class);
-    private final BundleContext bundleContext;
-    private final long refreshTimeout;
-    private RegionsPersistence regionsPersistence;
-
-    public BundleManager(BundleContext bundleContext) {
-        this(bundleContext, 5000);
-    }
-
-    public BundleManager(BundleContext bundleContext, long refreshTimeout) {
-        this.bundleContext = bundleContext;
-        this.refreshTimeout = refreshTimeout;
-    }
-
-    public void setRegionsPersistence(RegionsPersistence regionsPersistence) {
-        this.regionsPersistence = regionsPersistence;
-    }
-
-    public BundleInstallerResult installBundleIfNeeded(String bundleLocation, int startLevel, String regionName) throws IOException, BundleException {
-        BundleInstallerResult result = doInstallBundleIfNeeded(bundleLocation, startLevel, regionName);
-        installToRegion(regionName, result.bundle, result.isNew);
-        return result;
-    }
-
-    private void installToRegion(String region, Bundle bundle, boolean isNew) throws BundleException {
-        if (region != null && isNew) {
-            if (regionsPersistence != null) {
-                regionsPersistence.install(bundle, region);
-            }
-        }
-    }
-
-    private BundleInstallerResult doInstallBundleIfNeeded(String bundleLocation, int startLevel, String regionName) throws IOException, BundleException {
-        InputStream is = getInputStreamForBundle(bundleLocation);
-        try {
-            is.mark(256 * 1024);
-            @SuppressWarnings("resource")
-            JarInputStream jar = new JarInputStream(is);
-            Manifest m = jar.getManifest();
-            if (m == null) {
-                throw new BundleException("Manifest not present in the first entry of the zip " + bundleLocation);
-            }
-            String sn = m.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
-            if (sn == null) {
-                throw new BundleException("Jar is not a bundle, no Bundle-SymbolicName " + bundleLocation);
-            }
-            // remove attributes from the symbolic name (like
-            // ;blueprint.graceperiod:=false suffix)
-            int attributeIndexSep = sn.indexOf(';');
-            if (attributeIndexSep != -1) {
-                sn = sn.substring(0, attributeIndexSep);
-            }
-            String vStr = m.getMainAttributes().getValue(Constants.BUNDLE_VERSION);
-            Version v = vStr == null ? Version.emptyVersion : Version.parseVersion(vStr);
-            Bundle existingBundle = findInstalled(sn, v);
-            if (existingBundle != null) {
-                LOGGER.debug("Found installed bundle: " + existingBundle);
-                return new BundleInstallerResult(existingBundle, false);
-            }
-            try {
-                is.reset();
-            } catch (IOException e) {
-                is.close();
-                is = new URL(bundleLocation).openStream();
-                // is = new BufferedInputStream(new
-                // URL(bundleLocation).openStream());
-            }
-            is = new BufferedInputStream(new FilterInputStream(is) {
-                @Override
-                public int read(byte b[], int off, int len) throws IOException {
-                    if (Thread.currentThread().isInterrupted()) {
-                        throw new InterruptedIOException();
-                    }
-                    return super.read(b, off, len);
-                }
-            });
-
-            LOGGER.debug("Installing bundle " + bundleLocation);
-            Bundle b = bundleContext.installBundle(bundleLocation, is);
-
-            if (startLevel > 0) {
-                b.adapt(BundleStartLevel.class).setStartLevel(startLevel);
-            }
-
-            return new BundleInstallerResult(b, true);
-        } finally {
-            is.close();
-        }
-    }
-
-    private Bundle findInstalled(String symbolicName, Version version) {
-        String vStr;
-        for (Bundle b : bundleContext.getBundles()) {
-            if (b.getSymbolicName() != null && b.getSymbolicName().equals(symbolicName)) {
-                vStr = (String) b.getHeaders().get(Constants.BUNDLE_VERSION);
-                Version bv = vStr == null ? Version.emptyVersion : Version.parseVersion(vStr);
-                if (version.equals(bv)) {
-                    return b;
-                }
-            }
-        }
-        return null;
-    }
-
-    private InputStream getInputStreamForBundle(String bundleLocation) throws MalformedURLException, IOException {
-        InputStream is;
-        LOGGER.debug("Checking " + bundleLocation);
-        try {
-            int protocolIndex = bundleLocation.indexOf(":");
-            if (protocolIndex != -1) {
-                String protocol = bundleLocation.substring(0, protocolIndex);
-                waitForUrlHandler(protocol);
-            }
-            URL bundleUrl = new URL(bundleLocation);
-            is = new BufferedInputStream(bundleUrl.openStream());
-        } catch (RuntimeException e) {
-            LOGGER.error(e.getMessage());
-            throw e;
-        }
-        return is;
-    }
-
-    /**
-     * Will wait for the {@link URLStreamHandlerService} service for the
-     * specified protocol to be registered.
-     *
-     * @param protocol
-     */
-    private void waitForUrlHandler(String protocol) {
-        try {
-            Filter filter = bundleContext.createFilter("(&(" + Constants.OBJECTCLASS + "=" + URLStreamHandlerService.class.getName() + ")(url.handler.protocol=" + protocol + "))");
-            if (filter == null) {
-                return;
-            }
-            ServiceTracker<URLStreamHandlerService, URLStreamHandlerService> urlHandlerTracker = new ServiceTracker<URLStreamHandlerService, URLStreamHandlerService>(bundleContext, filter, null);
-            try {
-                urlHandlerTracker.open();
-                urlHandlerTracker.waitForService(30000);
-            } catch (InterruptedException e) {
-                LOGGER.debug("Interrupted while waiting for URL handler for protocol {}.", protocol);
-            } finally {
-                urlHandlerTracker.close();
-            }
-        } catch (Exception ex) {
-            LOGGER.error("Error creating service tracker.", ex);
-        }
-    }
-
-    protected Set<Bundle> findBundlesToRefresh(Set<Bundle> existing, Set<Bundle> installed) {
-        Set<Bundle> bundles = new HashSet<Bundle>();
-        bundles.addAll(findBundlesWithOptionalPackagesToRefresh(existing, installed));
-        bundles.addAll(findBundlesWithFragmentsToRefresh(existing, installed));
-        return bundles;
-    }
-
-    protected Set<Bundle> findBundlesWithFragmentsToRefresh(Set<Bundle> existing, Set<Bundle> installed) {
-        Set<Bundle> bundles = new HashSet<Bundle>();
-        Set<Bundle> oldBundles = new HashSet<Bundle>(existing);
-        oldBundles.removeAll(installed);
-        if (!oldBundles.isEmpty()) {
-            for (Bundle b : installed) {
-                String hostHeader = (String) b.getHeaders().get(Constants.FRAGMENT_HOST);
-                if (hostHeader != null) {
-                    Clause[] clauses = Parser.parseHeader(hostHeader);
-                    if (clauses != null && clauses.length > 0) {
-                        Clause path = clauses[0];
-                        for (Bundle hostBundle : oldBundles) {
-                            if (hostBundle.getSymbolicName().equals(path.getName())) {
-                                String ver = path.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE);
-                                if (ver != null) {
-                                    VersionRange v = VersionRange.parseVersionRange(ver);
-                                    if (v.contains(hostBundle.getVersion())) {
-                                        bundles.add(hostBundle);
-                                    }
-                                } else {
-                                    bundles.add(hostBundle);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return bundles;
-    }
-
-    protected Set<Bundle> findBundlesWithOptionalPackagesToRefresh(Set<Bundle> existing, Set<Bundle> installed) {
-        // First pass: include all bundles contained in these features
-        Set<Bundle> bundles = new HashSet<Bundle>(existing);
-        bundles.removeAll(installed);
-        if (bundles.isEmpty()) {
-            return bundles;
-        }
-        // Second pass: for each bundle, check if there is any unresolved
-        // optional package that could be resolved
-        Map<Bundle, List<Clause>> imports = new HashMap<Bundle, List<Clause>>();
-        for (Iterator<Bundle> it = bundles.iterator(); it.hasNext(); ) {
-            Bundle b = it.next();
-            String importsStr = (String) b.getHeaders().get(
-                    Constants.IMPORT_PACKAGE);
-            List<Clause> importsList = getOptionalImports(importsStr);
-            if (importsList.isEmpty()) {
-                it.remove();
-            } else {
-                imports.put(b, importsList);
-            }
-        }
-        if (bundles.isEmpty()) {
-            return bundles;
-        }
-        // Third pass: compute a list of packages that are exported by our
-        // bundles and see if
-        // some exported packages can be wired to the optional imports
-        List<Clause> exports = new ArrayList<Clause>();
-        for (Bundle b : installed) {
-            String exportsStr = (String) b.getHeaders().get(
-                    Constants.EXPORT_PACKAGE);
-            if (exportsStr != null) {
-                Clause[] exportsList = Parser.parseHeader(exportsStr);
-                exports.addAll(Arrays.asList(exportsList));
-            }
-        }
-        for (Iterator<Bundle> it = bundles.iterator(); it.hasNext(); ) {
-            Bundle b = it.next();
-            List<Clause> importsList = imports.get(b);
-            for (Iterator<Clause> itpi = importsList.iterator(); itpi.hasNext(); ) {
-                Clause pi = itpi.next();
-                boolean matching = false;
-                for (Clause pe : exports) {
-                    if (pi.getName().equals(pe.getName())) {
-                        String evStr = pe
-                                .getAttribute(Constants.VERSION_ATTRIBUTE);
-                        String ivStr = pi
-                                .getAttribute(Constants.VERSION_ATTRIBUTE);
-                        Version exported = evStr != null ? Version
-                                .parseVersion(evStr) : Version.emptyVersion;
-                        VersionRange imported = ivStr != null ? VersionRange
-                                .parseVersionRange(ivStr)
-                                : VersionRange.ANY_VERSION;
-                        if (imported.contains(exported)) {
-                            matching = true;
-                            break;
-                        }
-                    }
-                }
-                if (!matching) {
-                    itpi.remove();
-                }
-            }
-            if (importsList.isEmpty()) {
-                it.remove();
-            } else {
-                LOGGER.debug(
-                        "Refeshing bundle {} ({}) to solve the following optional imports",
-                        b.getSymbolicName(), b.getBundleId());
-                for (Clause p : importsList) {
-                    LOGGER.debug("    {}", p);
-                }
-
-            }
-        }
-        return bundles;
-    }
-
-    /*
-     * Get the list of optional imports from an OSGi Import-Package string
-     */
-    protected List<Clause> getOptionalImports(String importsStr) {
-        Clause[] imports = Parser.parseHeader(importsStr);
-        List<Clause> result = new LinkedList<Clause>();
-        for (Clause anImport : imports) {
-            String resolution = anImport
-                    .getDirective(Constants.RESOLUTION_DIRECTIVE);
-            if (Constants.RESOLUTION_OPTIONAL.equals(resolution)) {
-                result.add(anImport);
-            }
-        }
-        return result;
-    }
-
-    protected void refreshPackages(Collection<Bundle> bundles) {
-        final Object refreshLock = new Object();
-        FrameworkWiring wiring = bundleContext.getBundle().adapt(FrameworkWiring.class);
-        if (wiring != null) {
-            synchronized (refreshLock) {
-                wiring.refreshBundles(bundles, new FrameworkListener() {
-                    public void frameworkEvent(FrameworkEvent event) {
-                        if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) {
-                            synchronized (refreshLock) {
-                                refreshLock.notifyAll();
-                            }
-                        }
-                    }
-                });
-                try {
-                    refreshLock.wait(refreshTimeout);
-                } catch (InterruptedException e) {
-                    LOGGER.warn(e.getMessage(), e);
-                }
-            }
-        }
-    }
-
-    public void uninstall(Set<Bundle> bundles) {
-        uninstall(bundles, true);
-    }
-
-    public void uninstall(Set<Bundle> bundles, boolean refresh) {
-        for (Bundle b : bundles) {
-            try {
-                b.uninstall();
-            } catch (Exception e2) {
-                // Ignore
-            }
-        }
-        if (refresh) {
-            refreshPackages(null);
-        }
-    }
-
-    public void uninstall(List<Bundle> bundles) {
-        uninstall(bundles, true);
-    }
-
-    public void uninstall(List<Bundle> bundles, boolean refresh) {
-        for (Bundle b : bundles) {
-            try {
-                b.uninstall();
-            } catch (Exception e2) {
-                // Ignore
-            }
-        }
-        if (refresh) {
-            refreshPackages(null);
-        }
-    }
-
-    public void uninstallById(Set<Long> bundles) throws BundleException, InterruptedException {
-        uninstallById(bundles, true);
-    }
-
-    public void uninstallById(Set<Long> bundles, boolean refresh) throws BundleException,
-            InterruptedException {
-        for (long bundleId : bundles) {
-            Bundle b = bundleContext.getBundle(bundleId);
-            if (b != null) {
-                b.uninstall();
-            }
-        }
-        if (refresh) {
-            refreshPackages(null);
-        }
-    }
-
-    public File getDataFile(String fileName) {
-        return bundleContext.getDataFile(fileName);
-    }
-
-    EventAdminListener createAndRegisterEventAdminListener() {
-        EventAdminListener listener = null;
-        try {
-            getClass().getClassLoader().loadClass(
-                    "org.osgi.service.event.EventAdmin");
-            listener = new EventAdminListener(bundleContext);
-        } catch (Throwable t) {
-            // Ignore, if the EventAdmin package is not available, just don't
-            // use it
-            LOGGER.debug("EventAdmin package is not available, just don't use it");
-        }
-        return listener;
-    }
-
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    public ServiceTracker createServiceTrackerForResolverName(String resolver)
-            throws InvalidSyntaxException {
-        String filter = "(&(" + Constants.OBJECTCLASS + "="
-                + Resolver.class.getName() + ")(name=" + resolver + "))";
-        return new ServiceTracker(bundleContext,
-                FrameworkUtil.createFilter(filter), null);
-    }
-
-    public void refreshBundles(Set<Bundle> existing, Set<Bundle> installed,
-                               EnumSet<Option> options) {
-        boolean print = options.contains(Option.PrintBundlesToRefresh);
-        boolean refresh = !options.contains(Option.NoAutoRefreshBundles);
-        if (print || refresh) {
-            Set<Bundle> bundlesToRefresh = findBundlesToRefresh(existing,
-                    installed);
-            StringBuilder sb = new StringBuilder();
-            for (Bundle b : bundlesToRefresh) {
-                if (sb.length() > 0) {
-                    sb.append(", ");
-                }
-                sb.append(b.getSymbolicName()).append(" (")
-                        .append(b.getBundleId()).append(")");
-            }
-            LOGGER.debug("Bundles to refresh: {}", sb.toString());
-            if (!bundlesToRefresh.isEmpty()) {
-                if (print) {
-                    if (refresh) {
-                        System.out.println("Refreshing bundles "
-                                + sb.toString());
-                    } else {
-                        System.out
-                                .println("The following bundles may need to be refreshed: "
-                                        + sb.toString());
-                    }
-                }
-                if (refresh) {
-                    LOGGER.debug("Refreshing bundles: {}", sb.toString());
-                    refreshPackages(bundlesToRefresh);
-                }
-            }
-        }
-    }
-
-    public BundleContext getBundleContext() {
-        return this.bundleContext;
-    }
-
-    public static class BundleInstallerResult {
-        Bundle bundle;
-        boolean isNew;
-
-        public BundleInstallerResult(Bundle bundle, boolean isNew) {
-            super();
-            this.bundle = bundle;
-            this.isNew = isNew;
-        }
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/38502e41/features/core/src/main/java/org/apache/karaf/features/internal/EventAdminListener.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/EventAdminListener.java b/features/core/src/main/java/org/apache/karaf/features/internal/EventAdminListener.java
deleted file mode 100644
index d463282..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/EventAdminListener.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.features.internal;
-
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import org.apache.karaf.features.EventConstants;
-import org.apache.karaf.features.FeatureEvent;
-import org.apache.karaf.features.FeaturesListener;
-import org.apache.karaf.features.RepositoryEvent;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventAdmin;
-import org.osgi.util.tracker.ServiceTracker;
-
-/**
- * A listener to publish events to EventAdmin
- */
-public class EventAdminListener implements FeaturesListener {
-
-    private final ServiceTracker<EventAdmin, EventAdmin> tracker;
-
-    public EventAdminListener(BundleContext context) {
-        tracker = new ServiceTracker<EventAdmin, EventAdmin>(context, EventAdmin.class.getName(), null);
-        tracker.open();
-    }
-
-    public void featureEvent(FeatureEvent event) {
-        EventAdmin eventAdmin = tracker.getService();
-        if (eventAdmin == null) {
-            return;
-        }
-        Dictionary<String, Object> props = new Hashtable<String, Object>();
-        props.put(EventConstants.TYPE, event.getType());
-        props.put(EventConstants.EVENT, event);
-        props.put(EventConstants.TIMESTAMP, System.currentTimeMillis());
-        props.put(EventConstants.FEATURE_NAME, event.getFeature().getName());
-        props.put(EventConstants.FEATURE_VERSION, event.getFeature().getVersion());
-        String topic;
-        switch (event.getType()) {
-            case FeatureInstalled:
-                topic = EventConstants.TOPIC_FEATURES_INSTALLED;
-                break;
-            case FeatureUninstalled:
-                topic = EventConstants.TOPIC_FEATURES_UNINSTALLED;
-                break;
-            default:
-                throw new IllegalStateException("Unknown features event type: " + event.getType());
-        }
-        eventAdmin.postEvent(new Event(topic, props));
-    }
-
-    public void repositoryEvent(RepositoryEvent event) {
-        EventAdmin eventAdmin = tracker.getService();
-        if (eventAdmin == null) {
-            return;
-        }
-        Dictionary<String, Object> props = new Hashtable<String, Object>();
-        props.put(EventConstants.TYPE, event.getType());
-        props.put(EventConstants.EVENT, event);
-        props.put(EventConstants.TIMESTAMP, System.currentTimeMillis());
-        props.put(EventConstants.REPOSITORY_NAME, event.getRepository().getName());
-        props.put(EventConstants.REPOSITORY_URI, event.getRepository().getURI().toString());
-        String topic;
-        switch (event.getType()) {
-            case RepositoryAdded:
-                topic = EventConstants.TOPIC_REPOSITORY_ADDED;
-                break;
-            case RepositoryRemoved:
-                topic = EventConstants.TOPIC_REPOSITORY_REMOVED;
-                break;
-            default:
-                throw new IllegalStateException("Unknown repository event type: " + event.getType());
-        }
-        eventAdmin.postEvent(new Event(topic, props));
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/38502e41/features/core/src/main/java/org/apache/karaf/features/internal/FeatureConfigInstaller.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/FeatureConfigInstaller.java b/features/core/src/main/java/org/apache/karaf/features/internal/FeatureConfigInstaller.java
deleted file mode 100644
index 5946a3a..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/FeatureConfigInstaller.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.features.internal;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import org.apache.karaf.features.ConfigFileInfo;
-import org.apache.karaf.features.Feature;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FeatureConfigInstaller {
-	private static final Logger LOGGER = LoggerFactory.getLogger(FeaturesServiceImpl.class);
-    private static final String CONFIG_KEY = "org.apache.karaf.features.configKey";
-
-    private final ConfigurationAdmin configAdmin;
-    
-    public FeatureConfigInstaller(ConfigurationAdmin configAdmin) {
-		this.configAdmin = configAdmin;
-	}
-
-    private String[] parsePid(String pid) {
-        int n = pid.indexOf('-');
-        if (n > 0) {
-            String factoryPid = pid.substring(n + 1);
-            pid = pid.substring(0, n);
-            return new String[]{pid, factoryPid};
-        } else {
-            return new String[]{pid, null};
-        }
-    }
-
-    private Configuration createConfiguration(ConfigurationAdmin configurationAdmin,
-                                                String pid, String factoryPid) throws IOException, InvalidSyntaxException {
-        if (factoryPid != null) {
-            return configurationAdmin.createFactoryConfiguration(factoryPid, null);
-        } else {
-            return configurationAdmin.getConfiguration(pid, null);
-        }
-    }
-
-    private Configuration findExistingConfiguration(ConfigurationAdmin configurationAdmin,
-                                                      String pid, String factoryPid) throws IOException, InvalidSyntaxException {
-        String filter;
-        if (factoryPid == null) {
-            filter = "(" + Constants.SERVICE_PID + "=" + pid + ")";
-        } else {
-            String key = createConfigurationKey(pid, factoryPid);
-            filter = "(" + CONFIG_KEY + "=" + key + ")";
-        }
-        Configuration[] configurations = configurationAdmin.listConfigurations(filter);
-        if (configurations != null && configurations.length > 0) {
-            return configurations[0];
-        }
-        return null;
-    }
-
-    void installFeatureConfigs(Feature feature, boolean verbose) throws IOException, InvalidSyntaxException {
-        for (String config : feature.getConfigurations().keySet()) {
-            Dictionary<String,String> props = new Hashtable<String, String>(feature.getConfigurations().get(config));
-            String[] pid = parsePid(config);
-            Configuration cfg = findExistingConfiguration(configAdmin, pid[0], pid[1]);
-            if (cfg == null) {
-                cfg = createConfiguration(configAdmin, pid[0], pid[1]);
-                String key = createConfigurationKey(pid[0], pid[1]);
-                props.put(CONFIG_KEY, key);
-                if (cfg.getBundleLocation() != null) {
-                    cfg.setBundleLocation(null);
-                }
-                cfg.update(props);
-            }
-        }
-        for (ConfigFileInfo configFile : feature.getConfigurationFiles()) {
-            installConfigurationFile(configFile.getLocation(), configFile.getFinalname(), configFile.isOverride(), verbose);
-        }
-    }
-
-    private String createConfigurationKey(String pid, String factoryPid) {
-        return factoryPid == null ? pid : pid + "-" + factoryPid;
-    }
-
-    private void installConfigurationFile(String fileLocation, String finalname, boolean override, boolean verbose) throws IOException {
-    	LOGGER.debug("Checking configuration file " + fileLocation);
-        if (verbose) {
-            System.out.println("Checking configuration file " + fileLocation);
-        }
-    	
-    	String basePath = System.getProperty("karaf.base");
-    	
-    	if (finalname.indexOf("${") != -1) {
-    		//remove any placeholder or variable part, this is not valid.
-    		int marker = finalname.indexOf("}");
-    		finalname = finalname.substring(marker+1);
-    	}
-    	
-    	finalname = basePath + File.separator + finalname;
-    	
-    	File file = new File(finalname); 
-    	if (file.exists() && !override) {
-    		LOGGER.debug("configFile already exist, don't override it");
-    		return;
-    	}
-
-        InputStream is = null;
-        FileOutputStream fop = null;
-        try {
-            is = new BufferedInputStream(new URL(fileLocation).openStream());
-
-            if (!file.exists()) {
-                File parentFile = file.getParentFile();
-                if (parentFile != null)
-                    parentFile.mkdirs();
-                file.createNewFile();
-            }
-
-            fop = new FileOutputStream(file);
-        
-            int bytesRead;
-            byte[] buffer = new byte[1024];
-            
-            while ((bytesRead = is.read(buffer)) != -1) {
-                fop.write(buffer, 0, bytesRead);
-            }
-        } catch (RuntimeException e) {
-            LOGGER.error(e.getMessage());
-            throw e;
-        } catch (MalformedURLException e) {
-        	LOGGER.error(e.getMessage());
-            throw e;
-		} finally {
-			if (is != null)
-				is.close();
-            if (fop != null) {
-			    fop.flush();
-			    fop.close();
-            }
-		}
-            
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/38502e41/features/core/src/main/java/org/apache/karaf/features/internal/FeatureFinder.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/FeatureFinder.java b/features/core/src/main/java/org/apache/karaf/features/internal/FeatureFinder.java
deleted file mode 100644
index d3215fa..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/FeatureFinder.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.features.internal;
-
-import java.net.URI;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.cm.ManagedService;
-
-public class FeatureFinder implements ManagedService {
-
-    Map<String, String> nameToArtifactMap = new HashMap<String, String>();
-
-    public String[] getNames() {
-        return nameToArtifactMap.keySet().toArray(new String[] {});
-    }
-
-    public URI getUriFor(String name, String version) {
-        String coords = nameToArtifactMap.get(name);
-        if (coords == null) {
-            return null;
-        }
-        Artifact artifact = new Artifact(coords);
-        return artifact.getPaxUrlForArtifact(version);
-    }
-
-    @SuppressWarnings("rawtypes")
-    public void updated(Dictionary properties) throws ConfigurationException {
-        if (properties != null) {
-            nameToArtifactMap.clear();
-            Enumeration keys = properties.keys();
-            while (keys.hasMoreElements()) {
-                String key = (String)keys.nextElement();
-                if (!"felix.fileinstall.filename".equals(key) && !"service.pid".equals(key)) {
-                    nameToArtifactMap.put(key, (String)properties.get(key));
-                }
-            }
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/38502e41/features/core/src/main/java/org/apache/karaf/features/internal/FeatureValidationUtil.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/FeatureValidationUtil.java b/features/core/src/main/java/org/apache/karaf/features/internal/FeatureValidationUtil.java
deleted file mode 100644
index dfb7a7d..0000000
--- a/features/core/src/main/java/org/apache/karaf/features/internal/FeatureValidationUtil.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.karaf.features.internal;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URLConnection;
-import javax.xml.XMLConstants;
-import javax.xml.namespace.QName;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
-import javax.xml.validation.Validator;
-
-import org.apache.karaf.features.FeaturesNamespaces;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-/**
- * Utility class which fires XML Schema validation.
- */
-public class FeatureValidationUtil {
-
-    public static final QName FEATURES_0_0 = new QName("features");
-    public static final QName FEATURES_1_0 = new QName("http://karaf.apache.org/xmlns/features/v1.0.0", "features");
-    public static final QName FEATURES_1_1 = new QName("http://karaf.apache.org/xmlns/features/v1.1.0", "features");
-    public static final QName FEATURES_1_2 = new QName("http://karaf.apache.org/xmlns/features/v1.2.0", "features");
-    private static final Logger LOGGER = LoggerFactory.getLogger(FeatureValidationUtil.class);
-
-    /**
-     * Runs schema validation.
-     * 
-     * @param uri Uri to validate.
-     * @throws Exception When validation fails.
-     */
-    public static void validate(URI uri) throws Exception {
-        Document doc = load(uri);
-
-        QName name = new QName(doc.getDocumentElement().getNamespaceURI(), doc.getDocumentElement().getLocalName());
-
-        if (FeaturesNamespaces.FEATURES_0_0_0.equals(name)) {
-            LOGGER.warn("Old style feature file without namespace found (URI: {}). This format is deprecated and support for it will soon be removed", uri);
-            return;
-        } else if (FeaturesNamespaces.FEATURES_1_0_0.equals(name)) {
-            validate(doc, "/org/apache/karaf/features/karaf-features-1.0.0.xsd");
-        } else if (FeaturesNamespaces.FEATURES_1_1_0.equals(name)) {
-            validate(doc, "/org/apache/karaf/features/karaf-features-1.1.0.xsd");
-        } else if (FeaturesNamespaces.FEATURES_1_2_0.equals(name)) {
-            validate(doc, "/org/apache/karaf/features/karaf-features-1.2.0.xsd");
-        }
-        else {
-            throw new IllegalArgumentException("Unrecognized root element: " + name);
-        }
-    }
-
-    private static Document load(URI uri) throws IOException, SAXException, ParserConfigurationException {
-        InputStream stream = null;
-        try {
-            URLConnection conn;
-            try {
-                conn = uri.toURL().openConnection();
-            } catch (IllegalArgumentException e) {
-                throw new IllegalArgumentException("invalid URI: " + uri, e);
-            }
-            conn.setDefaultUseCaches(false);
-            stream = conn.getInputStream();
-            // load document and check the root element for namespace declaration
-            DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
-            dFactory.setNamespaceAware(true);
-            return dFactory.newDocumentBuilder().parse(stream);
-        } finally {
-            if (stream != null) {
-                stream.close();
-            }
-        }
-    }
-
-    private static void validate(Document doc, String schemaLocation) throws SAXException {
-        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
-        // root element has namespace - we can use schema validation
-        Schema schema = factory.newSchema(new StreamSource(FeatureValidationUtil.class.getResourceAsStream(schemaLocation)));
-        // create schema by reading it from an XSD file:
-        Validator validator = schema.newValidator();
-        try {
-            validator.validate(new DOMSource(doc));
-        } catch (Exception e) {
-            throw new IllegalArgumentException("Unable to validate " + doc.getDocumentURI(), e);
-        }
-    }
-
-}