diff --git a/jaxb-api-2.2/src/main/java/javax/xml/bind/ContextFinder.java b/jaxb-api-2.2/src/main/java/javax/xml/bind/ContextFinder.java
index 3118b17..a143cda 100644
--- a/jaxb-api-2.2/src/main/java/javax/xml/bind/ContextFinder.java
+++ b/jaxb-api-2.2/src/main/java/javax/xml/bind/ContextFinder.java
@@ -16,168 +16,496 @@
  */
 package javax.xml.bind;
 
-import java.lang.reflect.Method;
-import java.util.Map;
-import java.util.Properties;
+import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.BufferedReader;
 import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 
+import static javax.xml.bind.JAXBContext.JAXB_CONTEXT_FACTORY;
+
+//import java.lang.reflect.InvocationTargetException;
+
+/**
+ * This class is package private and therefore is not exposed as part of the 
+ * JAXB API.
+ *
+ * This code is designed to implement the JAXB 1.0 spec pluggability feature
+ *
+ * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li></ul>
+ * @see JAXBContext
+ */
 class ContextFinder {
-
-    private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.bind.v2.ContextFactory";
-    private static final String JAXB_CONTEXT_PROPERTY = JAXBContext.class.getName();
-    private static final String JAXB_CONTEXT_FACTORY = JAXBContext.JAXB_CONTEXT_FACTORY;
-
-    public static JAXBContext find(String factoryId, String contextPath, ClassLoader classLoader, Map properties) throws JAXBException {
-        String className = null;
-        // Patch for bug https://issues.apache.org/activemq/browse/SMX4-329
-        if (contextPath == null || contextPath.length() == 0) {
-            throw new JAXBException("Invalid contextPath (empty or null)");
-  	    }
-        String[] packages = contextPath.split(":");
-        if (packages == null || packages.length == 0) {
-            throw new JAXBException("Invalid contextPath (no packages)");
-        }
-        for (String pkg : packages) {
-            String url = pkg.replace('.', '/') + "/jaxb.properties";
-            className = loadClassNameFromProperties(url, classLoader);
-            if (className != null) {
-                break;
-            }
-        }
-        if (className == null) {
-            className = System.getProperty(JAXB_CONTEXT_PROPERTY);
-        }
-        if (className == null) {
-            String url = "META-INF/services/" + JAXB_CONTEXT_PROPERTY;
-            className = loadClassName(url, classLoader);
-        }
-        if (className == null) {
-            className = PLATFORM_DEFAULT_FACTORY_CLASS;
-        }
-        Class spi = loadSpi(className, classLoader);
+    private static final Logger logger;
+    static {
+        logger = Logger.getLogger("javax.xml.bind");
         try {
-            Method m = spi.getMethod("createContext", new Class[] { String.class, ClassLoader.class, Map.class });
-            return (JAXBContext) m.invoke(null, new Object[] { contextPath, classLoader, properties });
+            if (AccessController.doPrivileged(new GetPropertyAction("jaxb.debug")) != null) {
+                // disconnect the logger from a bigger framework (if any)
+                // and take the matters into our own hands
+                logger.setUseParentHandlers(false);
+                logger.setLevel(Level.ALL);
+                ConsoleHandler handler = new ConsoleHandler();
+                handler.setLevel(Level.ALL);
+                logger.addHandler(handler);
+            } else {
+                // don't change the setting of this logger
+                // to honor what other frameworks
+                // have done on configurations.
+            }
+        } catch(Throwable t) {
+            // just to be extra safe. in particular System.getProperty may throw
+            // SecurityException.
+        }
+    }
+
+    /**
+     * If the {@link InvocationTargetException} wraps an exception that shouldn't be wrapped,
+     * throw the wrapped exception.
+     */
+    private static void handleInvocationTargetException(InvocationTargetException x) throws JAXBException {
+        Throwable t = x.getTargetException();
+        if( t != null ) {
+            if( t instanceof JAXBException )
+                // one of our exceptions, just re-throw
+                throw (JAXBException)t;
+            if( t instanceof RuntimeException )
+                // avoid wrapping exceptions unnecessarily
+                throw (RuntimeException)t;
+            if( t instanceof Error )
+                throw (Error)t;
+        }
+    }
+
+
+    /**
+     * Determine if two types (JAXBContext in this case) will generate a ClassCastException.
+     *
+     * For example, (targetType)originalType
+     *
+     * @param originalType
+     *          The Class object of the type being cast
+     * @param targetType
+     *          The Class object of the type that is being cast to
+     * @return JAXBException to be thrown.
+     */
+    private static JAXBException handleClassCastException(Class originalType, Class targetType) {
+        final URL targetTypeURL = which(targetType);
+
+        return new JAXBException(Messages.format(Messages.ILLEGAL_CAST,
+                // we don't care where the impl class is, we want to know where JAXBContext lives in the impl
+                // class' ClassLoader
+                originalType.getClassLoader().getResource("javax/xml/bind/JAXBContext.class"),
+                targetTypeURL));
+    }
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */
+    static JAXBContext newInstance( String contextPath,
+                               String className, 
+                               ClassLoader classLoader,
+                               Map properties )
+        throws JAXBException
+    {
+        try {
+            Class spiClass = safeLoadClass(className,classLoader);
+
+            /*
+             * javax.xml.bind.context.factory points to a class which has a
+             * static method called 'createContext' that
+             * returns a javax.xml.JAXBContext.
+             */
+
+            Object context = null;
+
+            // first check the method that takes Map as the third parameter.
+            // this is added in 2.0.
+            try {
+                Method m = spiClass.getMethod("createContext",String.class,ClassLoader.class,Map.class);
+                // any failure in invoking this method would be considered fatal
+                context = m.invoke(null,contextPath,classLoader,properties);
+            } catch (NoSuchMethodException e) {
+                // it's not an error for the provider not to have this method.
+            }
+
+            if(context==null) {
+                // try the old method that doesn't take properties. compatible with 1.0.
+                // it is an error for an implementation not to have both forms of the createContext method.
+                Method m = spiClass.getMethod("createContext",String.class,ClassLoader.class);
+                // any failure in invoking this method would be considered fatal
+                context = m.invoke(null,contextPath,classLoader);
+            }
+
+            if(!(context instanceof JAXBContext)) {
+                // the cast would fail, so generate an exception with a nice message
+                throw handleClassCastException(context.getClass(), JAXBContext.class);
+            }
+            return (JAXBContext)context;
+        } catch (ClassNotFoundException x) {
+            throw new JAXBException(
+                Messages.format( Messages.PROVIDER_NOT_FOUND, className ),
+                x);
+        } catch (InvocationTargetException x) {
+            handleInvocationTargetException(x);
+            // for other exceptions, wrap the internal target exception
+            // with a JAXBException
+            Throwable e = x;
+            if(x.getTargetException()!=null)
+                e = x.getTargetException();
+
+            throw new JAXBException( Messages.format( Messages.COULD_NOT_INSTANTIATE, className, e ), e );
+        } catch (RuntimeException x) {
+            // avoid wrapping RuntimeException to JAXBException,
+            // because it indicates a bug in this code.
+            throw x;
+        } catch (Exception x) {
+            // can't catch JAXBException because the method is hidden behind
+            // reflection.  Root element collisions detected in the call to
+            // createContext() are reported as JAXBExceptions - just re-throw it
+            // some other type of exception - just wrap it
+            throw new JAXBException(
+                Messages.format( Messages.COULD_NOT_INSTANTIATE, className, x ),
+                x);
+        }
+    }
+
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */
+    static JAXBContext newInstance(
+                              Class[] classes,
+                              Map properties,
+                              String className) throws JAXBException {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        Class spi;
+        try {
+            spi = safeLoadClass(className,cl);
+        } catch (ClassNotFoundException e) {
+            throw new JAXBException(e);
+        }
+
+        if(logger.isLoggable(Level.FINE)) {
+            // extra check to avoid costly which operation if not logged
+            logger.fine("loaded "+className+" from "+which(spi));
+        }
+
+        Method m;
+        try {
+            m = spi.getMethod("createContext", Class[].class, Map.class);
         } catch (NoSuchMethodException e) {
-            // ignore
-        } catch (Throwable t) {
-            throw new JAXBException("Unable to create context", t);
-        } 
+            throw new JAXBException(e);
+        }
         // Fallback for JAXB 1.0 compatibility (at least JAXB TCK tests are using that feature)
         try {
-            Method m = spi.getMethod("createContext", new Class[] { String.class, ClassLoader.class, });
-            return (JAXBContext) m.invoke(null, new Object[] { contextPath, classLoader });
-        } catch (Throwable t) {
-            throw new JAXBException("Unable to create context", t);
+            Object context = m.invoke(null, classes, properties);
+            if(!(context instanceof JAXBContext)) {
+                // the cast would fail, so generate an exception with a nice message
+                throw handleClassCastException(context.getClass(), JAXBContext.class);
+            }
+            return (JAXBContext)context;
+        } catch (IllegalAccessException e) {
+            throw new JAXBException(e);
+        } catch (InvocationTargetException e) {
+            handleInvocationTargetException(e);
+
+            Throwable x = e;
+            if (e.getTargetException() != null)
+                x = e.getTargetException();
+
+            throw new JAXBException(x);
         }
     }
 
 
-    public static JAXBContext find(Class[] classes, Map properties) throws JAXBException {
-        String className = null;
-        for (Class cl : classes) {
-            Package pkg = cl.getPackage();
-            if (pkg != null) {
-                String url = pkg.getName().replace('.', '/') + "/jaxb.properties";
-                className = loadClassNameFromProperties(url, cl.getClassLoader());
-                if (className != null) {
-                    break;
-                }
-            }
-        }
-        if (className == null) {
-            className = System.getProperty(JAXB_CONTEXT_PROPERTY);
-        }
-        if (className == null) {
-            String url = "META-INF/services/" + JAXB_CONTEXT_PROPERTY;
-            className = loadClassName(url, Thread.currentThread().getContextClassLoader());
-        }
-        if (className == null) {
-            className = PLATFORM_DEFAULT_FACTORY_CLASS;
-        }
-        Class spi = loadSpi(className, Thread.currentThread().getContextClassLoader());
-        try {
-            Method m = spi.getMethod("createContext", new Class[] { Class[].class, Map.class });
-            return (JAXBContext) m.invoke(null, new Object[] { classes, properties });
-        } catch (Throwable t) {
-            throw new JAXBException("Unable to create context", t);
-        }
-    }
+    static JAXBContext find(String factoryId, String contextPath, ClassLoader classLoader, Map properties ) throws JAXBException {
 
-    private static String loadClassNameFromProperties(String url, ClassLoader classLoader) throws JAXBException {
-        try {
-            InputStream is;
-            if (classLoader != null) {
-                is = classLoader.getResourceAsStream(url);
-            } else {
-                is = ClassLoader.getSystemResourceAsStream(url);
-            }
-            if (is != null) {
-                try {
-                    Properties props = new Properties();
-                    props.load(is);
-                    String className = props.getProperty(JAXB_CONTEXT_FACTORY);
-                    if (className == null) {
-                        throw new JAXBException("jaxb.properties file " + url + " should contain a " + JAXB_CONTEXT_FACTORY + " property");
-                    }
-                    return className.trim();
-                } finally {
-                    is.close();
+        // TODO: do we want/need another layer of searching in $java.home/lib/jaxb.properties like JAXP?
+
+        final String jaxbContextFQCN = JAXBContext.class.getName();
+
+        // search context path for jaxb.properties first
+        StringBuilder propFileName;
+        StringTokenizer packages = new StringTokenizer( contextPath, ":" );
+        String factoryClassName;
+
+        if(!packages.hasMoreTokens())
+            // no context is specified
+            throw new JAXBException(Messages.format(Messages.NO_PACKAGE_IN_CONTEXTPATH));
+
+
+        logger.fine("Searching jaxb.properties");
+
+        while( packages.hasMoreTokens() ) {
+            String packageName = packages.nextToken(":").replace('.','/');
+            // com.acme.foo - > com/acme/foo/jaxb.properties
+             propFileName = new StringBuilder().append(packageName).append("/jaxb.properties");
+
+            Properties props = loadJAXBProperties( classLoader, propFileName.toString() );
+            if (props != null) {
+                if (props.containsKey(factoryId)) {
+                    factoryClassName = props.getProperty(factoryId);
+                    return newInstance( contextPath, factoryClassName, classLoader, properties );
+                } else {
+                    throw new JAXBException(Messages.format(Messages.MISSING_PROPERTY, packageName, factoryId));
                 }
-            } else {
-                return null;
             }
+        }
+
+        logger.fine("Searching the system property");
+
+        // search for a system property second (javax.xml.bind.JAXBContext)
+        factoryClassName = AccessController.doPrivileged(new GetPropertyAction(jaxbContextFQCN));
+        if(  factoryClassName != null ) {
+            return newInstance( contextPath, factoryClassName, classLoader, properties );
+        }
+
+        logger.fine("Searching META-INF/services");
+
+        // search META-INF services next
+        BufferedReader r;
+        try {
+            final StringBuilder resource = new StringBuilder().append("META-INF/services/").append(jaxbContextFQCN);
+            final InputStream resourceStream =
+                    classLoader.getResourceAsStream(resource.toString());
+            
+            if (resourceStream != null) {
+                r = new BufferedReader(new InputStreamReader(resourceStream, "UTF-8"));
+                factoryClassName = r.readLine().trim();
+                r.close();
+                return newInstance(contextPath, factoryClassName, classLoader, properties);
+            } else {
+                logger.fine("Unable to load:" + resource.toString());
+            }
+        } catch (UnsupportedEncodingException e) {
+            // should never happen
+            throw new JAXBException(e);
         } catch (IOException e) {
             throw new JAXBException(e);
         }
+
+        // else no provider found
+        logger.fine("Trying to create the platform default provider");
+        return newInstance(contextPath, PLATFORM_DEFAULT_FACTORY_CLASS, classLoader, properties);
     }
 
-    private static String loadClassName(String url, ClassLoader classLoader) throws JAXBException {
-        try {
-            InputStream is;
-            if (classLoader != null) {
-                is = classLoader.getResourceAsStream(url);
+    // TODO: log each step in the look up process
+    static JAXBContext find( Class[] classes, Map properties ) throws JAXBException {
+
+        // TODO: do we want/need another layer of searching in $java.home/lib/jaxb.properties like JAXP?
+
+        final String jaxbContextFQCN = JAXBContext.class.getName();
+        String factoryClassName;
+
+        // search for jaxb.properties in the class loader of each class first
+        for (final Class c : classes) {
+            // this classloader is used only to load jaxb.properties, so doing this should be safe.
+            ClassLoader classLoader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                public ClassLoader run() {
+                    return c.getClassLoader();
+                }
+            });
+            Package pkg = c.getPackage();
+            if(pkg==null)
+                continue;       // this is possible for primitives, arrays, and classes that are loaded by poorly implemented ClassLoaders
+            String packageName = pkg.getName().replace('.', '/');
+
+            // TODO: do we want to optimize away searching the same package?  org.Foo, org.Bar, com.Baz
+            //       classes from the same package might come from different class loades, so it might be a bad idea
+
+            // TODO: it's easier to look things up from the class
+            // c.getResourceAsStream("jaxb.properties");
+
+            // build the resource name and use the property loader code
+            String resourceName = packageName+"/jaxb.properties";
+            logger.fine("Trying to locate "+resourceName);
+            Properties props = loadJAXBProperties(classLoader, resourceName);
+            if (props == null) {
+                logger.fine("  not found");
             } else {
-                is = ClassLoader.getSystemResourceAsStream(url);
-            }
-            if (is != null) {
-                try {
-                    BufferedReader r = new BufferedReader(new InputStreamReader(is, "UTF-8"));
-                    return r.readLine().trim();
-                } finally {
-                    is.close();
+                logger.fine("  found");
+                if (props.containsKey(JAXB_CONTEXT_FACTORY)) {
+                    // trim() seems redundant, but adding to satisfy customer complaint
+                    factoryClassName = props.getProperty(JAXB_CONTEXT_FACTORY).trim();
+                    return newInstance(classes, properties, factoryClassName);
+                } else {
+                    throw new JAXBException(Messages.format(Messages.MISSING_PROPERTY, packageName, JAXB_CONTEXT_FACTORY));
                 }
             }
-            return null;
+        }
+
+        // search for a system property second (javax.xml.bind.JAXBContext)
+        logger.fine("Checking system property "+jaxbContextFQCN);
+        factoryClassName = AccessController.doPrivileged(new GetPropertyAction(jaxbContextFQCN));
+        if(  factoryClassName != null ) {
+            logger.fine("  found "+factoryClassName);
+            return newInstance( classes, properties, factoryClassName );
+        }
+        logger.fine("  not found");
+
+        // search META-INF services next
+        logger.fine("Checking META-INF/services");
+        BufferedReader r;
+        try {
+            final String resource = new StringBuilder("META-INF/services/").append(jaxbContextFQCN).toString();
+            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+            URL resourceURL;
+            if(classLoader==null)
+                resourceURL = ClassLoader.getSystemResource(resource);
+            else
+                resourceURL = classLoader.getResource(resource);
+
+            if (resourceURL != null) {
+                logger.fine("Reading "+resourceURL);
+                r = new BufferedReader(new InputStreamReader(resourceURL.openStream(), "UTF-8"));
+                factoryClassName = r.readLine().trim();
+                return newInstance(classes, properties, factoryClassName);
+            } else {
+                logger.fine("Unable to find: " + resource);
+            }
+        } catch (UnsupportedEncodingException e) {
+            // should never happen
+            throw new JAXBException(e);
         } catch (IOException e) {
             throw new JAXBException(e);
         }
+
+        // else no provider found
+        logger.fine("Trying to create the platform default provider");
+        return newInstance(classes, properties, PLATFORM_DEFAULT_FACTORY_CLASS);
     }
 
-    private static Class loadSpi(String className, ClassLoader classLoader) throws JAXBException {
-        Class spiClass;
+
+    private static Properties loadJAXBProperties( ClassLoader classLoader,
+                                                  String propFileName ) 
+        throws JAXBException {
+                                            
+        Properties props = null;
+                                                    
         try {
-            spiClass = org.apache.servicemix.specs.locator.OsgiLocator.locate(JAXBContext.class.getName());
-            if (spiClass != null) {
-                return spiClass;
-            }
-        } catch (Throwable t) {
+            URL url;
+            if(classLoader==null)
+                url = ClassLoader.getSystemResource(propFileName);
+            else
+                url = classLoader.getResource( propFileName );
+
+            if( url != null ) {
+                logger.fine("loading props from "+url);
+                props = new Properties();
+                InputStream is = url.openStream();
+                props.load( is );
+                is.close();
+            } 
+        } catch( IOException ioe ) {
+            logger.log(Level.FINE,"Unable to load "+propFileName,ioe);
+            throw new JAXBException( ioe.toString(), ioe );
         }
-        try {
-            if (classLoader != null) {
-                spiClass = classLoader.loadClass(className);
-            } else {
-                spiClass = Class.forName(className);
-            }
-        } catch (ClassNotFoundException e) {
-            throw new JAXBException("Provider " + className + " not found", e);
-        }
-        return spiClass;
+        
+        return props;
     }
 
 
+    /**
+     * Search the given ClassLoader for an instance of the specified class and
+     * return a string representation of the URL that points to the resource.
+     *
+     * @param clazz
+     *          The class to search for
+     * @param loader
+     *          The ClassLoader to search.  If this parameter is null, then the
+     *          system class loader will be searched
+     * @return
+     *          the URL for the class or null if it wasn't found
+     */
+    static URL which(Class clazz, ClassLoader loader) {
+
+        String classnameAsResource = clazz.getName().replace('.', '/') + ".class";
+
+        if(loader == null) {
+            loader = ClassLoader.getSystemClassLoader();
+        }
+
+        return loader.getResource(classnameAsResource);
+    }
+
+    /**
+     * Get the URL for the Class from it's ClassLoader.
+     *
+     * Convenience method for {@link #which(Class, ClassLoader)}.
+     *
+     * Equivalent to calling: which(clazz, clazz.getClassLoader())
+     *
+     * @param clazz
+     *          The class to search for
+     * @return
+     *          the URL for the class or null if it wasn't found
+     */
+    static URL which(Class clazz) {
+        return which(clazz, clazz.getClassLoader());
+    }
+
+    /**
+     * When JAXB is in J2SE, rt.jar has to have a JAXB implementation.
+     * However, rt.jar cannot have META-INF/services/javax.xml.bind.JAXBContext
+     * because if it has, it will take precedence over any file that applications have
+     * in their jar files.
+     *
+     * <p>
+     * When the user bundles his own JAXB implementation, we'd like to use it, and we
+     * want the platform default to be used only when there's no other JAXB provider.
+     *
+     * <p>
+     * For this reason, we have to hard-code the class name into the API.
+     */
+    private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.internal.bind.v2.ContextFactory";
+
+    /**
+     * Loads the class, provided that the calling thread has an access to the class being loaded.
+     */
+    private static Class safeLoadClass(String className, ClassLoader classLoader) throws ClassNotFoundException {
+       // using Osig locator to load the spi class 
+       try {
+           Class spiClass = org.apache.servicemix.specs.locator.OsgiLocator.locate(JAXBContext.class.getName());
+           if (spiClass != null) {
+               return spiClass;
+           }
+       } catch (Throwable t) {
+       }
+       logger.fine("Trying to load "+className);
+       try {
+          // make sure that the current thread has an access to the package of the given name.
+          SecurityManager s = System.getSecurityManager();
+          if (s != null) {
+              int i = className.lastIndexOf('.');
+              if (i != -1) {
+                  s.checkPackageAccess(className.substring(0,i));
+              }
+          }
+ 
+          if (classLoader == null) {
+              return Class.forName(className);
+          } else {
+              return classLoader.loadClass(className);
+          }
+       } catch (SecurityException se) {
+           // anyone can access the platform default factory class without permission
+           if (PLATFORM_DEFAULT_FACTORY_CLASS.equals(className)) {
+              return Class.forName(className);
+           }
+           throw se;
+       }
+    }
+
 }
-
