Merge branch 'cached-combined-classloader' of https://github.com/3cky/karaf-cellar
diff --git a/assembly/src/main/resources/hazelcast.xml b/assembly/src/main/resources/hazelcast.xml
index f1b2fae..43634e1 100644
--- a/assembly/src/main/resources/hazelcast.xml
+++ b/assembly/src/main/resources/hazelcast.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<hz:hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-3.5.xsd"
+<hz:hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config http://www.hazelcast.com/schema/config/hazelcast-config-3.6.xsd"
            xmlns:hz="http://www.hazelcast.com/schema/config"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     <hz:group>
diff --git a/bundle/src/main/java/org/apache/karaf/cellar/bundle/management/internal/CellarBundleMBeanImpl.java b/bundle/src/main/java/org/apache/karaf/cellar/bundle/management/internal/CellarBundleMBeanImpl.java
index f4ccc63..ec87ed9 100644
--- a/bundle/src/main/java/org/apache/karaf/cellar/bundle/management/internal/CellarBundleMBeanImpl.java
+++ b/bundle/src/main/java/org/apache/karaf/cellar/bundle/management/internal/CellarBundleMBeanImpl.java
@@ -516,14 +516,14 @@
                             bundles.add(bundle);
                         } else {
                             // no match on bundle name, fall back to symbolic name and check if it matches the regex
-                            matcher = namePattern.matcher(name);
+                            matcher = namePattern.matcher(bundleSplit[0]);
                             if (matcher.find()) {
                                 bundles.add(bundle);
                             }
                         }
                     } else {
                         // no bundle name, fall back to symbolic name and check if it matches the regex
-                        matcher = namePattern.matcher(name);
+                        matcher = namePattern.matcher(bundleSplit[0]);
                         if (matcher.find()) {
                             bundles.add(bundle);
                         }
diff --git a/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/BundleCommandSupport.java b/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/BundleCommandSupport.java
index 06182ac..caf6e65 100644
--- a/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/BundleCommandSupport.java
+++ b/bundle/src/main/java/org/apache/karaf/cellar/bundle/shell/BundleCommandSupport.java
@@ -122,14 +122,14 @@
                             bundles.add(bundle);
                         } else {
                             // no match on bundle name, fall back to symbolic name and check if it matches the regex
-                            matcher = namePattern.matcher(name);
+                            matcher = namePattern.matcher(bundleSplit[0]);
                             if (matcher.find()) {
                                 bundles.add(bundle);
                             }
                         }
                     } else {
                         // no bundle name, fall back to symbolic name and check if it matches the regex
-                        matcher = namePattern.matcher(name);
+                        matcher = namePattern.matcher(bundleSplit[0]);
                         if (matcher.find()) {
                             bundles.add(bundle);
                         }
diff --git a/core/src/main/java/org/apache/karaf/cellar/core/discovery/Discovery.java b/core/src/main/java/org/apache/karaf/cellar/core/discovery/Discovery.java
index ce16744..95c6040 100644
--- a/core/src/main/java/org/apache/karaf/cellar/core/discovery/Discovery.java
+++ b/core/src/main/java/org/apache/karaf/cellar/core/discovery/Discovery.java
@@ -19,7 +19,6 @@
 public class Discovery {
 
     public static final String PID = "org.apache.karaf.cellar.discovery";
-    public static final String MEMBERS_PROPERTY_NAME = "tcpIpMembers";
     public static final String DISCOVERED_MEMBERS_PROPERTY_NAME = "discoveredMembers";
 
     public static final String INTERVAL = "interval";
diff --git a/core/src/main/java/org/apache/karaf/cellar/core/discovery/DiscoveryTask.java b/core/src/main/java/org/apache/karaf/cellar/core/discovery/DiscoveryTask.java
index c3f0b41..b50cc6e 100644
--- a/core/src/main/java/org/apache/karaf/cellar/core/discovery/DiscoveryTask.java
+++ b/core/src/main/java/org/apache/karaf/cellar/core/discovery/DiscoveryTask.java
@@ -70,7 +70,7 @@
                     	properties = new Hashtable();
                     }
                     String newMemberText = CellarUtils.createStringFromSet(members, true);
-                    String memberText = (String) properties.get(Discovery.MEMBERS_PROPERTY_NAME);
+                    String memberText = (String) properties.get(Discovery.DISCOVERED_MEMBERS_PROPERTY_NAME);
                     if (newMemberText != null && newMemberText.length() > 0 && !newMemberText.equals(memberText)) {
                         properties.put(Discovery.DISCOVERED_MEMBERS_PROPERTY_NAME, newMemberText);
                         LOGGER.trace("CELLAR DISCOVERY: adding a new member {} to configuration and updating it", newMemberText);
diff --git a/features/pom.xml b/features/pom.xml
index 10513eb..fba0212 100644
--- a/features/pom.xml
+++ b/features/pom.xml
@@ -115,8 +115,11 @@
                             *
                         </Import-Package>
                         <Private-Package>
+                            org.apache.karaf.features.internal.model,
                             org.apache.karaf.cellar.features.management.internal,
                             org.apache.karaf.cellar.features.internal.osgi,
+                            org.apache.felix.utils.version,
+                            org.apache.karaf.util,
                             org.apache.karaf.util.tracker;-split-package:=merge-first
                         </Private-Package>
                     </instructions>
diff --git a/features/src/main/java/org/apache/karaf/cellar/features/management/internal/CellarFeaturesMBeanImpl.java b/features/src/main/java/org/apache/karaf/cellar/features/management/internal/CellarFeaturesMBeanImpl.java
index 7af4e04..a4d4574 100644
--- a/features/src/main/java/org/apache/karaf/cellar/features/management/internal/CellarFeaturesMBeanImpl.java
+++ b/features/src/main/java/org/apache/karaf/cellar/features/management/internal/CellarFeaturesMBeanImpl.java
@@ -26,6 +26,8 @@
 import org.apache.karaf.cellar.features.management.CellarFeaturesMBean;
 import org.apache.karaf.features.*;
 // import org.osgi.framework.BundleEvent;
+import org.apache.karaf.features.internal.model.Features;
+import org.apache.karaf.features.internal.model.JaxbUtil;
 import org.osgi.service.cm.ConfigurationAdmin;
 
 import javax.management.NotCompliantMBeanException;
@@ -438,39 +440,14 @@
                 }
             }
             if (name == null) {
-                // update the repository temporary locally
-                Repository repository = null;
-                boolean localRegistered = false;
-                // local lookup
-                for (Repository registeredRepository : featuresService.listRepositories()) {
-                    if (registeredRepository.getURI().equals(uri)) {
-                        repository = registeredRepository;
-                        break;
-                    }
-                }
-                if (repository == null) {
-                    // registered locally
-                    try {
-                        featuresService.addRepository(uri);
-                    } catch (Exception e) {
-                        throw new IllegalArgumentException("Features repository URL " + uri + " is not valid: " + e.getMessage());
-                    }
-                    // get the repository
-                    for (Repository registeredRepository : featuresService.listRepositories()) {
-                        if (registeredRepository.getURI().equals(uri)) {
-                            repository = registeredRepository;
-                            break;
-                        }
-                    }
-                    name = repository.getName();
-                } else {
-                    localRegistered = true;
-                }
+                // parsing the features repository to get content
+                Features repository = JaxbUtil.unmarshal(uri.toASCIIString(), true);
 
                 // update the cluster group
                 clusterRepositories.put(uri.toString(), name);
 
-                for (Feature feature : repository.getFeatures()) {
+                // update the features in the cluster group
+                for (Feature feature : repository.getFeature()) {
                     FeatureState state = new FeatureState();
                     state.setName(feature.getName());
                     state.setVersion(feature.getVersion());
@@ -478,10 +455,6 @@
                     clusterFeatures.put(feature.getName() + "/" + feature.getVersion(), state);
                 }
 
-                // un-register the repository if it's not local registered
-                if (!localRegistered)
-                    featuresService.removeRepository(uri);
-
                 // broadcast the cluster event
                 ClusterRepositoryEvent event = new ClusterRepositoryEvent(uri.toString(), RepositoryEvent.EventType.RepositoryAdded);
                 event.setInstall(install);
@@ -549,58 +522,31 @@
 
             for (String url : urls) {
                 // looking for the URL in the list
-                String name = null;
-                for (String clusterRepository : clusterRepositories.keySet()) {
-                    if (clusterRepository.equals(url)) {
-                        name = clusterRepositories.get(clusterRepository);
+                boolean found = false;
+                for (String repository : clusterRepositories.keySet()) {
+                    if (repository.equals(repository)) {
+                        found = true;
                         break;
                     }
                 }
-                if (name == null) {
-                    // update the repository temporary locally
-                    Repository repository = null;
-                    boolean localRegistered = false;
-                    // local lookup
-                    for (Repository registeredRepository : featuresService.listRepositories()) {
-                        if (registeredRepository.getURI().equals(new URI(url))) {
-                            repository = registeredRepository;
-                            break;
-                        }
-                    }
-                    if (repository == null) {
-                        // registered locally
-                        try {
-                            featuresService.addRepository(new URI(url));
-                        } catch (Exception e) {
-                            throw new IllegalArgumentException("Features repository URL " + url + " is not valid: " + e.getMessage());
-                        }
-                        // get the repository
-                        for (Repository registeredRepository : featuresService.listRepositories()) {
-                            if (registeredRepository.getURI().equals(new URI(url))) {
-                                repository = registeredRepository;
-                                break;
-                            }
-                        }
-                    } else {
-                        localRegistered = true;
-                    }
+                if (found) {
+                    Features repositoryModel = JaxbUtil.unmarshal(url, true);
 
-                    // update the cluster group
+                    // update the features repositories in the cluster group
                     clusterRepositories.remove(url);
 
-                    for (Feature feature : repository.getFeatures()) {
+                    // update the features in the cluster group
+                    for (Feature feature : repositoryModel.getFeature()) {
                         clusterFeatures.remove(feature.getName() + "/" + feature.getVersion());
                     }
 
-                    // un-register the repository if it's not local registered
-                    if (!localRegistered)
-                        featuresService.removeRepository(new URI(url));
-
                     // broadcast a cluster event
-                    ClusterRepositoryEvent event = new ClusterRepositoryEvent(repo, RepositoryEvent.EventType.RepositoryRemoved);
+                    ClusterRepositoryEvent event = new ClusterRepositoryEvent(url, RepositoryEvent.EventType.RepositoryRemoved);
                     event.setUninstall(uninstall);
                     event.setSourceGroup(group);
                     eventProducer.produce(event);
+                } else {
+                    throw new IllegalArgumentException("Features repository URL " + url + " not found in cluster group " + groupName);
                 }
             }
         } finally {
diff --git a/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoAddCommand.java b/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoAddCommand.java
index b00a111..549e887 100644
--- a/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoAddCommand.java
+++ b/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoAddCommand.java
@@ -27,6 +27,8 @@
 import org.apache.karaf.features.Repository;
 import org.apache.karaf.features.RepositoryEvent;
 import org.apache.karaf.features.command.completers.AvailableRepoNameCompleter;
+import org.apache.karaf.features.internal.model.Features;
+import org.apache.karaf.features.internal.model.JaxbUtil;
 import org.apache.karaf.shell.api.action.Argument;
 import org.apache.karaf.shell.api.action.Command;
 import org.apache.karaf.shell.api.action.Completion;
@@ -97,41 +99,16 @@
                     break;
                 }
             }
+
             if (name == null) {
-                // update the repository temporary locally
-                Repository repository = null;
-                boolean localRegistered = false;
-                // local lookup
-                for (Repository registeredRepository : featuresService.listRepositories()) {
-                    if (registeredRepository.getURI().equals(uri)) {
-                        repository = registeredRepository;
-                        break;
-                    }
-                }
-                if (repository == null) {
-                    // registered locally
-                    try {
-                        featuresService.addRepository(uri);
-                    } catch (Exception e) {
-                        System.err.println("Repository URL " + uri + " is not valid: " + e.getMessage());
-                        return null;
-                    }
-                    // get the repository
-                    for (Repository registeredRepository : featuresService.listRepositories()) {
-                        if (registeredRepository.getURI().equals(uri)) {
-                            repository = registeredRepository;
-                            break;
-                        }
-                    }
-                } else {
-                    localRegistered = true;
-                }
+                // parsing the features repository to get content
+                Features repository = JaxbUtil.unmarshal(uri.toASCIIString(), true);
 
                 // update the features repositories in the cluster group
                 clusterRepositories.put(uri.toString(), repository.getName());
 
                 // update the features in the cluster group
-                for (Feature feature : repository.getFeatures()) {
+                for (Feature feature : repository.getFeature()) {
                     FeatureState featureState = new FeatureState();
                     featureState.setName(feature.getName());
                     featureState.setVersion(feature.getVersion());
@@ -139,10 +116,6 @@
                     clusterFeatures.put(feature.getName() + "/" + feature.getVersion(), featureState);
                 }
 
-                // un-register the repository if it's not local registered
-                if (!localRegistered)
-                    featuresService.removeRepository(uri);
-
                 // broadcast the cluster event
                 ClusterRepositoryEvent event = new ClusterRepositoryEvent(uri.toString(), RepositoryEvent.EventType.RepositoryAdded);
                 event.setInstall(install);
diff --git a/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoRemoveCommand.java b/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoRemoveCommand.java
index df03c29..65bd6df 100644
--- a/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoRemoveCommand.java
+++ b/features/src/main/java/org/apache/karaf/cellar/features/shell/RepoRemoveCommand.java
@@ -27,6 +27,8 @@
 import org.apache.karaf.features.Repository;
 import org.apache.karaf.features.RepositoryEvent;
 import org.apache.karaf.features.command.completers.InstalledRepoNameCompleter;
+import org.apache.karaf.features.internal.model.Features;
+import org.apache.karaf.features.internal.model.JaxbUtil;
 import org.apache.karaf.shell.api.action.Argument;
 import org.apache.karaf.shell.api.action.Command;
 import org.apache.karaf.shell.api.action.Completion;
@@ -121,47 +123,16 @@
                     }
                 }
                 if (found) {
-                    // update the repository temporary locally
-                    Repository repository = null;
-                    boolean localRegistered = false;
-                    // local lookup
-                    for (Repository registeredRepository : featuresService.listRepositories()) {
-                        if (registeredRepository.getURI().equals(new URI(url))) {
-                            repository = registeredRepository;
-                            break;
-                        }
-                    }
-                    if (repository == null) {
-                        // registered locally
-                        try {
-                            featuresService.addRepository(new URI(url));
-                        } catch (Exception e) {
-                            System.err.println("Repository URL " + url + " is not valid: " + e.getMessage());
-                            continue;
-                        }
-                        // get the repository
-                        for (Repository registeredRepository : featuresService.listRepositories()) {
-                            if (registeredRepository.getURI().equals(new URI(url))) {
-                                repository = registeredRepository;
-                                break;
-                            }
-                        }
-                    } else {
-                        localRegistered = true;
-                    }
+                    Features repositoryModel = JaxbUtil.unmarshal(url, true);
 
                     // update the features repositories in the cluster group
                     clusterRepositories.remove(url);
 
                     // update the features in the cluster group
-                    for (Feature feature : repository.getFeatures()) {
+                    for (Feature feature : repositoryModel.getFeature()) {
                         clusterFeatures.remove(feature.getName() + "/" + feature.getVersion());
                     }
 
-                    // un-register the repository if it's not local registered
-                    if (!localRegistered)
-                        featuresService.removeRepository(new URI(url));
-
                     // broadcast a cluster event
                     ClusterRepositoryEvent event = new ClusterRepositoryEvent(url, RepositoryEvent.EventType.RepositoryRemoved);
                     event.setUninstall(uninstall);
diff --git a/hazelcast/src/main/java/org/apache/karaf/cellar/hazelcast/management/internal/CellarNodeMBeanImpl.java b/hazelcast/src/main/java/org/apache/karaf/cellar/hazelcast/management/internal/CellarNodeMBeanImpl.java
index 75d4862..4a4260a 100644
--- a/hazelcast/src/main/java/org/apache/karaf/cellar/hazelcast/management/internal/CellarNodeMBeanImpl.java
+++ b/hazelcast/src/main/java/org/apache/karaf/cellar/hazelcast/management/internal/CellarNodeMBeanImpl.java
@@ -81,7 +81,7 @@
         Set<Node> nodes = clusterManager.listNodes();
 
         for (Node node : nodes) {
-            boolean local = (nodes.equals(clusterManager.getNode()));
+            boolean local = (node.equals(clusterManager.getNode()));
             CompositeData data = new CompositeDataSupport(nodeType,
                     new String[]{ "id", "hostname", "port", "local" },
                     new Object[]{ node.getId(), node.getHost(), node.getPort(), local });
diff --git a/hazelcast/src/test/resources/etc/hazelcast.xml b/hazelcast/src/test/resources/etc/hazelcast.xml
index 9aaa40e..2e347ec 100644
--- a/hazelcast/src/test/resources/etc/hazelcast.xml
+++ b/hazelcast/src/test/resources/etc/hazelcast.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<hz:hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-3.5.xsd"
+<hz:hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config http://www.hazelcast.com/schema/config/hazelcast-config-3.6.xsd"
            xmlns:hz="http://www.hazelcast.com/schema/config"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 
diff --git a/manual/pom.xml b/manual/pom.xml
index 1b883db..ddb5045 100644
--- a/manual/pom.xml
+++ b/manual/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.apache.karaf</groupId>
         <artifactId>cellar</artifactId>
-        <version>4.0.0-SNAPSHOT</version>
+        <version>4.0.1-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
diff --git a/pom.xml b/pom.xml
index f51c52e..5b3bd1b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,7 +41,7 @@
         <felix.bundlerepository.version>2.0.6</felix.bundlerepository.version>
         <felix.utils.version>1.8.0</felix.utils.version>
         <felix.webconsole.version>4.2.14</felix.webconsole.version>
-        <hazelcast.version>3.5.4</hazelcast.version>
+        <hazelcast.version>3.6.3</hazelcast.version>
         <jclouds.version>1.9.1</jclouds.version>
         <joda-time.version>2.9.1</joda-time.version>
         <junit.version>4.11</junit.version>