bug 357814: Applies patch contributed by Stefan Zugal
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/Snap.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/Snap.java
index 189bc61..d39f124 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/Snap.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/Snap.java
@@ -30,4 +30,6 @@
     String getContextPath();
     
     Properties getSnapProperties();
+    
+	void addHost(Host host);
 }
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitor.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitor.java
index 11fcf9e..7318365 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitor.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitor.java
@@ -162,26 +162,32 @@
                 
                 Bundle hostBundle = hostReference.getBundle();
 
-                SnapLifecycleState newState = SnapLifecycleState.INIT_FAILED;
-
-                Snap snap = this.factory.createSnap(new Host(hostBundle, servletContext, new RequestRouter(this.snapRegistry, servletContext)));
-                try {
-                    logger.info("Initializing snap '{}'", snap.getContextPath());
-                    snap.init();
-                    
-                    newState = SnapLifecycleState.INIT_SUCCEEDED;
-                    
-                    logger.info("Publishing snap '{}'", snap.getContextPath());
-                    publishSnapService(snap, hostBundle);
-                    
-                } catch (ServletException e) {
-                    this.eventLogger.log(SnapsLogEvents.SNAP_INIT_FAILURE, SnapUtils.boundContextPath(servletContext.getContextPath(), snap.getContextPath()));
-                } finally {
-                	synchronized (this.snapStateMonitor) {                		
-						if (newState == SnapLifecycleState.INIT_SUCCEEDED) {
-							this.snap = snap;
-						}
-                	}                	
+                Host host = new Host(hostBundle, servletContext, new RequestRouter(this.snapRegistry, servletContext));
+                
+                synchronized (this.snapStateMonitor) {
+                	if (this.factory.hasSnap()) {
+                		Snap snap = this.factory.getSnap();
+                		snap.addHost(host);
+                		publishSnapService(snap, hostBundle);
+                	} else {
+                		SnapLifecycleState newState = SnapLifecycleState.INIT_FAILED;
+                		Snap snap = this.factory.createSnap(host);
+                		try {
+                			logger.info("Initializing snap '{}'", snap.getContextPath());
+                			snap.init();
+                			
+                			newState = SnapLifecycleState.INIT_SUCCEEDED;
+                			
+                			logger.info("Publishing snap '{}'", snap.getContextPath());
+                			publishSnapService(snap, hostBundle);
+                		} catch (ServletException e) {
+                			this.eventLogger.log(SnapsLogEvents.SNAP_INIT_FAILURE, SnapUtils.boundContextPath(servletContext.getContextPath(), snap.getContextPath()));
+                		} finally {
+                			if (newState == SnapLifecycleState.INIT_SUCCEEDED) {
+                				this.snap = snap;
+                			}
+                		}
+					}
                 }
             }
         }
