bug 448004: Implement changes in classloading functionality.
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/DelegatingClassLoaderCustomizer.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/DelegatingClassLoaderCustomizer.java
index 5f9c2f9..9b82eda 100644
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/DelegatingClassLoaderCustomizer.java
+++ b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/DelegatingClassLoaderCustomizer.java
@@ -22,7 +22,7 @@
 import java.util.LinkedHashSet;
 import java.util.Set;
 
-import org.eclipse.gemini.web.tomcat.internal.loading.ChainedClassLoader;
+import org.eclipse.gemini.web.tomcat.internal.loader.ChainedClassLoader;
 import org.eclipse.gemini.web.tomcat.spi.ClassLoaderCustomizer;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BaseWebappLoader.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/BaseWebappLoader.java
similarity index 68%
rename from org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BaseWebappLoader.java
rename to org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/BaseWebappLoader.java
index 3ea5b4b..7027089 100644
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BaseWebappLoader.java
+++ b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/BaseWebappLoader.java
@@ -1,44 +1,34 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2010 VMware Inc.
+ * Copyright (c) 2009, 2015 VMware Inc.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
+ * and Apache License v2.0 which accompanies this distribution.
  * The Eclipse Public License is available at
  *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
+ * and the Apache License v2.0 is available at
  *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
+ * You may elect to redistribute this code under either of these licenses.
  *
  * Contributors:
  *   VMware Inc. - initial contribution
  *******************************************************************************/
 
-package org.eclipse.gemini.web.tomcat.internal.loading;
+package org.eclipse.gemini.web.tomcat.internal.loader;
 
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeSupport;
 
-import org.apache.catalina.Container;
 import org.apache.catalina.Context;
 import org.apache.catalina.Loader;
-import org.apache.catalina.core.StandardContext;
-import org.apache.catalina.loader.Constants;
-import org.apache.catalina.mbeans.MBeanUtils;
 import org.apache.catalina.util.LifecycleMBeanBase;
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
-import org.apache.tomcat.util.res.StringManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 abstract class BaseWebappLoader extends LifecycleMBeanBase implements Loader, PropertyChangeListener {
 
-    /**
-     * The string manager for this package.
-     */
-    protected static final StringManager sm = StringManager.getManager(Constants.Package);
-
-    protected final Log log = LogFactory.getLog(getClass());
+    protected final Logger log = LoggerFactory.getLogger(getClass());
 
     /**
      * The property change support for this Loader.
@@ -51,9 +41,9 @@
     private boolean delegate = false;
 
     /**
-     * The Container with which this Loader has been associated.
+     * The Context with which this Loader has been associated.
      */
-    private Container container = null;
+    private Context context = null;
 
     /**
      * The reloadable flag for this Loader.
@@ -76,22 +66,18 @@
     protected String getObjectNameKeyProperties() {
         StringBuilder name = new StringBuilder("type=Loader");
 
-        if (this.container instanceof Context) {
-            name.append(",context=");
-            Context context = (Context) this.container;
+        name.append(",host=");
+        name.append(this.context.getParent().getName());
 
-            name.append(getCatalinaContextPath(context));
-
-            name.append(",host=");
-            name.append(context.getParent().getName());
-        }
+        name.append(",context=");
+        name.append(getCatalinaContextPath(this.context));
 
         return name.toString();
     }
 
     @Override
     protected String getDomainInternal() {
-        return MBeanUtils.getDomain(this.container);
+        return this.context.getDomain();
     }
 
     // -------------------------------------------------------------------------
@@ -107,12 +93,12 @@
         if (this.reloadable && modified()) {
             try {
                 Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
-                if (getContainer() instanceof StandardContext) {
-                    ((StandardContext) getContainer()).reload();
+                if (this.context != null) {
+                    this.context.reload();
                 }
             } finally {
-                if (getContainer().getLoader() != null) {
-                    Thread.currentThread().setContextClassLoader(getContainer().getLoader().getClassLoader());
+                if (this.context != null && this.context.getLoader() != null) {
+                    Thread.currentThread().setContextClassLoader(this.context.getLoader().getClassLoader());
                 }
             }
         }
@@ -120,7 +106,7 @@
 
     /**
      * Add a property change listener to this component.
-     * 
+     *
      * @param listener The listener to add
      */
     @Override
@@ -129,33 +115,40 @@
     }
 
     /**
-     * Set the Container with which this Logger has been associated.
-     * 
-     * @param container The associated Container
+     * Set the Context with which this Logger has been associated.
+     *
+     * @param context The associated Context
      */
     @Override