@@ -217,7 +223,11 @@
 
         private void unregisterHostListener() {
             logger.info("No longer listening for hosts to be registered.");
-            this.context.removeServiceListener(this);
+            try {
+				this.context.removeServiceListener(this);
+			} catch (IllegalStateException e) {
+				logger.warn("Could not remove host listener. Reason: " + e.getMessage());
+			}
         }
 
 		public void serviceChanged(ServiceEvent event) {
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinition.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinition.java
index e84df10..c6374f5 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinition.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinition.java
@@ -11,19 +11,20 @@
 
 package org.eclipse.virgo.snaps.core.internal;
 
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.eclipse.virgo.snaps.core.internal.deployer.SnapFactory;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import org.eclipse.virgo.util.osgi.manifest.VersionRange;
 import org.eclipse.virgo.util.osgi.manifest.parse.HeaderDeclaration;
 import org.eclipse.virgo.util.osgi.manifest.parse.HeaderParser;
 import org.eclipse.virgo.util.osgi.manifest.parse.HeaderParserFactory;
 import org.eclipse.virgo.util.osgi.manifest.parse.ParserLogger;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public final class SnapHostDefinition {
 
@@ -46,18 +47,22 @@
         return this.versionRange;
     }
 
-    public static SnapHostDefinition parse(String descriptor) {
+    public static Set<SnapHostDefinition> parse(String descriptor) {
         HeaderParser parser = createHeaderParser();
         List<HeaderDeclaration> header = parser.parseHeader(descriptor);
-        if (header == null || header.size() != 1) {
+        if (header == null) {
             logger.error("Invalid Snap-Host header '{}'", descriptor);
             throw new IllegalArgumentException("Invalid Snap-Host header '" + descriptor + "'");
         }
-        HeaderDeclaration declaration = header.get(0);
-        String factoryName = declaration.getNames().get(0);
 
-        String rangeString = declaration.getAttributes().get(Constants.VERSION_ATTRIBUTE);
-        return createSnapHostDefinition(factoryName, rangeString);
+        Set<SnapHostDefinition> hostDefinitions = new HashSet<SnapHostDefinition>();
+        for (HeaderDeclaration declaration:header) {
+        	String factoryName = declaration.getNames().get(0);
+        	String rangeString = declaration.getAttributes().get(Constants.VERSION_ATTRIBUTE);
+        	hostDefinitions.add(createSnapHostDefinition(factoryName, rangeString));
+        }
+        
+        return hostDefinitions;
     }
 
     public static SnapHostDefinition fromServiceReference(ServiceReference<SnapFactory> snapFactoryReference) {
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapUtils.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapUtils.java
index 2db87b3..664a1be 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapUtils.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapUtils.java
@@ -11,11 +11,12 @@
 
 package org.eclipse.virgo.snaps.core.internal;
 
+import java.util.Set;
+
 import javax.servlet.http.HttpServletRequest;
 
-import org.osgi.framework.Bundle;
-
 import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
+import org.osgi.framework.Bundle;
 
 public final class SnapUtils {
 
@@ -48,7 +49,7 @@
         return manifest.getHeader(HEADER_SNAP_HOST) != null;
     }
 
-    public static SnapHostDefinition getSnapHostHeader(BundleManifest manifest) {
+    public static Set<SnapHostDefinition> getSnapHostHeader(BundleManifest manifest) {
         String header = manifest.getHeader(HEADER_SNAP_HOST);
         return (header == null ? null : SnapHostDefinition.parse(header));
     }
@@ -62,7 +63,7 @@
     }
 
     /**
-     * Catenate the host and snap context paths, <i>unless</i> host context path ends with a path separator.<br/>
+     * Concatenate the host and snap context paths, <i>unless</i> host context path ends with a path separator.<br/>
      * <code>null</code> {@link String}s are converted to the empty string <code>""</code>.
      * @param hostContextPath the host context path
      * @param snapContextPath the snap context path
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapFactory.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapFactory.java
index 03de854..4572303 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapFactory.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapFactory.java
@@ -16,9 +16,13 @@
 
 public interface SnapFactory {
     
-    static final String FACTORY_NAME_PROPERTY = "snap.factory.host.name";
+   String FACTORY_NAME_PROPERTY = "snap.factory.host.name";
 
-    static final String FACTORY_RANGE_PROPERTY = "snap.factory.host.range";
+   String FACTORY_RANGE_PROPERTY = "snap.factory.host.range";
 
     Snap createSnap(Host host);
+    
+    boolean hasSnap();
+    
+    Snap getSnap();
 }
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListener.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListener.java
index 1fb702d..ef186d6 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListener.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListener.java
@@ -13,28 +13,29 @@
 
 import java.io.IOException;
 import java.util.Dictionary;
+import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.eclipse.gemini.web.tomcat.spi.WebBundleClassLoaderFactory;
+import org.eclipse.virgo.kernel.install.artifact.BundleInstallArtifact;
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifact;
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifactLifecycleListenerSupport;
+import org.eclipse.virgo.medic.eventlog.EventLogger;
+import org.eclipse.virgo.nano.deployer.api.core.DeploymentException;
+import org.eclipse.virgo.nano.shim.scope.Scope;
 import org.eclipse.virgo.snaps.core.internal.SnapHostDefinition;
 import org.eclipse.virgo.snaps.core.internal.SnapUtils;
 import org.eclipse.virgo.snaps.core.internal.webapp.WebAppSnapFactory;
+import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker;
+import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceRegistration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.eclipse.virgo.nano.deployer.api.core.DeploymentException;
-import org.eclipse.virgo.kernel.install.artifact.BundleInstallArtifact;
-import org.eclipse.virgo.kernel.install.artifact.InstallArtifact;
-import org.eclipse.virgo.kernel.install.artifact.InstallArtifactLifecycleListenerSupport;
-import org.eclipse.virgo.nano.shim.scope.Scope;
-import org.eclipse.virgo.medic.eventlog.EventLogger;
-import org.eclipse.gemini.web.tomcat.spi.WebBundleClassLoaderFactory;
-import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker;
-import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
-
 /**
  * <strong>Concurrent Semantics</strong><br />
  * Thread-safe.
@@ -64,28 +65,36 @@
             Bundle bundle = ((BundleInstallArtifact) installArtifact).getBundle();
             BundleManifest bundleManifest = getBundleManifest((BundleInstallArtifact) installArtifact);
 
-            ServiceRegistration<SnapFactory> registration = createAndRegisterSnapFactoryService(bundle, bundleManifest);
+            Set<ServiceRegistration<SnapFactory>> registrations = createAndRegisterSnapFactoryService(bundle, bundleManifest);
 
-            ServiceRegistrationTracker registrationTracker = new ServiceRegistrationTracker();
-            registrationTracker.track(registration);
+            for (ServiceRegistration<SnapFactory> registration:registrations) {
+            	ServiceRegistrationTracker registrationTracker = new ServiceRegistrationTracker();
+            	registrationTracker.track(registration);
 
-            this.registrationTrackers.put(installArtifact, registrationTracker);
+            	this.registrationTrackers.put(installArtifact, registrationTracker);
+            }
         }
     }
 
-    ServiceRegistration<SnapFactory> createAndRegisterSnapFactoryService(Bundle bundle, BundleManifest bundleManifest) {
+    Set<ServiceRegistration<SnapFactory>> createAndRegisterSnapFactoryService(Bundle bundle, BundleManifest bundleManifest) {
         logger.info("Creating a SnapFactory for bundle '{}'", bundle);
         SnapFactory snapFactory = new WebAppSnapFactory(bundle, this.classLoaderFactory, this.eventLogger);
 
-        SnapHostDefinition hostDefinition = SnapUtils.getSnapHostHeader(bundleManifest);
+        Set<SnapHostDefinition> hostDefinitions = SnapUtils.getSnapHostHeader(bundleManifest);
 
-        Dictionary<String, String> serviceProperties= new Hashtable<String, String>();
-        serviceProperties.put(Scope.PROPERTY_SERVICE_SCOPE, Scope.SCOPE_ID_GLOBAL); // expose service outside any containing scope
-        serviceProperties.put(SnapFactory.FACTORY_NAME_PROPERTY, hostDefinition.getSymbolicName());
-        serviceProperties.put(SnapFactory.FACTORY_RANGE_PROPERTY, hostDefinition.getVersionRange().toParseString());
+        Set<ServiceRegistration<SnapFactory>> registrations = new HashSet<ServiceRegistration<SnapFactory>>();
+        
+        for (SnapHostDefinition hostDefinition : hostDefinitions) {
+        	Dictionary<String, String> serviceProperties= new Hashtable<String, String>();
+        	serviceProperties.put(Scope.PROPERTY_SERVICE_SCOPE, Scope.SCOPE_ID_GLOBAL); // expose service outside any containing scope
+        	serviceProperties.put(SnapFactory.FACTORY_NAME_PROPERTY, hostDefinition.getSymbolicName());
+        	serviceProperties.put(SnapFactory.FACTORY_RANGE_PROPERTY, hostDefinition.getVersionRange().toParseString());
 
-        ServiceRegistration<SnapFactory> registration = bundle.getBundleContext().registerService(SnapFactory.class, snapFactory, serviceProperties);
-        return registration;
+        	ServiceRegistration<SnapFactory> registration = bundle.getBundleContext().registerService(SnapFactory.class, snapFactory, serviceProperties);
+        	registrations.add(registration);
+        }
+        
+        return registrations;
     }
 
     static BundleManifest getBundleManifest(BundleInstallArtifact bundleInstallArtifact) throws DeploymentException {
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnap.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnap.java
index 173720b..e63f3af 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnap.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnap.java
@@ -85,7 +85,7 @@
      * 
      * @throws ServletException
      */
-    public final void init() throws ServletException {
+    public synchronized final void init() throws ServletException {
         logger.info("Initializing snap '{}'", this.contextPath);
         WebXml webXml = BundleWebXmlLoader.loadWebXml(this.snapBundle);
         SnapServletContext servletContext = new SnapServletContext(this.host.getServletContext(), this.snapBundle, this.contextPath);
@@ -179,4 +179,15 @@
         }
         return properties;
     }
+    
+	@Override
+	public synchronized void addHost(Host host) {
+		logger.info("Adding host '{}' to snap '{}'", host.getBundle(), this.contextPath);
+        SnapServletContext servletContext = new SnapServletContext(host.getServletContext(), this.snapBundle, this.contextPath);
+	    servletContext.setAttribute(WebContainer.ATTRIBUTE_BUNDLE_CONTEXT, this.snapBundle.getBundleContext());
+
+	    this.virtualContainer.addHost(servletContext);
+
+	    this.eventLogger.log(SnapsLogEvents.SNAP_BOUND, SnapUtils.boundContextPath(host.getServletContext().getContextPath(), this.contextPath));
+	}
 }
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnapFactory.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnapFactory.java
index dfde7c8..d8bb9ef 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnapFactory.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnapFactory.java
@@ -31,6 +31,8 @@
 
     private final EventLogger eventLogger;
 
+	private WebAppSnap webAppSnap;
+
     public WebAppSnapFactory(Bundle snapBundle, WebBundleClassLoaderFactory webBundleClassLoaderFactory, EventLogger eventLogger) {
         this.snapBundle = snapBundle;
         this.classLoaderFactory = webBundleClassLoaderFactory;
@@ -39,7 +41,18 @@
 
     public Snap createSnap(Host host) {
         logger.info("Creating new snap that binds snap bundle '{}' to host bundle '{}'", this.snapBundle, host.getBundle());
-        return new WebAppSnap(host, this.snapBundle, this.classLoaderFactory, this.eventLogger);
+        webAppSnap = new WebAppSnap(host, this.snapBundle, this.classLoaderFactory, this.eventLogger);
+		return webAppSnap;
     }
+    
+	@Override
+	public boolean hasSnap() {
+		return this.webAppSnap != null;
+	}
+
+	@Override
+	public Snap getSnap() {
+		return webAppSnap;
+	}
 
 }
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/FilterManager.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/FilterManager.java
index bb16747..edbbfc8 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/FilterManager.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/FilterManager.java
@@ -37,8 +37,8 @@
 
 class FilterManager {
     
-    private final SnapServletContext snapServletContext;
-    
+	private final List<SnapServletContext> snapServletContexts = new ArrayList<>();
+	
     private final ClassLoader classLoader;        
     
     private final List<FilterHolder> filters = Collections.synchronizedList(new ArrayList<FilterHolder>());
@@ -47,22 +47,28 @@
     
     private final List<ServletNameFilterMapping> servletNameFilterMappings = Collections.synchronizedList(new ArrayList<ServletNameFilterMapping>());
     
+	private WebXml webXml;
+
+	private Map<String, FilterHolder> filtersMap;
+    
     public FilterManager(WebXml webXml, SnapServletContext snapServletContext, ClassLoader classLoader) {
-        this.snapServletContext = snapServletContext;
+    	this.webXml = webXml;
+		this.snapServletContexts.add(snapServletContext);
         this.classLoader = classLoader;
 
-        reifyWebXml(webXml);
+        this.filtersMap = processFilters();
+        reifyWebXml(snapServletContext);
     }
     
-    private void reifyWebXml(WebXml webXml) {
-        Map<String, FilterHolder> filters = processFilters(webXml);
-        processFilterMappings(webXml, filters);
-    }            
+    private void reifyWebXml(SnapServletContext snapServletContext) {
+        processUrlPatternFilterMappings(snapServletContext);
+        processServletNameFilterMappings();
+    }           
     
-    private Map<String, FilterHolder> processFilters(WebXml webXml) throws SnapException {
+    private Map<String, FilterHolder> processFilters() throws SnapException {
         Map<String, FilterHolder> filtersMap = new HashMap<String, FilterHolder>();
         
-        for (FilterDefinition filterDefinition : webXml.getFilterDefinitions()) {
+        for (FilterDefinition filterDefinition : this.webXml.getFilterDefinitions()) {
             try {
                 Class<?> filterClass = ManagerUtils.loadComponentClass(filterDefinition.getFilterClassName(), this.classLoader);
                 if (Filter.class.isAssignableFrom(filterClass)) {
@@ -86,24 +92,26 @@
         return filtersMap;
     }
     
-    private void processFilterMappings(WebXml webXml, Map<String, FilterHolder> filters) throws SnapException {
-        for (UrlPatternFilterMappingDefinition definition : webXml.getUrlPatternFilterMappingDefinitions()) {
-            Filter filter = filters.get(definition.getFilterName()).getInstance();
-            this.urlPatternFilterMappings.add(new UrlPatternFilterMapping(filter, ManagerUtils.expandMapping(definition.getUrlPattern(), this.snapServletContext), definition.getFilterDispatcherTypes()));
-        }
-        
-        for (ServletNameFilterMappingDefinition definition : webXml.getServletNameFilterMappingDefinitions()) {
-            Filter filter = filters.get(definition.getFilterName()).getInstance();
-            this.servletNameFilterMappings.add(new ServletNameFilterMapping(filter, definition.getServletName(), definition.getFilterDispatcherTypes()));            
+    private void processUrlPatternFilterMappings(SnapServletContext snapServletContext) throws SnapException {
+        for (UrlPatternFilterMappingDefinition definition : this.webXml.getUrlPatternFilterMappingDefinitions()) {
+            Filter filter = this.filtersMap.get(definition.getFilterName()).getInstance();
+            this.urlPatternFilterMappings.add(new UrlPatternFilterMapping(filter, ManagerUtils.expandMapping(definition.getUrlPattern(), snapServletContext), definition.getFilterDispatcherTypes()));
         }
     }
+
+	private void processServletNameFilterMappings() {
+		for (ServletNameFilterMappingDefinition definition : this.webXml.getServletNameFilterMappingDefinitions()) {
+            Filter filter = this.filtersMap.get(definition.getFilterName()).getInstance();
+            this.servletNameFilterMappings.add(new ServletNameFilterMapping(filter, definition.getServletName(), definition.getFilterDispatcherTypes()));            
+        }
+	}
     
     void init() throws ServletException {
         try {
             ManagerUtils.doWithThreadContextClassLoader(this.classLoader, new ClassLoaderCallback<Void>() {
                 public Void doWithClassLoader() throws ServletException {
                     for (FilterHolder filterHolder : filters) {                        
-                        FilterConfig config = new ImmutableFilterConfig(filterHolder.getDefinition(), snapServletContext);
+                        FilterConfig config = new ImmutableFilterConfig(filterHolder.getDefinition(), snapServletContexts.get(0));
                         try {
                             filterHolder.getInstance().init(config);
                         } catch (ServletException se) {
@@ -187,4 +195,9 @@
             return this.dispatcherTypes.contains(dispatcherType) && this.servletName.equals(servletName);
         }
     }
+    
+	public void addSnapServletContext(SnapServletContext snapServletContext) {
+		this.snapServletContexts.add(snapServletContext);
+		processUrlPatternFilterMappings(snapServletContext);
+	}
 }
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/ServletManager.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/ServletManager.java
index 9f49f74..c168168 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/ServletManager.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/ServletManager.java
@@ -12,6 +12,8 @@
 package org.eclipse.virgo.snaps.core.internal.webapp.container;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -45,19 +47,22 @@
 
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
-    private final SnapServletContext snapServletContext;
+    private final List<SnapServletContext> snapServletContexts = new ArrayList<>();
 
     private final ClassLoader classLoader;
 
     private final UrlPatternMatcher patternMatcher = new UrlPatternMatcher();
 
     private final Map<String, ServletHolder> servlets = new ConcurrentHashMap<String, ServletHolder>();
+    
+	private WebXml webXml;
 
     ServletManager(WebXml webXml, SnapServletContext snapServletContext, ClassLoader classLoader) {
-        this.snapServletContext = snapServletContext;
+    	this.webXml = webXml;
+		this.snapServletContexts.add(snapServletContext);
         this.classLoader = classLoader;
 
-        reifyWebXml(webXml);
+        reifyWebXml(snapServletContext);
     }
 
     void init() throws ServletException {
@@ -67,7 +72,7 @@
                 public Void doWithClassLoader() throws ServletException {
                     for (Map.Entry<String, ServletHolder> entry : servlets.entrySet()) {
                         ServletHolder holder = entry.getValue();
-                        ServletConfig config = new ImmutableServletConfig(holder.getDefinition(), snapServletContext);
+                        ServletConfig config = new ImmutableServletConfig(holder.getDefinition(),  snapServletContexts.get(0));
                         holder.getInstance().init(config);
                         // TODO Log which servlet failed, and re-throw
                     }
@@ -98,13 +103,13 @@
         }
     }
 
-    private void reifyWebXml(WebXml webXml) {
-        processServlets(webXml);
-        processServletMappingDefinitions(webXml);
+    private void reifyWebXml(SnapServletContext snapServletContext) {
+        processServlets();
+        processServletMappingDefinitions(snapServletContext);
     }
 
-    private void processServlets(WebXml webXml) throws SnapException {
-        for (ServletDefinition servletDefinition : webXml.getServletDefinitions()) {
+    private void processServlets( ) throws SnapException {
+        for (ServletDefinition servletDefinition : this.webXml.getServletDefinitions()) {
             try {
                 Class<?> servletClass = ManagerUtils.loadComponentClass(servletDefinition.getServletClassName(), this.classLoader);
                 Servlet servlet = (Servlet) servletClass.newInstance();
@@ -126,10 +131,10 @@
         }
     }
 
-    private void processServletMappingDefinitions(WebXml webXml) {
-        for (ServletMappingDefinition mappingDefinition : webXml.getServletMappingDefinitions()) {
+    private void processServletMappingDefinitions(SnapServletContext snapServletContext) {
+        for (ServletMappingDefinition mappingDefinition : this.webXml.getServletMappingDefinitions()) {
             this.patternMatcher.addMapping(mappingDefinition.getServletName(), ManagerUtils.expandMapping(mappingDefinition.getUrlPattern(),
-                this.snapServletContext));
+                snapServletContext));
             // TODO Validate, probably in WebXml, the referenced servlets exist, etc.
         }
     }
@@ -159,4 +164,9 @@
             return mapping;
         }
     }
+    
+	public void addSnapServletContext(SnapServletContext snapServletContext) {
+		this.snapServletContexts.add(snapServletContext);
+		processServletMappingDefinitions(snapServletContext);
+	}
 }
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/SnapHttpSession.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/SnapHttpSession.java
index fde835d..05b2c6e 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/SnapHttpSession.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/SnapHttpSession.java
@@ -23,6 +23,9 @@
 public final class SnapHttpSession extends HttpSessionWrapper {
 
     private static final String QUALIFIED_NAME_MARKER = "##";
+    
+    // This constant should have the same value as within org.springframework.aop.scope.ScopedProxyUtils
+    private static final String TARGET_NAME_PREFIX = "scopedTarget.";
 
     private final SnapServletContext snapServletContext;
 
@@ -48,11 +51,17 @@
     @Override
     public void removeAttribute(String name) {
         super.removeAttribute(qualifyName(name));
+        if (name.startsWith(TARGET_NAME_PREFIX)) {
+        	super.removeAttribute(name);
+        }
     }
 
     @Override
     public void setAttribute(String name, Object value) {
         super.setAttribute(qualifyName(name), value);
+        if (name.startsWith(TARGET_NAME_PREFIX)) {
+        	super.setAttribute(name, value);
+        }
     }
 
     @Override
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/StandardVirtualContainer.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/StandardVirtualContainer.java
index e9bdbae..15d4205 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/StandardVirtualContainer.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/StandardVirtualContainer.java
@@ -93,4 +93,10 @@
     public SnapServletContext getSnapServletContext() {
         return this.snapServletContext;
     }
+    
+	@Override
+	public void addHost(SnapServletContext servletContext) {
+		this.servletManager.addSnapServletContext(servletContext);
+		this.filterManager.addSnapServletContext(servletContext);
+	}
 }
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/VirtualContainer.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/VirtualContainer.java
index ba0e4ee..a15c433 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/VirtualContainer.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/VirtualContainer.java
@@ -36,4 +36,6 @@
     VirtualContainerRequestDispatcher createDispatcher();
     
     SnapServletContext getSnapServletContext();
+    
+	void addHost(SnapServletContext servletContext);
 }
diff --git a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitorTests.java b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitorTests.java
index 627c4d3..218244d 100644
--- a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitorTests.java
+++ b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitorTests.java
@@ -69,13 +69,13 @@
 
         SnapFactory factory = createMock(SnapFactory.class);
         expect(factory.createSnap(isA(Host.class))).andReturn(snap);
+        expect(factory.hasSnap()).andReturn(Boolean.FALSE);
 
         replay(factory, snap);
         publishFactory(factory, "travel", "[1.0, 2.0)");
 
         assertSnapPublished("/hotels", host);
         verify(factory, snap);
-
     }
 
     @Test
@@ -90,6 +90,7 @@
 
         SnapFactory factory = createMock(SnapFactory.class);
         expect(factory.createSnap(isA(Host.class))).andReturn(snap);
+        expect(factory.hasSnap()).andReturn(Boolean.FALSE);
         publishFactory(factory, "travel", "[1.0, 2.0)");
 
         replay(factory, snap);
@@ -129,6 +130,7 @@
 
         SnapFactory factory = createMock(SnapFactory.class);
         expect(factory.createSnap(isA(Host.class))).andReturn(snap);
+        expect(factory.hasSnap()).andReturn(Boolean.FALSE);
         replay(factory, snap);
 
         publishFactory(factory, "travel", "[1.0, 3.0)");
@@ -149,6 +151,7 @@
 
         SnapFactory factory = createMock(SnapFactory.class);
         expect(factory.createSnap(isA(Host.class))).andReturn(snap);
+        expect(factory.hasSnap()).andReturn(Boolean.FALSE);
         publishFactory(factory, "travel", "[1.0, 2.0)");
 
         replay(factory, snap);
@@ -222,6 +225,7 @@
 
         final SnapFactory factory = createMock(SnapFactory.class);
         expect(factory.createSnap(isA(Host.class))).andReturn(slice);
+        expect(factory.hasSnap()).andReturn(Boolean.FALSE);
         replay(factory, slice);
 
         // public snap factory bound to "clinic" host
diff --git a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinitionTests.java b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinitionTests.java
index 5dea8c0..15ac663 100644
--- a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinitionTests.java
+++ b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinitionTests.java
@@ -11,32 +11,52 @@
 
 package org.eclipse.virgo.snaps.core.internal;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
 
-import org.eclipse.virgo.snaps.core.internal.SnapHostDefinition;
-import org.junit.Test;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
 
 import org.eclipse.virgo.util.osgi.manifest.VersionRange;
+import org.junit.Test;
 
 
 public class SnapHostDefinitionTests {
 
     @Test
     public void testStandard() {
-        SnapHostDefinition def = SnapHostDefinition.parse("travel;version=\"[1.2, 1.3)\"");
-        assertEquals("travel", def.getSymbolicName());
-        assertEquals(new VersionRange("[1.2, 1.3)"), def.getVersionRange());
+    	Set<SnapHostDefinition> definitions = SnapHostDefinition.parse("travel;version=\"[1.2, 1.3)\"");
+		assertEquals(1, definitions.size());
+
+		SnapHostDefinition definition = definitions.iterator().next();
+		assertEquals("travel", definition.getSymbolicName());
+		assertEquals(new VersionRange("[1.2, 1.3)"), definition.getVersionRange());
     }
     
-    @Test
-    public void testWithoutRange() {
-        SnapHostDefinition def = SnapHostDefinition.parse("travel");
-        assertEquals("travel", def.getSymbolicName());
-        assertEquals(VersionRange.NATURAL_NUMBER_RANGE, def.getVersionRange());
-    }
+	@Test
+	public void testWithoutRange() {
+		Set<SnapHostDefinition> definitions = SnapHostDefinition.parse("travel");
+		assertEquals(1, definitions.size());
+
+		SnapHostDefinition definition = definitions.iterator().next();
+		assertEquals("travel", definition.getSymbolicName());
+		assertEquals(VersionRange.NATURAL_NUMBER_RANGE, definition.getVersionRange());
+	}
     
-    @Test(expected=IllegalArgumentException.class)
-    public void testInvalid() {
-        SnapHostDefinition.parse("travel,hotels");
-    }
+	@Test
+	public void testMultiple() throws Exception {
+		Set<SnapHostDefinition> definitions = SnapHostDefinition.parse("travel,ski;version=\"[1.4, 2)\"");
+
+		Map<String, VersionRange> expected = new HashMap<>();
+		expected.put("travel", VersionRange.NATURAL_NUMBER_RANGE);
+		expected.put("ski", new VersionRange("[1.4, 2)"));
+		assertEquals(expected.size(), definitions.size());
+
+		for (SnapHostDefinition host : definitions) {
+			VersionRange expectedRange = expected.get(host.getSymbolicName());
+			
+			assertNotNull("Could not find a header for " + host.getSymbolicName(), expectedRange);
+			assertEquals(expectedRange, host.getVersionRange());
+		}
+	}
 }
diff --git a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapUtilsTests.java b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapUtilsTests.java
index b83c413..fe40385 100644
--- a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapUtilsTests.java
+++ b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapUtilsTests.java
@@ -23,15 +23,13 @@
 
 import java.util.Dictionary;
 import java.util.Hashtable;
+import java.util.Set;
 
-import org.eclipse.virgo.snaps.core.internal.SnapHostDefinition;
-import org.eclipse.virgo.snaps.core.internal.SnapUtils;
+import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
 import org.junit.Test;
 import org.osgi.framework.Bundle;
 import org.springframework.mock.web.MockHttpServletRequest;
 
-import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
-
 public class SnapUtilsTests {
 
     @Test
@@ -84,9 +82,11 @@
         expect(manifest.getHeader(SnapUtils.HEADER_SNAP_HOST)).andReturn("travel;version=\"[1.2, 1.3)\"");
         
         replay(manifest);
-        SnapHostDefinition header = SnapUtils.getSnapHostHeader(manifest);
+        Set<SnapHostDefinition> header = SnapUtils.getSnapHostHeader(manifest);
+        assertEquals(1, header.size());
+        
         assertNotNull(header);
-        assertEquals("travel", header.getSymbolicName());
+        assertEquals("travel", header.iterator().next().getSymbolicName());
         verify(manifest);
     }
     
@@ -96,7 +96,7 @@
         expect(manifest.getHeader(SnapUtils.HEADER_SNAP_HOST)).andReturn(null);
         
         replay(manifest);
-        SnapHostDefinition header = SnapUtils.getSnapHostHeader(manifest);
+        Set<SnapHostDefinition> header = SnapUtils.getSnapHostHeader(manifest);
         assertNull(header);
         verify(manifest);
     }
diff --git a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListenerTests.java b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListenerTests.java
index 2e6c7d8..876c469 100644
--- a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListenerTests.java
+++ b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListenerTests.java
@@ -18,20 +18,17 @@
 
 import java.io.IOException;
 
-import org.eclipse.virgo.snaps.core.internal.deployer.SnapFactory;
-import org.eclipse.virgo.snaps.core.internal.deployer.SnapLifecycleListener;
-import org.junit.Test;
-import org.osgi.framework.Version;
-
-import org.eclipse.virgo.nano.deployer.api.core.DeploymentException;
+import org.eclipse.gemini.web.tomcat.spi.WebBundleClassLoaderFactory;
 import org.eclipse.virgo.kernel.install.artifact.BundleInstallArtifact;
 import org.eclipse.virgo.medic.test.eventlog.MockEventLogger;
+import org.eclipse.virgo.nano.deployer.api.core.DeploymentException;
 import org.eclipse.virgo.test.stubs.framework.OSGiAssert;
 import org.eclipse.virgo.test.stubs.framework.StubBundle;
 import org.eclipse.virgo.test.stubs.framework.StubBundleContext;
-import org.eclipse.gemini.web.tomcat.spi.WebBundleClassLoaderFactory;
 import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
 import org.eclipse.virgo.util.osgi.manifest.internal.StandardBundleManifest;
+import org.junit.Test;
+import org.osgi.framework.Version;
 
 public class SnapLifecycleListenerTests {
 
@@ -65,4 +62,5 @@
 
         verify(installArtifact, classLoaderFactory);
     }
+
 }