-    public void setContainer(Container container) {
+    public void setContext(Context context) {
+        if (this.context == context) {
+            return;
+        }
 
-        // unregister from the old Container (if any)
-        if (this.container != null && this.container instanceof Context) {
-            ((Context) this.container).removePropertyChangeListener(this);
+        if (getState().isAvailable()) {
+            throw new IllegalStateException("Setting the Context is not permitted while the loader is started.");
+        }
+
+        // Deregister from the old Context (if any)
+        if (this.context != null) {
+            this.context.removePropertyChangeListener(this);
         }
 
         // Process this property change
-        Container oldContainer = this.container;
-        this.container = container;
-        this.support.firePropertyChange("container", oldContainer, this.container);
+        Context oldContext = this.context;
+        this.context = context;
+        this.support.firePropertyChange("context", oldContext, this.context);
 
         // Register with the new Container (if any)
-        if (this.container != null && this.container instanceof Context) {
-            setReloadable(((Context) this.container).getReloadable());
-            ((Context) this.container).addPropertyChangeListener(this);
+        if (this.context != null) {
+            setReloadable(this.context.getReloadable());
+            this.context.addPropertyChangeListener(this);
         }
     }
 
     @Override
-    public final Container getContainer() {
-        return this.container;
+    public final Context getContext() {
+        return this.context;
     }
 
     /**
@@ -176,7 +169,7 @@
 
     /**
      * Set the reloadable flag for this Loader.
-     * 
+     *
      * @param reloadable The new reloadable flag
      */
     @Override
@@ -197,7 +190,7 @@
 
     /**
      * Set the "follow standard delegation model" flag used to configure our ClassLoader.
-     * 
+     *
      * @param delegate The new flag
      */
     @Override
@@ -227,7 +220,7 @@
             try {
                 setReloadable(((Boolean) event.getNewValue()).booleanValue());
             } catch (Exception e) {
-                this.log.error(sm.getString("webappLoader.reloadable", event.getNewValue().toString()));
+                this.log.error("Cannot set reloadable property to [" + event.getNewValue().toString() + "].");
             }
         }
     }
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleClassPathURLExtractor.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleClassPathURLExtractor.java
similarity index 91%
rename from org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleClassPathURLExtractor.java
rename to org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleClassPathURLExtractor.java
index 841f7e5..49c47cc 100644
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleClassPathURLExtractor.java
+++ b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleClassPathURLExtractor.java
@@ -1,20 +1,20 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2014 VMware Inc.
+ * Copyright (c) 2009, 2015 VMware Inc.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
+ * and Apache License v2.0 which accompanies this distribution.
  * The Eclipse Public License is available at
  *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
+ * and the Apache License v2.0 is available at
  *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
+ * You may elect to redistribute this code under either of these licenses.
  *
  * Contributors:
  *   VMware Inc. - initial contribution
  *******************************************************************************/
 
-package org.eclipse.gemini.web.tomcat.internal.loading;
+package org.eclipse.gemini.web.tomcat.internal.loader;
 
 import java.net.URI;
 import java.net.URISyntaxException;
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDelegatingClassLoader.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleDelegatingClassLoader.java
old mode 100755
new mode 100644
similarity index 94%
rename from org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDelegatingClassLoader.java
rename to org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleDelegatingClassLoader.java
index 465858c..7d489f7
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDelegatingClassLoader.java
+++ b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleDelegatingClassLoader.java
@@ -1,19 +1,19 @@
 /******************************************************************************
- * Copyright (c) 2006, 2011 VMware Inc., Oracle Inc.
+ * Copyright (c) 2006, 2015 VMware Inc., Oracle Inc.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
- * The Eclipse Public License is available at 
+ * and Apache License v2.0 which accompanies this distribution.
+ * The Eclipse Public License is available at
  * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0
  * is available at http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses. 
- * 
+ * You may elect to redistribute this code under either of these licenses.
+ *
  * Contributors:
  *   VMware Inc.
  *   Oracle Inc.
  *****************************************************************************/
 
-package org.eclipse.gemini.web.tomcat.internal.loading;
+package org.eclipse.gemini.web.tomcat.internal.loader;
 
 import java.io.IOException;
 import java.net.URL;
@@ -26,9 +26,9 @@
 
 /**
  * ClassLoader backed by an OSGi bundle. Provides the ability to use a separate class loader as fall back.
- * 
+ *
  * This class is based on the one provided by Eclipse Gemini Blueprint.
- * 
+ *
  * @author Adrian Colyer
  * @author Andy Piper
  * @author Costin Leau
@@ -42,7 +42,7 @@
 
     /**
      * Factory method for creating a class loader over the given bundle.
-     * 
+     *
      * @param aBundle bundle to use for class loading and resource acquisition
      * @return class loader adapter over the given bundle
      */
@@ -53,7 +53,7 @@
     /**
      * Factory method for creating a class loader over the given bundle and with a given class loader as fall-back. In
      * case the bundle cannot find a class or locate a resource, the given class loader will be used as fall back.
-     * 
+     *
      * @param bundle bundle used for class loading and resource acquisition
      * @param bridge class loader used as fall back in case the bundle cannot load a class or find a resource. Can be
      *        <code>null</code>
@@ -71,9 +71,9 @@
 
     /**
      * Private constructor.
-     * 
+     *
      * Constructs a new <code>BundleDelegatingClassLoader</code> instance.
-     * 
+     *
      * @param bundle
      * @param bridgeLoader
      */
@@ -150,7 +150,7 @@
 
     /**
      * Returns the bundle to which this class loader delegates calls to.
-     * 
+     *
      * @return the backing bundle
      */
     public Bundle getBundle() {
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleWebappClassLoader.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleWebappClassLoader.java
similarity index 77%
rename from org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleWebappClassLoader.java
rename to org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleWebappClassLoader.java
index 24d853e..b9aa2d2 100644
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleWebappClassLoader.java
+++ b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleWebappClassLoader.java
@@ -1,20 +1,20 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2011 VMware Inc.
+ * Copyright (c) 2009, 2015 VMware Inc.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
+ * and Apache License v2.0 which accompanies this distribution.
  * The Eclipse Public License is available at
  *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
+ * and the Apache License v2.0 is available at
  *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
+ * You may elect to redistribute this code under either of these licenses.
  *
  * Contributors:
  *   VMware Inc. - initial contribution
  *******************************************************************************/
 
-package org.eclipse.gemini.web.tomcat.internal.loading;
+package org.eclipse.gemini.web.tomcat.internal.loader;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -34,21 +34,16 @@
 import org.apache.catalina.LifecycleException;
 import org.apache.catalina.LifecycleListener;
 import org.apache.catalina.LifecycleState;
-import org.apache.catalina.loader.Constants;
 import org.apache.tomcat.util.IntrospectionUtils;
-import org.apache.tomcat.util.res.StringManager;
 import org.eclipse.gemini.web.tomcat.spi.ClassLoaderCustomizer;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class BundleWebappClassLoader extends URLClassLoader implements Lifecycle, BundleReference {
 
-    /**
-     * The string manager for this package.
-     */
-    protected static final StringManager sm = StringManager.getManager(Constants.Package);
-
-    protected static final org.apache.juli.logging.Log log = org.apache.juli.logging.LogFactory.getLog(BundleWebappClassLoader.class);
+    private final Logger log = LoggerFactory.getLogger(getClass());
 
     /**
      * Has this class loader been started?
@@ -64,6 +59,8 @@
 
     private final Bundle bundle;
 
+    private volatile LifecycleState state = LifecycleState.NEW;
+
     // ------------------------------------------------------------------------
     // --- Constructors
     // ------------------------------------------------------------------------
@@ -150,12 +147,19 @@
 
     @Override
     public void destroy() throws LifecycleException {
-        /* no-op */
+        this.state = LifecycleState.DESTROYING;
+
+        try {
+            super.close();
+        } catch (IOException ioe) {
+            this.log.warn("Failure calling close() on super class", ioe);
+        }
+        this.state = LifecycleState.DESTROYED;
     }
 
     @Override
     public LifecycleState getState() {
-        return LifecycleState.NEW;
+        return this.state;
     }
 
     @Override
@@ -165,7 +169,7 @@
 
     @Override
     public void init() throws LifecycleException {
-        /* no-op */
+        this.state = LifecycleState.INITIALIZED;
     }
 
     /**
@@ -202,13 +206,13 @@
      * <ul>
      * <li>???</li>
      * </ul>
-     * 
+     *
      * @param name Name of the resource to return a URL for
      */
     @Override
     public URL getResource(String name) {
-        if (log.isDebugEnabled()) {
-            log.debug("getResource(" + name + ")");
+        if (this.log.isDebugEnabled()) {
+            this.log.debug("getResource(" + name + ")");
         }
 
         URL url = null;
@@ -219,8 +223,8 @@
         }
 
         // Resource was not found
-        if (log.isDebugEnabled()) {
-            log.debug("  --> Resource not found, returning null");
+        if (this.log.isDebugEnabled()) {
+            this.log.debug("Resource not found, returning null.");
         }
 
         return null;
@@ -228,7 +232,7 @@
 
     @Override
     public InputStream getResourceAsStream(String name) {
-        return super.getResourceAsStream(name);
+        return this.bundleDelegatingClassLoader.getResourceAsStream(name);
     }
 
     /**
@@ -236,8 +240,8 @@
      */
     @Override
     public Enumeration<URL> getResources(String name) throws IOException {
-        if (log.isDebugEnabled()) {
-            log.debug("getResources(" + name + ")");
+        if (this.log.isDebugEnabled()) {
+            this.log.debug("getResources(" + name + ")");
         }
 
         return this.bundleDelegatingClassLoader.getResources(name);
@@ -255,16 +259,16 @@
      * </ul>
      * If the class was found using the above steps, and the <code>resolve</code> flag is <code>true</code>, this method
      * will then call <code>resolveClass(Class)</code> on the resulting Class object.
-     * 
+     *
      * @param name Name of the class to be loaded
      * @param resolve If <code>true</code> then resolve the class
-     * 
+     *
      * @exception ClassNotFoundException if the class was not found
      */
     @Override
     public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
-        if (log.isDebugEnabled()) {
-            log.debug("loadClass(" + name + ", " + resolve + ")");
+        if (this.log.isDebugEnabled()) {
+            this.log.debug("loadClass(" + name + ", " + resolve + ")");
         }
 
         Class<?> clazz = null;
@@ -274,15 +278,17 @@
             try {
                 throw new IllegalStateException();
             } catch (IllegalStateException e) {
-                log.info(sm.getString("webappClassLoader.stopped", name), e);
+                this.log.info("Illegal access: this web application instance has been stopped already.  Could not load [" + name
+                    + "].  The eventual following stack trace is caused by an error thrown for debugging purposes"
+                    + "as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.", e);
             }
         }
 
         // Check our previously loaded class cache
         clazz = findLoadedClass(name);
         if (clazz != null) {
-            if (log.isDebugEnabled()) {
-                log.debug("  Returning class from cache");
+            if (this.log.isDebugEnabled()) {
+                this.log.debug("Returning class from cache.");
             }
             if (resolve) {
                 resolveClass(clazz);
@@ -291,14 +297,14 @@
         }
 
         // Search the application's bundle
-        if (log.isDebugEnabled()) {
-            log.debug("  Searching the application's bundle");
+        if (this.log.isDebugEnabled()) {
+            this.log.debug("Searching the application's bundle.");
         }
         try {
             clazz = this.bundleDelegatingClassLoader.loadClass(name);
             if (clazz != null) {
-                if (log.isDebugEnabled()) {
-                    log.debug("  Loading class from the delegating classloader");
+                if (this.log.isDebugEnabled()) {
+                    this.log.debug("Loading class from the delegating classloader.");
                 }
                 if (resolve) {
                     resolveClass(clazz);
@@ -331,7 +337,7 @@
                 try {
                     DriverManager.deregisterDriver(driver);
                 } catch (SQLException e) {
-                    log.warn("SQL driver deregistration failed", e);
+                    this.log.warn("SQL driver deregistration failed.", e);
                 }
             }
         }
@@ -352,4 +358,40 @@
     public Bundle getBundle() {
         return this.bundle;
     }
+
+    /**
+     * Set the clearReferencesStatic feature for this Context.
+     *
+     * @param clearReferencesStatic The new flag value
+     */
+    public void setClearReferencesStatic(boolean clearReferencesStatic) {
+        // no-op
+    }
+
+    /**
+     * Set the clearReferencesStopThreads feature for this Context.
+     *
+     * @param clearReferencesStopThreads The new flag value
+     */
+    public void setClearReferencesStopThreads(boolean clearReferencesStopThreads) {
+        // no-op
+    }
+
+    /**
+     * Set the clearReferencesStopTimerThreads feature for this Context.
+     *
+     * @param clearReferencesStopTimerThreads The new flag value
+     */
+    public void setClearReferencesStopTimerThreads(boolean clearReferencesStopTimerThreads) {
+        // no-op
+    }
+
+    /**
+     * Set the clearReferencesHttpClientKeepAliveThread feature for this Context.
+     *
+     * @param clearReferencesHttpClientKeepAliveThread The new flag value
+     */
+    public void setClearReferencesHttpClientKeepAliveThread(boolean clearReferencesHttpClientKeepAliveThread) {
+        // no-op
+    }
 }
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleWebappLoader.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleWebappLoader.java
similarity index 61%
rename from org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleWebappLoader.java
rename to org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleWebappLoader.java
index 15feabd..e188b6d 100644
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleWebappLoader.java
+++ b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleWebappLoader.java
@@ -1,22 +1,20 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2010 VMware Inc.
+ * Copyright (c) 2009, 2015 VMware Inc.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
+ * and Apache License v2.0 which accompanies this distribution.
  * The Eclipse Public License is available at
  *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
+ * and the Apache License v2.0 is available at
  *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
+ * You may elect to redistribute this code under either of these licenses.
  *
  * Contributors:
  *   VMware Inc. - initial contribution
  *******************************************************************************/
 
-package org.eclipse.gemini.web.tomcat.internal.loading;
-
-import java.beans.PropertyChangeListener;
+package org.eclipse.gemini.web.tomcat.internal.loader;
 
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
@@ -24,22 +22,18 @@
 
 import org.apache.catalina.Context;
 import org.apache.catalina.Globals;
-import org.apache.catalina.Lifecycle;
 import org.apache.catalina.LifecycleException;
 import org.apache.catalina.LifecycleState;
-import org.apache.catalina.Loader;
-import org.apache.catalina.core.StandardContext;
-import org.apache.catalina.mbeans.MBeanUtils;
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
-import org.apache.naming.resources.DirContextURLStreamHandler;
+import org.apache.tomcat.util.ExceptionUtils;
 import org.apache.tomcat.util.modeler.Registry;
 import org.eclipse.gemini.web.tomcat.spi.ClassLoaderCustomizer;
 import org.osgi.framework.Bundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-public class BundleWebappLoader extends BaseWebappLoader implements Loader, PropertyChangeListener {
+public class BundleWebappLoader extends BaseWebappLoader {
 
-    private static Log log = LogFactory.getLog(BundleWebappLoader.class);
+    private final Logger log = LoggerFactory.getLogger(getClass());
 
     /**
      * The OSGi {@link Bundle bundle} which will back the {@link ClassLoader} we will create.
@@ -59,12 +53,7 @@
     /**
      * The class loader being managed by this Loader.
      */
-    private ClassLoader classLoader = null;
-
-    /**
-     * The descriptive information about this Loader implementation.
-     */
-    private static final String INFO = BaseWebappLoader.class.getName() + "/1.0";
+    private BundleWebappClassLoader classLoader = null;
 
     // -------------------------------------------------------------------------
     // --- Constructors
@@ -84,7 +73,7 @@
      * @return
      * @see #getClassLoaderName()
      */
-    private ClassLoader createClassLoader() {
+    private BundleWebappClassLoader createClassLoader() {
         return new BundleWebappClassLoader(this.bundle, this.classLoaderCustomizer);
     }
 
@@ -93,22 +82,6 @@
     // -------------------------------------------------------------------------
 
     /**
-     * @throws UnsupportedOperationException always
-     */
-    @Override
-    public void addRepository(String repository) {
-        throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support addRepository(String)");
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String[] findRepositories() {
-        return new String[0];
-    }
-
-    /**
      * {@inheritDoc}
      */
     @Override
@@ -117,15 +90,6 @@
     }
 
     /**
-     * Return descriptive information about this Loader implementation and the corresponding version number, in the
-     * format <code>&lt;description&gt;/&lt;version&gt;</code>.
-     */
-    @Override
-    public String getInfo() {
-        return INFO;
-    }
-
-    /**
      * {@inheritDoc}
      */
     @Override
@@ -153,12 +117,12 @@
      */
     @Override
     public void startInternal() throws LifecycleException {
-        if (log.isDebugEnabled()) {
-            log.debug(sm.getString("webappLoader.starting"));
+        if (this.log.isDebugEnabled()) {
+            this.log.debug("Starting this loader.");
         }
 
-        if (getContainer().getResources() == null) {
-            log.info("No resources for " + getContainer());
+        if (getContext().getResources() == null) {
+            this.log.info("No resources for [" + getContext() + "].");
             setState(LifecycleState.STARTING);
             return;
         }
@@ -167,16 +131,14 @@
         try {
 
             this.classLoader = createClassLoader();
-            if (this.classLoader instanceof Lifecycle) {
-                ((Lifecycle) this.classLoader).start();
-            }
-
-            DirContextURLStreamHandler.bind(this.classLoader, getContainer().getResources());
+            this.classLoader.start();
 
             registerClassLoaderMBean();
 
         } catch (Throwable t) {
-            log.error("LifecycleException ", t);
+            t = ExceptionUtils.unwrapInvocationTargetException(t);
+            ExceptionUtils.handleThrowable(t);
+            this.log.error("LifecycleException ", t);
             throw new LifecycleException("start: ", t);
         }
 
@@ -188,25 +150,23 @@
      */
     @Override
     public void stopInternal() throws LifecycleException {
-        if (log.isDebugEnabled()) {
-            log.debug(sm.getString("webappLoader.stopping"));
+        if (this.log.isDebugEnabled()) {
+            this.log.debug("Stopping this loader.");
         }
 
         setState(LifecycleState.STOPPING);
 
         // Remove context attributes as appropriate
-        if (getContainer() instanceof Context) {
-            ServletContext servletContext = ((Context) getContainer()).getServletContext();
-            servletContext.removeAttribute(Globals.CLASS_PATH_ATTR);
-        }
+        ServletContext servletContext = getContext().getServletContext();
+        servletContext.removeAttribute(Globals.CLASS_PATH_ATTR);
 
         // Throw away our current class loader
-        if (this.classLoader instanceof Lifecycle) {
-            ((Lifecycle) this.classLoader).stop();
+        try {
+            this.classLoader.stop();
+        } finally {
+            this.classLoader.destroy();
         }
 
-        DirContextURLStreamHandler.unbind(this.classLoader);
-
         unregisterClassLoaderMBean();
 
         this.classLoader = null;
@@ -215,24 +175,22 @@
     }
 
     private void registerClassLoaderMBean() throws MalformedObjectNameException, Exception {
-        StandardContext ctx = (StandardContext) getContainer();
-        ObjectName classLoaderObjectName = createClassLoaderObjectName(ctx);
+        ObjectName classLoaderObjectName = createClassLoaderObjectName(getContext());
         Registry.getRegistry(null, null).registerComponent(this.classLoader, classLoaderObjectName, null);
     }
 
     private void unregisterClassLoaderMBean() {
         try {
-            StandardContext ctx = (StandardContext) getContainer();
-            ObjectName classLoaderObjectName = createClassLoaderObjectName(ctx);
+            ObjectName classLoaderObjectName = createClassLoaderObjectName(getContext());
             Registry.getRegistry(null, null).unregisterComponent(classLoaderObjectName);
         } catch (Throwable t) {
-            log.error("LifecycleException ", t);
+            this.log.error("LifecycleException ", t);
         }
     }
 
-    private ObjectName createClassLoaderObjectName(StandardContext ctx) throws MalformedObjectNameException {
-        return new ObjectName(MBeanUtils.getDomain(ctx) + ":type=OsgiWebappClassLoader,context=" + getCatalinaContextPath(ctx) + ",host="
-            + ctx.getParent().getName());
+    private ObjectName createClassLoaderObjectName(Context ctx) throws MalformedObjectNameException {
+        return new ObjectName(ctx.getDomain() + ":type=" + this.classLoader.getClass().getSimpleName() + ",host=" + ctx.getParent().getName()
+            + ",context=" + getCatalinaContextPath(ctx));
     }
 
 }
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/ChainedClassLoader.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/ChainedClassLoader.java
similarity index 96%
rename from org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/ChainedClassLoader.java
rename to org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/ChainedClassLoader.java
index 5912b68..0624d51 100644
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/ChainedClassLoader.java
+++ b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/ChainedClassLoader.java
@@ -1,20 +1,20 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2014 VMware Inc.
+ * Copyright (c) 2009, 2015 VMware Inc.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
+ * and Apache License v2.0 which accompanies this distribution.
  * The Eclipse Public License is available at
  *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
+ * and the Apache License v2.0 is available at
  *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
+ * You may elect to redistribute this code under either of these licenses.
  *
  * Contributors:
  *   VMware Inc. - initial contribution
  *******************************************************************************/
 
-package org.eclipse.gemini.web.tomcat.internal.loading;
+package org.eclipse.gemini.web.tomcat.internal.loader;
 
 import java.io.IOException;
 import java.net.URL;
@@ -34,7 +34,7 @@
 
 /**
  * <strong>Concurrent Semantics</strong><br />
- * 
+ *
  * This class is immutable and therefore thread safe.
  */
 public final class ChainedClassLoader extends ClassLoader implements BundleReference {
@@ -46,7 +46,7 @@
 
     /**
      * Constructs a new <code>ChainedClassLoader</code> instance.
-     * 
+     *
      * @param loaders array of non-null class loaders
      * @param parent parent class loader (can be null)
      */
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/StandardWebBundleClassLoaderFactory.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/StandardWebBundleClassLoaderFactory.java
similarity index 88%
rename from org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/StandardWebBundleClassLoaderFactory.java
rename to org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/StandardWebBundleClassLoaderFactory.java
index 623003b..06ec218 100644
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/StandardWebBundleClassLoaderFactory.java
+++ b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loader/StandardWebBundleClassLoaderFactory.java
@@ -1,20 +1,20 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2010 VMware Inc.
+ * Copyright (c) 2009, 2015 VMware Inc.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
+ * and Apache License v2.0 which accompanies this distribution.
  * The Eclipse Public License is available at
  *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
+ * and the Apache License v2.0 is available at
  *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
+ * You may elect to redistribute this code under either of these licenses.
  *
  * Contributors:
  *   VMware Inc. - initial contribution
  *******************************************************************************/
 
-package org.eclipse.gemini.web.tomcat.internal.loading;
+package org.eclipse.gemini.web.tomcat.internal.loader;
 
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -26,11 +26,11 @@
 /**
  * TODO Document StandardWebBundleClassLoaderFactory
  * <p />
- * 
+ *
  * <strong>Concurrent Semantics</strong><br />
- * 
+ *
  * TODO Document concurrent semantics of StandardWebBundleClassLoaderFactory
- * 
+ *
  */
 public class StandardWebBundleClassLoaderFactory implements WebBundleClassLoaderFactory {
 
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/AbstractReadOnlyDirContext.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/AbstractReadOnlyDirContext.java
deleted file mode 100644
index ea7ea04..0000000
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/AbstractReadOnlyDirContext.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2010 VMware Inc.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
- * The Eclipse Public License is available at
- *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
- *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
- *
- * Contributors:
- *   VMware Inc. - initial contribution
- *******************************************************************************/
-
-package org.eclipse.gemini.web.tomcat.internal.loading;
-
-import java.util.Hashtable;
-
-import javax.naming.Context;
-import javax.naming.Name;
-import javax.naming.NameParser;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.directory.Attributes;
-import javax.naming.directory.DirContext;
-import javax.naming.directory.ModificationItem;
-import javax.naming.directory.SearchControls;
-import javax.naming.directory.SearchResult;
-
-import org.apache.naming.resources.BaseDirContext;
-
-abstract class AbstractReadOnlyDirContext extends BaseDirContext {
-
-    @Override
-    public void bind(String name, Object obj, Attributes attrs) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void modifyAttributes(String name, int mod_op, Attributes attrs) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void rebind(String name, Object obj, Attributes attrs) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Object addToEnvironment(String propName, Object propVal) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void bind(String name, Object obj) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void rebind(String name, Object obj) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Object removeFromEnvironment(String propName) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void rename(String oldName, String newName) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void unbind(String name) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public DirContext createSubcontext(String name, Attributes attrs) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public DirContext getSchema(String name) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public DirContext getSchemaClassDefinition(String name) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public NamingEnumeration<SearchResult> search(String name, Attributes matchingAttributes) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public NamingEnumeration<SearchResult> search(String name, Attributes matchingAttributes, String[] attributesToReturn) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public NamingEnumeration<SearchResult> search(String name, String filter, SearchControls cons) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public NamingEnumeration<SearchResult> search(String name, String filterExpr, Object[] filterArgs, SearchControls cons) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Name composeName(Name name, Name prefix) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String composeName(String name, String prefix) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Context createSubcontext(String name) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void destroySubcontext(String name) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Hashtable<String, Object> getEnvironment() throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getNameInNamespace() throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public NameParser getNameParser(String name) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Object lookupLink(String name) throws NamingException {
-        throw new UnsupportedOperationException();
-    }
-
-}
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDirContext.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDirContext.java
deleted file mode 100644
index 3a9c7ae..0000000
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDirContext.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2014 VMware Inc.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
- * The Eclipse Public License is available at
- *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
- *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
- *
- * Contributors:
- *   VMware Inc. - initial contribution
- *******************************************************************************/
-
-package org.eclipse.gemini.web.tomcat.internal.loading;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map.Entry;
-
-import javax.naming.NameNotFoundException;
-import javax.naming.NamingException;
-import javax.naming.directory.Attributes;
-
-import org.apache.naming.NamingEntry;
-import org.osgi.framework.Bundle;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class BundleDirContext extends AbstractReadOnlyDirContext {
-
-    private final static Logger LOGGER = LoggerFactory.getLogger(BundleDirContext.class);
-
-    private volatile BundleEntry bundleEntry;
-
-    public BundleDirContext(Bundle bundle) {
-        this(new BundleEntry(bundle));
-    }
-
-    private BundleDirContext(BundleEntry bundleEntry) {
-        this.bundleEntry = bundleEntry;
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @return an enumeration of the bindings in this context or null if the name cannot be found. If null is returned
-     *         then <code>BaseDirContext.listBidings(String)</code> will continue to search in the alternative
-     *         locations.
-     */
-    @Override
-    public List<NamingEntry> doListBindings(String name) throws NamingException {
-        try {
-            return doSafeList(name);
-        } catch (NameNotFoundException e) {
-            if (LOGGER.isDebugEnabled()) {
-                LOGGER.debug("Name '" + name + "' does not exist.", e);
-            }
-            return null;
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @return the object bound to name or null if NamingException has occurred. If null is returned then
-     *         <code>BaseDirContext.lookup(String)</code> will continue to search in the alternative locations.
-     */
-    @Override
-    public Object doLookup(String name) {
-        try {
-            Entry<BundleEntry, URL> entry = getNamedEntry(name);
-            return entryToResult(entry.getKey(), entry.getValue());
-        } catch (NamingException e) {
-            if (LOGGER.isDebugEnabled()) {
-                LOGGER.debug("", e);
-            }
-            return null;
-        }
-    }
-
-    private List<NamingEntry> doSafeList(String name) throws NamingException {
-        Entry<BundleEntry, URL> entry = getNamedEntry(name);
-        return doList(entry.getKey());
-    }
-
-    private Entry<BundleEntry, URL> getNamedEntry(String name) throws NamingException {
-        checkCanLookup(name);
-        Entry<BundleEntry, URL> namedEntry = this.bundleEntry.getEntry(name);
-        if (namedEntry == null) {
-            throw new NameNotFoundException("Name '" + name + "' does not exist.");
-        }
-        return namedEntry;
-    }
-
-    private List<NamingEntry> doList(BundleEntry bundleEntry) {
-        List<BundleEntry> list = bundleEntry.list();
-        List<NamingEntry> resources = new ArrayList<>();
-        for (BundleEntry entry : list) {
-            Object object;
-            object = entryToResult(entry);
-            resources.add(new NamingEntry(entry.getName(), object, NamingEntry.ENTRY));
-        }
-        return resources;
-    }
-
-    private Object entryToResult(BundleEntry entry) {
-        return entryToResult(entry, entry.getURL());
-    }
-
-    private Object entryToResult(BundleEntry entry, URL url) {
-        Object result;
-        if (BundleEntry.isDirectory(url)) {
-            result = new BundleDirContext(entry);
-        } else {
-            result = new URLResource(url);
-        }
-        return result;
-    }
-
-    private void checkCanLookup(String name) throws NamingException {
-        BundleEntry entry = this.bundleEntry;
-        if (entry == null || entry.getBundle().getState() == Bundle.UNINSTALLED) {
-            throw new NamingException("Resource not found '" + name + "'");
-        }
-        checkNotAttemptingToLookupFromProtectedLocation(name);
-    }
-
-    private void checkNotAttemptingToLookupFromProtectedLocation(String name) throws NamingException {
-        checkNotAttemptingToLookupFrom(name, "/OSGI-INF/");
-        checkNotAttemptingToLookupFrom(name, "/OSGI-OPT/");
-    }
-
-    private void checkNotAttemptingToLookupFrom(String name, String prefix) throws NamingException {
-        if (name.startsWith(prefix)) {
-            throw new NamingException("Resource cannot be obtained from " + prefix);
-        }
-    }
-
-    @Override
-    public void close() throws NamingException {
-        super.close();
-        this.bundleEntry = null;
-    }
-
-    /**
-     * Retrieves selected attributes associated with a named object.
-     * 
-     * @return the requested attributes or null if the specified name does not exists. If null is returned then
-     *         <code>BaseDirContext.getAttributes(String, String[])</code> will continue to search in the alternative
-     *         locations.
-     * @param name the name of the object from which to retrieve attributes
-     * @param attrIds the identifiers of the attributes to retrieve. null indicates that all attributes should be
-     *        retrieved; an empty array indicates that none should be retrieved
-     * @exception NamingException if a naming exception is encountered
-     */
-    @Override
-    protected Attributes doGetAttributes(String name, String[] attrIds) throws NamingException {
-        try {
-            Entry<BundleEntry, URL> entry = getNamedEntry(name);
-            return new BundleEntryAttributes(entry.getKey(), attrIds, entry.getValue());
-        } catch (NameNotFoundException e) {
-            if (LOGGER.isDebugEnabled()) {
-                LOGGER.debug("Name '" + name + "' does not exist.", e);
-            }
-            return null;
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     * 
-     * @return Returns the real path for a given virtual path, if possible; otherwise returns null. If null is returned
-     *         then <code>BaseDirContext.getRealPath(String)</code> will continue to search in the alternative
-     *         locations.
-     */
-    @Override
-    protected String doGetRealPath(String path) {
-        if (this.bundleEntry.isBundleLocationDirectory()) {
-            boolean checkInBundleLocation = path != null && path.indexOf("..") >= 0;
-            String bundleLocationCanonicalPath = this.bundleEntry.getBundleLocationCanonicalPath();
-            File entry = new File(bundleLocationCanonicalPath, path);
-            if (checkInBundleLocation) {
-                try {
-                    if (!entry.getCanonicalPath().startsWith(bundleLocationCanonicalPath)) {
-                        return null;
-                    }
-                } catch (IOException e) {
-                    return null;
-                }
-            }
-            return entry.getAbsolutePath();
-        }
-        return null;
-    }
-}
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntry.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntry.java
deleted file mode 100644
index f060b8b..0000000
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntry.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2014 VMware Inc.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
- * The Eclipse Public License is available at
- *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
- *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
- *
- * Contributors:
- *   VMware Inc. - initial contribution
- *******************************************************************************/
-
-package org.eclipse.gemini.web.tomcat.internal.loading;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.eclipse.gemini.web.tomcat.internal.support.BundleFileResolver;
-import org.eclipse.gemini.web.tomcat.internal.support.BundleFileResolverFactory;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
-import org.osgi.framework.wiring.BundleWiring;
-
-public final class BundleEntry {
-
-    private static final String WEB_INF_DOT = "WEB-INF.";
-
-    private static final String META_INF_DOT = "META-INF.";
-
-    private static final String META_INF = "META-INF";
-
-    private static final String OSGI_INF_DOT = "OSGI-INF.";
-
-    private static final String OSGI_OPT_DOT = "OSGI-OPT.";
-
-    private static final String PATH_SEPARATOR = "/";
-
-    private static final String DOT = ".";
-
-    private final String path;
-
-    private final Bundle bundle;
-
-    private final List<Bundle> fragments;
-
-    private final BundleFileResolver bundleFileResolver = BundleFileResolverFactory.createBundleFileResolver();
-
-    private final boolean checkEntryPath;
-
-    private String bundleLocationCanonicalPath;
-
-    private boolean isBundleLocationDirectory;
-
-    public BundleEntry(Bundle bundle) {
-        this.path = "";
-        this.bundle = bundle;
-        this.fragments = getFragments(bundle);
-        this.checkEntryPath = checkEntryPath();
-        File bundleLocation = this.bundleFileResolver.resolve(bundle);
-        if (bundleLocation != null) {
-            try {
-                this.bundleLocationCanonicalPath = bundleLocation.getCanonicalPath();
-            } catch (IOException e) {
-            }
-            if (bundleLocation.isDirectory()) {
-                this.isBundleLocationDirectory = true;
-            }
-        }
-    }
-
-    private BundleEntry(Bundle bundle, List<Bundle> fragments, String path, boolean checkEntryPath, String bundleLocationCanonicalPath,
-        boolean isBundleLocationDirectory) {
-        this.path = path;
-        this.bundle = bundle;
-        this.fragments = fragments;
-        this.checkEntryPath = checkEntryPath;
-        this.bundleLocationCanonicalPath = bundleLocationCanonicalPath;
-        this.isBundleLocationDirectory = isBundleLocationDirectory;
-    }
-
-    public Bundle getBundle() {
-        return this.bundle;
-    }
-
-    public List<BundleEntry> list() {
-        List<BundleEntry> entries = new ArrayList<>();
-        Set<String> paths = getEntryPathsFromBundle();
-        if (paths != null) {
-            Iterator<String> iterator = paths.iterator();
-            while (iterator.hasNext()) {
-                String subPath = iterator.next();
-                entries.add(createBundleEntry(subPath));
-            }
-        }
-        return entries;
-    }
-
-    private BundleEntry createBundleEntry(String path) {
-        return new BundleEntry(this.bundle, this.fragments, path, this.checkEntryPath, this.bundleLocationCanonicalPath,
-            this.isBundleLocationDirectory);
-    }
-
-    private Set<String> getEntryPathsFromBundle() {
-        Set<String> paths = getEntryPathsFromBundle(this.bundle);
-
-        for (int i = 0; i < this.fragments.size(); i++) {
-            paths.addAll(getEntryPathsFromBundle(this.fragments.get(i)));
-        }
-
-        if (paths.isEmpty()) {
-            return null;
-        }
-
-        return paths;
-    }
-
-    private Set<String> getEntryPathsFromBundle(Bundle bundle) {
-        final Enumeration<String> ep = bundle.getEntryPaths(this.path);
-
-        Set<String> paths = new HashSet<>();
-        if (ep != null) {
-            while (ep.hasMoreElements()) {
-                paths.add(ep.nextElement());
-            }
-        }
-
-        return paths;
-    }
-
-    public Entry<BundleEntry, URL> getEntry(String subPath) {
-        String finalPath = this.path + subPath;
-        URL entryURL = getEntryFromBundle(finalPath);
-        if (entryURL != null) {
-            Map<BundleEntry, URL> result = new HashMap<>();
-            result.put(createBundleEntry(finalPath), entryURL);
-            return result.entrySet().iterator().next();
-        }
-        return null;
-    }
-
-    /**
-     * This method has been generalized from this.bundle.getEntry(path) to allow entries to be supplied by a fragment.
-     */
-    private URL getEntryFromBundle(String path) {
-        if (this.checkEntryPath
-            && (checkNotAttemptingToAccess(path, META_INF_DOT) || checkNotAttemptingToAccess(path, WEB_INF_DOT)
-                || checkNotAttemptingToAccess(path, OSGI_INF_DOT) || checkNotAttemptingToAccess(path, OSGI_OPT_DOT))) {
-            return null;
-        }
-
-        if (path.endsWith(PATH_SEPARATOR) || path.length() == 0) {
-            return this.bundle.getEntry(path);
-        }
-
-        String searchPath;
-        String searchFile;
-        int lastSlashIndex = path.lastIndexOf(PATH_SEPARATOR);
-        if (lastSlashIndex == -1) {
-            searchPath = PATH_SEPARATOR;
-            searchFile = path;
-        } else {
-            searchPath = path.substring(0, lastSlashIndex);
-            searchFile = path.substring(lastSlashIndex + 1);
-        }
-
-        if (searchFile.equals(DOT)) {
-            return this.bundle.getEntry(path.substring(0, path.length() - 1));
-        }
-
-        Enumeration<URL> entries = this.bundle.findEntries(searchPath, searchFile, false);
-
-        if (entries != null) {
-            if (entries.hasMoreElements()) {
-                return entries.nextElement();
-            }
-        }
-
-        return null;
-    }
-
-    private boolean checkNotAttemptingToAccess(String path, String prefix) {
-        return path.startsWith(prefix + PATH_SEPARATOR) || path.startsWith(PATH_SEPARATOR + prefix + PATH_SEPARATOR)
-            || path.startsWith(DOT + PATH_SEPARATOR + prefix + PATH_SEPARATOR);
-    }
-
-    public String getName() {
-        String name = this.path;
-
-        if (name.endsWith(PATH_SEPARATOR)) {
-            name = name.substring(0, this.path.length() - 1);
-        }
-
-        int index = name.lastIndexOf(PATH_SEPARATOR);
-        if (index > -1) {
-            name = name.substring(index + 1);
-        }
-
-        if (name.length() == 0) {
-            return PATH_SEPARATOR;
-        }
-        return name;
-    }
-
-    public URL getURL() {
-        return getEntryFromBundle(this.path);
-    }
-
-    public String getPath() {
-        return this.path;
-    }
-
-    public static boolean isDirectory(URL url) {
-        return url.getFile().endsWith(PATH_SEPARATOR);
-    }
-
-    @Override
-    public String toString() {
-        return String.format("BundleEntry [bundle=%s,path=%s]", this.bundle, this.path);
-    }
-
-    /**
-     * Returns the bundle entry size. If the BundleFileResolver is EquinoxBundleFileResolver then we will use equinox
-     * specific functionality to get BundleEntry and its size. If the BundleFileResolver is NoOpBundleFileResolver we
-     * will use URLConnection.getContentLength(). Note: URLConnection.getContentLength() returns "int", if the bundle
-     * entry size exceeds max "int", then the content length will not be correct.
-     * 
-     * @return the bundle entry size
-     */
-    public long getContentLength(URLConnection urlConnection) {
-        long size = this.bundleFileResolver.resolveBundleEntrySize(this.bundle, this.path);
-        if (size == -1 && urlConnection != null) {
-            size = urlConnection.getContentLength();
-        }
-        return size;
-    }
-
-    private List<Bundle> getFragments(Bundle bundle) {
-        List<Bundle> fragments = new ArrayList<>();
-        BundleRevision bundleRevision = bundle.adapt(BundleRevision.class);
-        if (bundleRevision != null) {
-            BundleWiring bundleWiring = bundleRevision.getWiring();
-            List<BundleWire> bundleWires = bundleWiring.getProvidedWires(BundleRevision.HOST_NAMESPACE);
-            for (int i = 0; bundleWires != null && i < bundleWires.size(); i++) {
-                fragments.add(bundleWires.get(i).getRequirerWiring().getRevision().getBundle());
-            }
-        }
-        return fragments;
-    }
-
-    private boolean checkEntryPath() {
-        try {
-            return new File(META_INF).getCanonicalPath().equals(new File(META_INF_DOT).getCanonicalPath());
-        } catch (IOException e) {
-            return true;
-        }
-    }
-
-    public String getBundleLocationCanonicalPath() {
-        return this.bundleLocationCanonicalPath;
-    }
-
-    public boolean isBundleLocationDirectory() {
-        return this.isBundleLocationDirectory;
-    }
-}
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntryAttributes.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntryAttributes.java
deleted file mode 100644
index feda801..0000000
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntryAttributes.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2014 VMware Inc.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
- * The Eclipse Public License is available at
- *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
- *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
- *
- * Contributors:
- *   VMware Inc. - initial contribution
- *******************************************************************************/
-
-package org.eclipse.gemini.web.tomcat.internal.loading;
-
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLConnection;
-
-import javax.naming.directory.Attributes;
-
-import org.apache.naming.resources.ResourceAttributes;
-
-/**
- * {@link BundleEntryAttributes} provides the default {@link Attributes} for a {@link BundleEntry}.
- */
-final class BundleEntryAttributes extends ResourceAttributes {
-
-    private static final int CREATION_DATE_UNKNOWN = 0;
-
-    private static final long TIME_NOT_SET = -1L;
-
-    private static final long CONTENT_LENGTH_NOT_SET = -1L;
-
-    private static final long serialVersionUID = 7799793247259935763L;
-
-    private final transient BundleEntry bundleEntry;
-
-    private final String[] attrIds;
-
-    /**
-     * Creates a {@link BundleEntryAttributes} for the given {@link BundleEntry} and attribute identifier array.
-     * 
-     * @param bundleEntry the <code>BundleEntry</code> from which to retrieve attributes
-     * @param attrIds the identifiers of the attributes to retrieve, or <code>null</code> if all attributes should be
-     *        retrieved
-     */
-    BundleEntryAttributes(BundleEntry bundleEntry, String[] attrIds, URL url) {
-        this.bundleEntry = bundleEntry;
-        this.attrIds = attrIds;
-        getName();
-        if (url != null) {
-            setCollection(BundleEntry.isDirectory(url));
-        }
-        URLConnection urlConnection = getBundleEntryURLConnection(url);
-        if (urlConnection != null) {
-            long lastModified = getLastModified(urlConnection);
-            getCreation(urlConnection, lastModified);
-            getContentLength(urlConnection);
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public long getCreation() {
-        return getCreation(null, TIME_NOT_SET);
-    }
-
-    private long getCreation(URLConnection urlConnection, long lastModified) {
-        long creation = TIME_NOT_SET;
-
-        if (attrPresent(CREATION_DATE) || attrPresent(ALTERNATE_CREATION_DATE)) {
-            creation = super.getCreation();
-
-            if (creation == TIME_NOT_SET) {
-                if (urlConnection == null) {
-                    urlConnection = getBundleEntryURLConnection(this.bundleEntry.getURL());
-                }
-
-                if (urlConnection != null) {
-                    creation = determineDate(urlConnection);
-
-                    if (creation == CREATION_DATE_UNKNOWN) {
-                        if (lastModified == TIME_NOT_SET) {
-                            lastModified = determineLastModified(urlConnection);
-                        }
-
-                        creation = lastModified;
-                    }
-                }
-
-                if (creation != TIME_NOT_SET) {
-                    setCreation(creation);
-                }
-            }
-        }
-
-        return creation;
-    }
-
-    private long determineDate(URLConnection urlConnection) {
-        return urlConnection.getDate();
-    }
-
-    private boolean attrPresent(String attrId) {
-        if (this.attrIds == null) {
-            return true;
-        }
-
-        for (String ai : this.attrIds) {
-            if (ai.equals(attrId)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public long getLastModified() {
-        return getLastModified(null);
-    }
-
-    private long getLastModified(URLConnection urlConnection) {
-        long lastModified = TIME_NOT_SET;
-
-        if (attrPresent(LAST_MODIFIED) || attrPresent(ALTERNATE_LAST_MODIFIED)) {
-            lastModified = super.getLastModified();
-
-            if (lastModified == TIME_NOT_SET) {
-                if (urlConnection == null) {
-                    urlConnection = getBundleEntryURLConnection(this.bundleEntry.getURL());
-                }
-
-                if (urlConnection != null) {
-                    lastModified = determineLastModified(urlConnection);
-                }
-
-                if (lastModified != TIME_NOT_SET) {
-                    setLastModified(lastModified);
-                }
-            }
-        }
-
-        return lastModified;
-    }
-
-    private long determineLastModified(URLConnection urlConnection) {
-        return urlConnection.getLastModified();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getName() {
-        if (!attrPresent(NAME)) {
-            return null;
-        }
-
-        String name = super.getName();
-        if (name == null) {
-            name = this.bundleEntry.getName();
-        }
-        return name;
-    }
-
-    @Override
-    public long getContentLength() {
-        return getContentLength(null);
-    }
-
-    private long getContentLength(URLConnection urlConnection) {
-        long contentLength = CONTENT_LENGTH_NOT_SET;
-
-        if (attrPresent(CONTENT_LENGTH) || attrPresent(ALTERNATE_CONTENT_LENGTH)) {
-            contentLength = super.getContentLength();
-
-            if (contentLength == CONTENT_LENGTH_NOT_SET) {
-                if (urlConnection == null) {
-                    urlConnection = getBundleEntryURLConnection(this.bundleEntry.getURL());
-                }
-
-                contentLength = determineContentLength(urlConnection);
-
-                if (contentLength != CONTENT_LENGTH_NOT_SET) {
-                    setContentLength(contentLength);
-                }
-            }
-        }
-
-        return contentLength;
-    }
-
-    private long determineContentLength(URLConnection urlConnection) {
-        return this.bundleEntry.getContentLength(urlConnection);
-    }
-
-    private URLConnection getBundleEntryURLConnection(URL url) {
-        try {
-            if (url != null) {
-                return url.openConnection();
-            }
-            return null;
-        } catch (IOException e) {
-            return null;
-        }
-    }
-
-}
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/DirContextURLStreamHandlerService.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/DirContextURLStreamHandlerService.java
deleted file mode 100644
index f15f897..0000000
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/DirContextURLStreamHandlerService.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2010 VMware Inc.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
- * The Eclipse Public License is available at
- *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
- *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
- *
- * Contributors:
- *   VMware Inc. - initial contribution
- *******************************************************************************/
-
-package org.eclipse.gemini.web.tomcat.internal.loading;
-
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLConnection;
-
-import org.apache.naming.resources.DirContextURLStreamHandler;
-import org.osgi.service.url.AbstractURLStreamHandlerService;
-
-public class DirContextURLStreamHandlerService extends AbstractURLStreamHandlerService {
-
-    private final DirContextURLStreamHandler handler = new DirContextURLStreamHandler();
-
-    @Override
-    public URLConnection openConnection(URL u) throws IOException {
-        return new URL(null, u.toExternalForm(), this.handler).openConnection();
-    }
-
-}
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/URLResource.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/URLResource.java
deleted file mode 100644
index 8d9d266..0000000
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/URLResource.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2010 VMware Inc.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
- * The Eclipse Public License is available at
- *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
- *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
- *
- * Contributors:
- *   VMware Inc. - initial contribution
- *******************************************************************************/
-
-package org.eclipse.gemini.web.tomcat.internal.loading;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-
-import org.apache.naming.resources.Resource;
-
-final class URLResource extends Resource {
-
-    private final URL url;
-
-    public URLResource(URL url) {
-        this.url = url;
-    }
-
-    @Override
-    public InputStream streamContent() throws IOException {
-        if (this.binaryContent == null) {
-            this.inputStream = this.url.openStream();
-        }
-        return super.streamContent();
-
-    }
-
-}
diff --git a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleClassPathURLExtractorTests.java b/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleClassPathURLExtractorTests.java
similarity index 90%
rename from org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleClassPathURLExtractorTests.java
rename to org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleClassPathURLExtractorTests.java
index 5b9a061..6682e79 100644
--- a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleClassPathURLExtractorTests.java
+++ b/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleClassPathURLExtractorTests.java
@@ -1,20 +1,20 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2010 VMware Inc.
+ * Copyright (c) 2009, 2015 VMware Inc.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
+ * and Apache License v2.0 which accompanies this distribution.
  * The Eclipse Public License is available at
  *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
+ * and the Apache License v2.0 is available at
  *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
+ * You may elect to redistribute this code under either of these licenses.
  *
  * Contributors:
  *   VMware Inc. - initial contribution
  *******************************************************************************/
 
-package org.eclipse.gemini.web.tomcat.internal.loading;
+package org.eclipse.gemini.web.tomcat.internal.loader;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
diff --git a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDelegatingClassLoaderTests.java b/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleDelegatingClassLoaderTests.java
old mode 100755
new mode 100644
similarity index 96%
rename from org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDelegatingClassLoaderTests.java
rename to org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleDelegatingClassLoaderTests.java
index b782a68..ce0d2b3
--- a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDelegatingClassLoaderTests.java
+++ b/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loader/BundleDelegatingClassLoaderTests.java
@@ -1,18 +1,18 @@
 /******************************************************************************
- * Copyright (c) 2006, 2014 VMware Inc.
+ * Copyright (c) 2006, 2015 VMware Inc.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
- * The Eclipse Public License is available at 
+ * and Apache License v2.0 which accompanies this distribution.
+ * The Eclipse Public License is available at
  * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0
  * is available at http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses. 
- * 
+ * You may elect to redistribute this code under either of these licenses.
+ *
  * Contributors:
  *   VMware Inc.
  *****************************************************************************/
 
-package org.eclipse.gemini.web.tomcat.internal.loading;
+package org.eclipse.gemini.web.tomcat.internal.loader;
 
 import static org.easymock.EasyMock.createStrictControl;
 import static org.easymock.EasyMock.expect;
@@ -35,7 +35,7 @@
 
 /**
  * This class is based on the one provided by Eclipse Gemini Blueprint.
- * 
+ *
  * @author Costin Leau
  * @author Violeta Georgieva
  */
diff --git a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/ChainedClassLoaderTests.java b/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loader/ChainedClassLoaderTests.java
similarity index 89%
rename from org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/ChainedClassLoaderTests.java
rename to org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loader/ChainedClassLoaderTests.java
index 42487b0..48caeb2 100644
--- a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/ChainedClassLoaderTests.java
+++ b/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loader/ChainedClassLoaderTests.java
@@ -1,20 +1,20 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2010 VMware Inc.
+ * Copyright (c) 2009, 2015 VMware Inc.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
+ * and Apache License v2.0 which accompanies this distribution.
  * The Eclipse Public License is available at
  *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
+ * and the Apache License v2.0 is available at
  *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
+ * You may elect to redistribute this code under either of these licenses.
  *
  * Contributors:
  *   VMware Inc. - initial contribution
  *******************************************************************************/
 
-package org.eclipse.gemini.web.tomcat.internal.loading;
+package org.eclipse.gemini.web.tomcat.internal.loader;
 
 import static org.junit.Assert.assertNotNull;
 
diff --git a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/FindEntriesDelegateImpl.java b/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loader/FindEntriesDelegateImpl.java
similarity index 92%
rename from org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/FindEntriesDelegateImpl.java
rename to org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loader/FindEntriesDelegateImpl.java
index ba186cc..3e6505c 100644
--- a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/FindEntriesDelegateImpl.java
+++ b/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loader/FindEntriesDelegateImpl.java
@@ -1,5 +1,5 @@
 /*******************************************************************************

- * Copyright (c) 2014 SAP AG

+ * Copyright (c) 2014, 2015 SAP SE

  *

  * All rights reserved. This program and the accompanying materials

  * are made available under the terms of the Eclipse Public License v1.0

@@ -14,7 +14,7 @@
  *   Violeta Georgieva - initial contribution

  *******************************************************************************/

 

-package org.eclipse.gemini.web.tomcat.internal.loading;

+package org.eclipse.gemini.web.tomcat.internal.loader;

 

 import java.net.URL;

 import java.util.Enumeration;

@@ -24,7 +24,7 @@
 

 public class FindEntriesDelegateImpl implements FindEntriesDelegate {

 

-    private Bundle testBundle;

+    private final Bundle testBundle;

 

     public FindEntriesDelegateImpl(Bundle testBundle) {

         this.testBundle = testBundle;

diff --git a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDirContextTests.java b/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDirContextTests.java
deleted file mode 100644
index e22d765..0000000
--- a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDirContextTests.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2014 VMware Inc.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
- * The Eclipse Public License is available at
- *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
- *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
- *
- * Contributors:
- *   VMware Inc. - initial contribution
- *******************************************************************************/
-
-package org.eclipse.gemini.web.tomcat.internal.loading;
-
-import java.io.File;
-
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.directory.Attribute;
-import javax.naming.directory.Attributes;
-
-import org.eclipse.virgo.test.stubs.framework.StubBundle;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class BundleDirContextTests {
-
-    private static final String FILE_NAME = "sub/one.txt";
-
-    private static final String DIRECTORY_NAME = "sub/";
-
-    private final StubBundle testBundle = new StubBundle();
-
-    private BundleDirContext bundleDirContext;
-
-    @Before
-    public void setUp() throws Exception {
-        this.testBundle.addEntry("", new File("src/test/resources/").toURI().toURL());
-        this.testBundle.addEntry(DIRECTORY_NAME, new File("src/test/resources/sub/").toURI().toURL());
-        this.testBundle.addEntry(FILE_NAME, new File("src/test/resources/sub/one.txt").toURI().toURL());
-        this.testBundle.setFindEntriesDelegate(new FindEntriesDelegateImpl(this.testBundle));
-
-        this.bundleDirContext = new BundleDirContext(this.testBundle);
-    }
-
-    @Test(expected = NamingException.class)
-    public void testDoGetAttributesStringStringArrayNameNotFound() throws NamingException {
-        this.bundleDirContext.getAttributes("sub", null);
-    }
-
-    @Test
-    public void testGetAttributesOfDirectory() throws NamingException {
-        Attributes attributes = this.bundleDirContext.getAttributes(DIRECTORY_NAME);
-
-        checkName(attributes, DIRECTORY_NAME.substring(0, DIRECTORY_NAME.length() - 1));
-
-        checkDirectoryResourceType(attributes);
-
-        checkTimes(attributes);
-
-        checkContentLength(attributes);
-    }
-
-    private void checkContentLength(Attributes attributes) {
-        Attribute contentLength = attributes.get(org.apache.naming.resources.ResourceAttributes.CONTENT_LENGTH);
-        Assert.assertNotNull(contentLength);
-
-        contentLength = attributes.get(org.apache.naming.resources.ResourceAttributes.ALTERNATE_CONTENT_LENGTH);
-        Assert.assertNotNull(contentLength);
-    }
-
-    private void checkName(Attributes attributes, String expectedName) throws NamingException {
-        Attribute name = attributes.get(org.apache.naming.resources.ResourceAttributes.NAME);
-        Assert.assertNotNull(name);
-        NamingEnumeration<?> namingEnumeration = name.getAll();
-        Assert.assertTrue(namingEnumeration.hasMore());
-        String nameValue = (String) namingEnumeration.next();
-        Assert.assertEquals(expectedName, nameValue);
-    }
-
-    private void checkDirectoryResourceType(Attributes attributes) throws NamingException {
-        Attribute resourceType = attributes.get(org.apache.naming.resources.ResourceAttributes.TYPE);
-        checkCollectionResourceType(resourceType);
-
-        resourceType = attributes.get(org.apache.naming.resources.ResourceAttributes.ALTERNATE_TYPE);
-        checkCollectionResourceType(resourceType);
-    }
-
-    private void checkCollectionResourceType(Attribute resourceType) throws NamingException {
-        Assert.assertNotNull(resourceType);
-        NamingEnumeration<?> namingEnumeration = resourceType.getAll();
-        Assert.assertTrue(namingEnumeration.hasMore());
-        String resourceTypeValue = (String) namingEnumeration.next();
-        Assert.assertEquals(org.apache.naming.resources.ResourceAttributes.COLLECTION_TYPE, resourceTypeValue);
-    }
-
-    @Test
-    public void testGetAttributesOfFile() throws NamingException {
-        Attributes attributes = this.bundleDirContext.getAttributes(FILE_NAME);
-
-        checkName(attributes, FILE_NAME.split("/")[1]);
-
-        checkNoResourceType(attributes);
-
-        checkTimes(attributes);
-
-        checkContentLength(attributes);
-    }
-
-    private void checkNoResourceType(Attributes attributes) {
-        Attribute resourceType = attributes.get(org.apache.naming.resources.ResourceAttributes.TYPE);
-        Assert.assertNull(resourceType);
-    }
-
-    private void checkTimes(Attributes attributes) {
-        Attribute creationDate = attributes.get(org.apache.naming.resources.ResourceAttributes.CREATION_DATE);
-        Assert.assertNotNull(creationDate);
-
-        creationDate = attributes.get(org.apache.naming.resources.ResourceAttributes.ALTERNATE_CREATION_DATE);
-        Assert.assertNotNull(creationDate);
-
-        Attribute lastModified = attributes.get(org.apache.naming.resources.ResourceAttributes.LAST_MODIFIED);
-        Assert.assertNotNull(lastModified);
-
-        lastModified = attributes.get(org.apache.naming.resources.ResourceAttributes.ALTERNATE_LAST_MODIFIED);
-        Assert.assertNotNull(lastModified);
-    }
-
-    @Test
-    public void testGetNoAttributesOfFile() throws NamingException {
-        Attributes attributes = this.bundleDirContext.getAttributes(FILE_NAME, new String[] {});
-
-        checkNoName(attributes);
-
-        checkNoResourceType(attributes);
-
-        checkNoTimes(attributes);
-
-        checkNoContentLength(attributes);
-    }
-
-    private void checkNoContentLength(Attributes attributes) {
-        Attribute contentLength = attributes.get(org.apache.naming.resources.ResourceAttributes.CONTENT_LENGTH);
-        Assert.assertNull(contentLength);
-
-        contentLength = attributes.get(org.apache.naming.resources.ResourceAttributes.ALTERNATE_CONTENT_LENGTH);
-        Assert.assertNull(contentLength);
-    }
-
-    /**
-     * @throws NamingException
-     */
-    private void checkNoName(Attributes attributes) throws NamingException {
-        Attribute name = attributes.get(org.apache.naming.resources.ResourceAttributes.NAME);
-        Assert.assertNull(name);
-
-    }
-
-    private void checkNoTimes(Attributes attributes) {
-        Attribute creationDate = attributes.get(org.apache.naming.resources.ResourceAttributes.CREATION_DATE);
-        Assert.assertNull(creationDate);
-
-        creationDate = attributes.get(org.apache.naming.resources.ResourceAttributes.ALTERNATE_CREATION_DATE);
-        Assert.assertNull(creationDate);
-
-        Attribute lastModified = attributes.get(org.apache.naming.resources.ResourceAttributes.LAST_MODIFIED);
-        Assert.assertNull(lastModified);
-
-        lastModified = attributes.get(org.apache.naming.resources.ResourceAttributes.ALTERNATE_LAST_MODIFIED);
-        Assert.assertNull(lastModified);
-    }
-
-    @Test
-    public void testGetSomeAttributesOfFile() throws NamingException {
-        Attributes attributes = this.bundleDirContext.getAttributes(FILE_NAME,
-            new String[] { org.apache.naming.resources.ResourceAttributes.ALTERNATE_CREATION_DATE });
-
-        checkNoName(attributes);
-
-        checkNoResourceType(attributes);
-
-        checkOnlyCreationDate(attributes);
-
-        checkNoContentLength(attributes);
-    }
-
-    private void checkOnlyCreationDate(Attributes attributes) {
-        Attribute creationDate = attributes.get(org.apache.naming.resources.ResourceAttributes.CREATION_DATE);
-        Assert.assertNotNull(creationDate);
-
-        creationDate = attributes.get(org.apache.naming.resources.ResourceAttributes.ALTERNATE_CREATION_DATE);
-        Assert.assertNotNull(creationDate);
-
-        Attribute lastModified = attributes.get(org.apache.naming.resources.ResourceAttributes.LAST_MODIFIED);
-        Assert.assertNull(lastModified);
-
-        lastModified = attributes.get(org.apache.naming.resources.ResourceAttributes.ALTERNATE_LAST_MODIFIED);
-        Assert.assertNull(lastModified);
-    }
-
-}
diff --git a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntryTests.java b/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntryTests.java
deleted file mode 100644
index 6ed9640..0000000
--- a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntryTests.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2014 VMware Inc.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
- * The Eclipse Public License is available at
- *   http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
- *   http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.  
- *
- * Contributors:
- *   VMware Inc. - initial contribution
- *******************************************************************************/
-
-package org.eclipse.gemini.web.tomcat.internal.loading;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Vector;
-
-import org.eclipse.virgo.test.stubs.framework.StubBundle;
-import org.junit.Before;
-import org.junit.Test;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
-import org.osgi.framework.wiring.BundleWiring;
-
-public class BundleEntryTests {
-
-    private final StubBundle testBundle = new StubBundle();
-
-    @Before
-    public void createEntries() throws MalformedURLException {
-        this.testBundle.addEntryPaths("", createPathsEnumeration("sub/"));
-        this.testBundle.addEntryPaths("sub/", createPathsEnumeration("sub/one.txt", "sub/another.sub/"));
-        this.testBundle.addEntryPaths("sub/another.sub/", createPathsEnumeration("sub/another.sub/two.txt"));
-
-        this.testBundle.addEntry("", new File("src/test/resources/").toURI().toURL());
-        this.testBundle.addEntry("sub/", new File("src/test/resources/sub/").toURI().toURL());
-        this.testBundle.addEntry("sub/one.txt", new File("src/test/resources/sub/one.txt").toURI().toURL());
-        this.testBundle.addEntry("sub/another.sub/", new File("src/test/resources/sub/another.sub/").toURI().toURL());
-        this.testBundle.addEntry("sub/another.sub/two.txt", new File("src/test/resources/sub/another.sub/two.txt").toURI().toURL());
-        this.testBundle.addEntry("a/", new File("src/test/resources/a/").toURI().toURL());
-        this.testBundle.addEntry("a/b/", new File("src/test/resources/a/b/").toURI().toURL());
-        this.testBundle.addEntry("a/b/c.txt", new File("src/test/resources/a/b/c.txt").toURI().toURL());
-
-        this.testBundle.addEntry("/", new File("src/test/resources/").toURI().toURL());
-        this.testBundle.addEntry("/sub/", new File("src/test/resources/sub/").toURI().toURL());
-        this.testBundle.addEntry("/sub/one.txt", new File("src/test/resources/sub/one.txt").toURI().toURL());
-        this.testBundle.addEntry("/sub/another.sub/", new File("src/test/resources/sub/another.sub/").toURI().toURL());
-        this.testBundle.addEntry("/sub/another.sub/two.txt", new File("src/test/resources/sub/another.sub/two.txt").toURI().toURL());
-        this.testBundle.addEntry("/a/", new File("src/test/resources/a/").toURI().toURL());
-        this.testBundle.addEntry("/a/b/", new File("src/test/resources/a/b/").toURI().toURL());
-        this.testBundle.addEntry("/a/b/c.txt", new File("src/test/resources/a/b/c.txt").toURI().toURL());
-        this.testBundle.setFindEntriesDelegate(new FindEntriesDelegateImpl(this.testBundle));
-    }
-
-    @Test
-    public void testList() {
-        testList(this.testBundle);
-    }
-
-    @Test
-    public void testListBundleWithFragment() {
-        Bundle bundle = createMock(Bundle.class);
-        BundleRevision bundleRevision = createMock(BundleRevision.class);
-        BundleWiring bundleWiring = createMock(BundleWiring.class);
-        BundleWire bundleWire = createMock(BundleWire.class);
-        Bundle fbundle = createMock(Bundle.class);
-        BundleRevision fbundleRevision = createMock(BundleRevision.class);
-        BundleWiring fbundleWiring = createMock(BundleWiring.class);
-        expect(bundle.getEntryPaths("")).andReturn(createPathsEnumeration("sub/"));
-        expect(bundle.getEntryPaths("sub/")).andReturn(createPathsEnumeration("sub/one.txt"));
-        expect(bundle.adapt(BundleRevision.class)).andReturn(bundleRevision);
-        expect(bundleRevision.getWiring()).andReturn(bundleWiring);
-        expect(bundleWiring.getProvidedWires(BundleRevision.HOST_NAMESPACE)).andReturn(Arrays.asList(new BundleWire[] { bundleWire }));
-        expect(bundleWire.getRequirerWiring()).andReturn(fbundleWiring);
-        expect(fbundleWiring.getRevision()).andReturn(fbundleRevision);
-        expect(fbundleRevision.getBundle()).andReturn(fbundle);
-        expect(fbundle.getEntryPaths("")).andReturn(createPathsEnumeration("sub/"));
-        expect(fbundle.getEntryPaths("sub/")).andReturn(createPathsEnumeration("sub/another.sub/"));
-
-        replay(bundle, bundleRevision, bundleWiring, bundleWire, fbundle, fbundleRevision, fbundleWiring);
-
-        testList(bundle);
-
-        verify(bundle, bundleRevision, bundleWiring, bundleWire, fbundle, fbundleRevision, fbundleWiring);
-    }
-
-    @Test
-    public void testGetEntry() {
-        BundleEntry entry = new BundleEntry(this.testBundle);
-
-        assertNotNull(entry.getEntry("sub/"));
-        assertNotNull(entry.getEntry("sub/one.txt"));
-        assertNotNull(entry.getEntry("sub/another.sub/"));
-        assertNotNull(entry.getEntry("sub/another.sub/two.txt"));
-        assertNotNull(entry.getEntry("."));
-        assertNotNull(entry.getEntry("sub/."));
-        assertNotNull(entry.getEntry(""));
-        assertNotNull(entry.getEntry("/"));
-
-        assertTrue(BundleEntry.isDirectory(entry.getEntry("sub/").getValue()));
-        assertTrue(BundleEntry.isDirectory(entry.getEntry("sub/another.sub/").getValue()));
-        assertTrue(BundleEntry.isDirectory(entry.getEntry(".").getValue()));
-        assertTrue(BundleEntry.isDirectory(entry.getEntry("sub/.").getValue()));
-        assertTrue(BundleEntry.isDirectory(entry.getEntry("").getValue()));
-        assertTrue(BundleEntry.isDirectory(entry.getEntry("/").getValue()));
-    }
-
-    @Test
-    public void testNames() {
-        BundleEntry entry = new BundleEntry(this.testBundle);
-
-        Entry<BundleEntry, URL> e = entry.getEntry("/");
-        assertEquals("/", e.getKey().getName());
-
-        e = entry.getEntry("/sub/");
-        assertEquals("sub", e.getKey().getName());
-
-        e = entry.getEntry("/sub/one.txt");
-        assertEquals("one.txt", e.getKey().getName());
-
-        e = entry.getEntry("");
-        assertEquals("/", e.getKey().getName());
-
-        e = entry.getEntry("sub/");
-        assertEquals("sub", e.getKey().getName());
-
-        e = entry.getEntry("sub/one.txt");
-        assertEquals("one.txt", e.getKey().getName());
-
-        e = entry.getEntry("/a/");
-        assertEquals("a", e.getKey().getName());
-
-        e = entry.getEntry("/a/b/");
-        assertEquals("b", e.getKey().getName());
-
-        e = entry.getEntry("/a/b/c.txt");
-        assertEquals("c.txt", e.getKey().getName());
-
-        e = entry.getEntry("a/");
-        assertEquals("a", e.getKey().getName());
-
-        e = entry.getEntry("a/b/");
-        assertEquals("b", e.getKey().getName());
-
-        e = entry.getEntry("a/b/c.txt");
-        assertEquals("c.txt", e.getKey().getName());
-    }
-
-    private BundleEntry findByPath(List<BundleEntry> entries, String entry) {
-        for (BundleEntry bundleEntry : entries) {
-            if (bundleEntry.getPath().equals(entry)) {
-                return bundleEntry;
-            }
-        }
-        return null;
-    }
-
-    private Enumeration<String> createPathsEnumeration(String... paths) {
-        Vector<String> vector = new Vector<>();
-
-        for (String path : paths) {
-            vector.add(path);
-        }
-
-        return vector.elements();
-    }
-
-    public void testList(Bundle bundle) {
-        BundleEntry entry = new BundleEntry(bundle);
-        List<BundleEntry> list = entry.list();
-
-        BundleEntry subEntry = findByPath(list, "sub/");
-        assertNotNull(subEntry);
-
-        list = subEntry.list();
-        assertNotNull(findByPath(list, "sub/one.txt"));
-        assertNotNull(findByPath(list, "sub/another.sub/"));
-    }
-}