diff --git a/src/org/apache/xalan/extensions/ExtensionHandler.java b/src/org/apache/xalan/extensions/ExtensionHandler.java
index 4d365ae..f7fd5bf 100644
--- a/src/org/apache/xalan/extensions/ExtensionHandler.java
+++ b/src/org/apache/xalan/extensions/ExtensionHandler.java
@@ -65,7 +65,7 @@
 import org.apache.xalan.templates.Stylesheet;
 import org.apache.xalan.transformer.TransformerImpl;
 import org.apache.xpath.functions.FuncExtFunction;
-import org.apache.xml.utils.ObjectFactory;
+
 
 /**
  * Abstract base class for handling an extension namespace for XPath.
diff --git a/src/org/apache/xalan/extensions/ExtensionHandlerGeneral.java b/src/org/apache/xalan/extensions/ExtensionHandlerGeneral.java
index 96b29dc..900e873 100644
--- a/src/org/apache/xalan/extensions/ExtensionHandlerGeneral.java
+++ b/src/org/apache/xalan/extensions/ExtensionHandlerGeneral.java
@@ -73,7 +73,7 @@
 import org.apache.xalan.transformer.TransformerImpl;
 import org.apache.xml.dtm.DTMIterator;
 import org.apache.xml.dtm.ref.DTMNodeList;
-import org.apache.xml.utils.ObjectFactory;
+
 import org.apache.xml.utils.StringVector;
 import org.apache.xml.utils.SystemIDResolver;
 import org.apache.xpath.XPathProcessorException;
diff --git a/src/org/apache/xalan/extensions/ObjectFactory.java b/src/org/apache/xalan/extensions/ObjectFactory.java
new file mode 100755
index 0000000..7302c1b
--- /dev/null
+++ b/src/org/apache/xalan/extensions/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.extensions;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        FileInputStream fis =
+                                         ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                        fis.close();
+                    }
+	            } catch (Exception x) {
+	                fXalanProperties = null;
+	                fLastModified = -1;
+                        // assert(x instanceof FileNotFoundException
+	                //        || x instanceof SecurityException)
+	                // In both cases, ignore and continue w/ next location
+	            }
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            try {
+                FileInputStream fis =
+                           ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                fis.close();
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {
+      
+        SecurityManager security = System.getSecurityManager();
+        try{
+            if (security != null)
+                security.checkPackageAccess(className);
+        }catch(SecurityException e){
+            throw e;
+        }
+
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+            rd.close();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        public ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        public Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/extensions/SecuritySupport.java b/src/org/apache/xalan/extensions/SecuritySupport.java
new file mode 100755
index 0000000..c647419
--- /dev/null
+++ b/src/org/apache/xalan/extensions/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.extensions;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/org/apache/xalan/extensions/SecuritySupport12.java b/src/org/apache/xalan/extensions/SecuritySupport12.java
new file mode 100755
index 0000000..4043e1d
--- /dev/null
+++ b/src/org/apache/xalan/extensions/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.extensions;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/org/apache/xalan/lib/Extensions.java b/src/org/apache/xalan/lib/Extensions.java
index 8d2e883..2b46346 100644
--- a/src/org/apache/xalan/lib/Extensions.java
+++ b/src/org/apache/xalan/lib/Extensions.java
@@ -69,7 +69,7 @@
 import org.apache.xpath.objects.XBoolean;
 import org.apache.xpath.objects.XNumber;
 import org.apache.xpath.objects.XObject;
-import org.apache.xml.utils.ObjectFactory;
+
 
 import org.w3c.dom.Document;
 import org.w3c.dom.DocumentFragment;
diff --git a/src/org/apache/xalan/lib/ObjectFactory.java b/src/org/apache/xalan/lib/ObjectFactory.java
new file mode 100755
index 0000000..065faf2
--- /dev/null
+++ b/src/org/apache/xalan/lib/ObjectFactory.java
@@ -0,0 +1,666 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.lib;
+
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        FileInputStream fis =
+                                         ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                        fis.close();
+                    }
+	            } catch (Exception x) {
+	                fXalanProperties = null;
+	                fLastModified = -1;
+                        // assert(x instanceof FileNotFoundException
+	                //        || x instanceof SecurityException)
+	                // In both cases, ignore and continue w/ next location
+	            }
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            try {
+                FileInputStream fis =
+                           ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                fis.close();
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {
+      
+        SecurityManager security = System.getSecurityManager();
+        try{
+            if (security != null)
+                security.checkPackageAccess(className);
+        }catch(SecurityException e){
+            throw e;
+        }
+
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+            rd.close();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        public ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        public Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/lib/SecuritySupport.java b/src/org/apache/xalan/lib/SecuritySupport.java
new file mode 100755
index 0000000..db79980
--- /dev/null
+++ b/src/org/apache/xalan/lib/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.lib;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/org/apache/xalan/lib/SecuritySupport12.java b/src/org/apache/xalan/lib/SecuritySupport12.java
new file mode 100755
index 0000000..a840d7f
--- /dev/null
+++ b/src/org/apache/xalan/lib/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.lib;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/org/apache/xalan/lib/sql/DefaultConnectionPool.java b/src/org/apache/xalan/lib/sql/DefaultConnectionPool.java
index 030ddcb..4c86e5d 100644
--- a/src/org/apache/xalan/lib/sql/DefaultConnectionPool.java
+++ b/src/org/apache/xalan/lib/sql/DefaultConnectionPool.java
@@ -67,7 +67,7 @@
 
 import org.apache.xalan.res.XSLMessages;
 import org.apache.xalan.res.XSLTErrorResources;
-import org.apache.xml.utils.ObjectFactory;
+
 
 /**
  * For internal connectiones, i.e. Connection information supplies in the
diff --git a/src/org/apache/xalan/lib/sql/ObjectFactory.java b/src/org/apache/xalan/lib/sql/ObjectFactory.java
new file mode 100755
index 0000000..dbed753
--- /dev/null
+++ b/src/org/apache/xalan/lib/sql/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.lib.sql;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        FileInputStream fis =
+                                         ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                        fis.close();
+                    }
+	            } catch (Exception x) {
+	                fXalanProperties = null;
+	                fLastModified = -1;
+                        // assert(x instanceof FileNotFoundException
+	                //        || x instanceof SecurityException)
+	                // In both cases, ignore and continue w/ next location
+	            }
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            try {
+                FileInputStream fis =
+                           ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                fis.close();
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {
+      
+        SecurityManager security = System.getSecurityManager();
+        try{
+            if (security != null)
+                security.checkPackageAccess(className);
+        }catch(SecurityException e){
+            throw e;
+        }
+
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+            rd.close();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        public ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        public Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/lib/sql/SecuritySupport.java b/src/org/apache/xalan/lib/sql/SecuritySupport.java
new file mode 100755
index 0000000..4d547d5
--- /dev/null
+++ b/src/org/apache/xalan/lib/sql/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.lib.sql;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/org/apache/xalan/lib/sql/SecuritySupport12.java b/src/org/apache/xalan/lib/sql/SecuritySupport12.java
new file mode 100755
index 0000000..90c83b5
--- /dev/null
+++ b/src/org/apache/xalan/lib/sql/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.lib.sql;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/org/apache/xalan/xslt/EnvironmentCheck.java b/src/org/apache/xalan/xslt/EnvironmentCheck.java
index bd0d9c9..abf09db 100644
--- a/src/org/apache/xalan/xslt/EnvironmentCheck.java
+++ b/src/org/apache/xalan/xslt/EnvironmentCheck.java
@@ -66,7 +66,7 @@
 import java.util.StringTokenizer;
 import java.util.Vector;
 
-import org.apache.xml.utils.ObjectFactory;
+
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
diff --git a/src/org/apache/xalan/xslt/ObjectFactory.java b/src/org/apache/xalan/xslt/ObjectFactory.java
new file mode 100755
index 0000000..b96f7de
--- /dev/null
+++ b/src/org/apache/xalan/xslt/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xslt;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        FileInputStream fis =
+                                         ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                        fis.close();
+                    }
+	            } catch (Exception x) {
+	                fXalanProperties = null;
+	                fLastModified = -1;
+                        // assert(x instanceof FileNotFoundException
+	                //        || x instanceof SecurityException)
+	                // In both cases, ignore and continue w/ next location
+	            }
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            try {
+                FileInputStream fis =
+                           ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                fis.close();
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {
+      
+        SecurityManager security = System.getSecurityManager();
+        try{
+            if (security != null)
+                security.checkPackageAccess(className);
+        }catch(SecurityException e){
+            throw e;
+        }
+
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+            rd.close();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        public ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        public Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/xslt/Process.java b/src/org/apache/xalan/xslt/Process.java
index 939ada6..86e042c 100644
--- a/src/org/apache/xalan/xslt/Process.java
+++ b/src/org/apache/xalan/xslt/Process.java
@@ -90,7 +90,7 @@
 import org.apache.xalan.trace.TraceManager;
 import org.apache.xalan.transformer.XalanProperties;
 import org.apache.xml.utils.DefaultErrorHandler;
-import org.apache.xml.utils.ObjectFactory;
+
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
diff --git a/src/org/apache/xalan/xslt/SecuritySupport.java b/src/org/apache/xalan/xslt/SecuritySupport.java
new file mode 100755
index 0000000..9349fac
--- /dev/null
+++ b/src/org/apache/xalan/xslt/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xslt;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/org/apache/xalan/xslt/SecuritySupport12.java b/src/org/apache/xalan/xslt/SecuritySupport12.java
new file mode 100755
index 0000000..f62d65c
--- /dev/null
+++ b/src/org/apache/xalan/xslt/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xslt;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/org/apache/xalan/xsltc/cmdline/ObjectFactory.java b/src/org/apache/xalan/xsltc/cmdline/ObjectFactory.java
new file mode 100755
index 0000000..c2bc107
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/cmdline/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.cmdline;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        FileInputStream fis =
+                                         ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                        fis.close();
+                    }
+	            } catch (Exception x) {
+	                fXalanProperties = null;
+	                fLastModified = -1;
+                        // assert(x instanceof FileNotFoundException
+	                //        || x instanceof SecurityException)
+	                // In both cases, ignore and continue w/ next location
+	            }
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            try {
+                FileInputStream fis =
+                           ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                fis.close();
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {
+      
+        SecurityManager security = System.getSecurityManager();
+        try{
+            if (security != null)
+                security.checkPackageAccess(className);
+        }catch(SecurityException e){
+            throw e;
+        }
+
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+            rd.close();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        public ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        public Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/xsltc/cmdline/SecuritySupport.java b/src/org/apache/xalan/xsltc/cmdline/SecuritySupport.java
new file mode 100755
index 0000000..ec1bda9
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/cmdline/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.cmdline;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/org/apache/xalan/xsltc/cmdline/SecuritySupport12.java b/src/org/apache/xalan/xsltc/cmdline/SecuritySupport12.java
new file mode 100755
index 0000000..a4b4089
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/cmdline/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.cmdline;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/org/apache/xalan/xsltc/cmdline/Transform.java b/src/org/apache/xalan/xsltc/cmdline/Transform.java
index 8035a49..69ca677 100644
--- a/src/org/apache/xalan/xsltc/cmdline/Transform.java
+++ b/src/org/apache/xalan/xsltc/cmdline/Transform.java
@@ -80,7 +80,7 @@
 import org.apache.xalan.xsltc.dom.XSLTCDTMManager;
 import org.apache.xalan.xsltc.runtime.AbstractTranslet;
 import org.apache.xalan.xsltc.runtime.Constants;
-import org.apache.xml.utils.ObjectFactory;
+
 import org.apache.xalan.xsltc.runtime.Parameter;
 import org.apache.xalan.xsltc.runtime.output.TransletOutputHandlerFactory;
 import org.apache.xml.serializer.SerializationHandler;
diff --git a/src/org/apache/xalan/xsltc/compiler/FunctionAvailableCall.java b/src/org/apache/xalan/xsltc/compiler/FunctionAvailableCall.java
index 4828dde..428ea96 100644
--- a/src/org/apache/xalan/xsltc/compiler/FunctionAvailableCall.java
+++ b/src/org/apache/xalan/xsltc/compiler/FunctionAvailableCall.java
@@ -75,7 +75,7 @@
 import org.apache.xalan.xsltc.compiler.util.Type;
 import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
 import org.apache.xalan.xsltc.compiler.util.Util;
-import org.apache.xml.utils.ObjectFactory;
+
 
 final class FunctionAvailableCall extends FunctionCall {
 
diff --git a/src/org/apache/xalan/xsltc/compiler/FunctionCall.java b/src/org/apache/xalan/xsltc/compiler/FunctionCall.java
index 2a7f667..afa0375 100644
--- a/src/org/apache/xalan/xsltc/compiler/FunctionCall.java
+++ b/src/org/apache/xalan/xsltc/compiler/FunctionCall.java
@@ -95,7 +95,7 @@
 import org.apache.xalan.xsltc.compiler.util.ReferenceType;
 import org.apache.xalan.xsltc.compiler.util.Type;
 import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
-import org.apache.xml.utils.ObjectFactory;
+
 
 class FunctionCall extends Expression {
 
diff --git a/src/org/apache/xalan/xsltc/compiler/ObjectFactory.java b/src/org/apache/xalan/xsltc/compiler/ObjectFactory.java
new file mode 100755
index 0000000..9702f13
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/compiler/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.compiler;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        FileInputStream fis =
+                                         ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                        fis.close();
+                    }
+	            } catch (Exception x) {
+	                fXalanProperties = null;
+	                fLastModified = -1;
+                        // assert(x instanceof FileNotFoundException
+	                //        || x instanceof SecurityException)
+	                // In both cases, ignore and continue w/ next location
+	            }
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            try {
+                FileInputStream fis =
+                           ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                fis.close();
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {
+      
+        SecurityManager security = System.getSecurityManager();
+        try{
+            if (security != null)
+                security.checkPackageAccess(className);
+        }catch(SecurityException e){
+            throw e;
+        }
+
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+            rd.close();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        public ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        public Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/xsltc/compiler/Parser.java b/src/org/apache/xalan/xsltc/compiler/Parser.java
index abd6784..1b61789 100644
--- a/src/org/apache/xalan/xsltc/compiler/Parser.java
+++ b/src/org/apache/xalan/xsltc/compiler/Parser.java
@@ -87,7 +87,7 @@
 import org.apache.xalan.xsltc.compiler.util.Type;
 import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
 import org.apache.xalan.xsltc.runtime.AttributeList;
-import org.apache.xml.utils.ObjectFactory;
+
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.InputSource;
diff --git a/src/org/apache/xalan/xsltc/compiler/SecuritySupport.java b/src/org/apache/xalan/xsltc/compiler/SecuritySupport.java
new file mode 100755
index 0000000..4c4571d
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/compiler/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.compiler;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/org/apache/xalan/xsltc/compiler/SecuritySupport12.java b/src/org/apache/xalan/xsltc/compiler/SecuritySupport12.java
new file mode 100755
index 0000000..cead24e
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/compiler/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.compiler;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/org/apache/xalan/xsltc/compiler/util/ObjectFactory.java b/src/org/apache/xalan/xsltc/compiler/util/ObjectFactory.java
new file mode 100755
index 0000000..2b8e1d0
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/compiler/util/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.compiler.util;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        FileInputStream fis =
+                                         ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                        fis.close();
+                    }
+	            } catch (Exception x) {
+	                fXalanProperties = null;
+	                fLastModified = -1;
+                        // assert(x instanceof FileNotFoundException
+	                //        || x instanceof SecurityException)
+	                // In both cases, ignore and continue w/ next location
+	            }
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            try {
+                FileInputStream fis =
+                           ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                fis.close();
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {
+      
+        SecurityManager security = System.getSecurityManager();
+        try{
+            if (security != null)
+                security.checkPackageAccess(className);
+        }catch(SecurityException e){
+            throw e;
+        }
+
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+            rd.close();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        public ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        public Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/xsltc/compiler/util/ObjectType.java b/src/org/apache/xalan/xsltc/compiler/util/ObjectType.java
index 0f31317..94389c7 100644
--- a/src/org/apache/xalan/xsltc/compiler/util/ObjectType.java
+++ b/src/org/apache/xalan/xsltc/compiler/util/ObjectType.java
@@ -74,7 +74,7 @@
 import org.apache.bcel.generic.InstructionList;
 import org.apache.bcel.generic.PUSH;
 import org.apache.xalan.xsltc.compiler.Constants;
-import org.apache.xml.utils.ObjectFactory;
+
 
 public final class ObjectType extends Type {
     
diff --git a/src/org/apache/xalan/xsltc/compiler/util/SecuritySupport.java b/src/org/apache/xalan/xsltc/compiler/util/SecuritySupport.java
new file mode 100755
index 0000000..e75b963
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/compiler/util/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.compiler.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/org/apache/xalan/xsltc/compiler/util/SecuritySupport12.java b/src/org/apache/xalan/xsltc/compiler/util/SecuritySupport12.java
new file mode 100755
index 0000000..4fc7cd7
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/compiler/util/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.compiler.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/org/apache/xalan/xsltc/dom/NodeSortRecordFactory.java b/src/org/apache/xalan/xsltc/dom/NodeSortRecordFactory.java
index 1b59a71..9987105 100644
--- a/src/org/apache/xalan/xsltc/dom/NodeSortRecordFactory.java
+++ b/src/org/apache/xalan/xsltc/dom/NodeSortRecordFactory.java
@@ -68,7 +68,7 @@
 import org.apache.xalan.xsltc.Translet;
 import org.apache.xalan.xsltc.TransletException;
 import org.apache.xalan.xsltc.runtime.AbstractTranslet;
-import org.apache.xml.utils.ObjectFactory;
+
 
 public class NodeSortRecordFactory {
 
diff --git a/src/org/apache/xalan/xsltc/dom/ObjectFactory.java b/src/org/apache/xalan/xsltc/dom/ObjectFactory.java
new file mode 100755
index 0000000..fc356b9
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/dom/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.dom;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        FileInputStream fis =
+                                         ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                        fis.close();
+                    }
+	            } catch (Exception x) {
+	                fXalanProperties = null;
+	                fLastModified = -1;
+                        // assert(x instanceof FileNotFoundException
+	                //        || x instanceof SecurityException)
+	                // In both cases, ignore and continue w/ next location
+	            }
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            try {
+                FileInputStream fis =
+                           ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                fis.close();
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {
+      
+        SecurityManager security = System.getSecurityManager();
+        try{
+            if (security != null)
+                security.checkPackageAccess(className);
+        }catch(SecurityException e){
+            throw e;
+        }
+
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+            rd.close();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        public ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        public Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/xsltc/dom/SecuritySupport.java b/src/org/apache/xalan/xsltc/dom/SecuritySupport.java
new file mode 100755
index 0000000..07f3c20
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/dom/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.dom;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/org/apache/xalan/xsltc/dom/SecuritySupport12.java b/src/org/apache/xalan/xsltc/dom/SecuritySupport12.java
new file mode 100755
index 0000000..31f37ed
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/dom/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.dom;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/org/apache/xalan/xsltc/dom/XSLTCDTMManager.java b/src/org/apache/xalan/xsltc/dom/XSLTCDTMManager.java
index ac79ae1..4d4eabb 100644
--- a/src/org/apache/xalan/xsltc/dom/XSLTCDTMManager.java
+++ b/src/org/apache/xalan/xsltc/dom/XSLTCDTMManager.java
@@ -68,7 +68,7 @@
 import org.apache.xml.dtm.ref.DTMManagerDefault;
 import org.apache.xml.res.XMLErrorResources;
 import org.apache.xml.res.XMLMessages;
-import org.apache.xml.utils.ObjectFactory;
+
 import org.apache.xml.utils.SystemIDResolver;
 import org.apache.xalan.xsltc.trax.DOM2SAX;
 
diff --git a/src/org/apache/xalan/xsltc/trax/ObjectFactory.java b/src/org/apache/xalan/xsltc/trax/ObjectFactory.java
new file mode 100755
index 0000000..3ceee7b
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/trax/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.trax;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        FileInputStream fis =
+                                         ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                        fis.close();
+                    }
+	            } catch (Exception x) {
+	                fXalanProperties = null;
+	                fLastModified = -1;
+                        // assert(x instanceof FileNotFoundException
+	                //        || x instanceof SecurityException)
+	                // In both cases, ignore and continue w/ next location
+	            }
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            try {
+                FileInputStream fis =
+                           ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                fis.close();
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {
+      
+        SecurityManager security = System.getSecurityManager();
+        try{
+            if (security != null)
+                security.checkPackageAccess(className);
+        }catch(SecurityException e){
+            throw e;
+        }
+
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+            rd.close();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        public ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        public Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xalan/xsltc/trax/SecuritySupport.java b/src/org/apache/xalan/xsltc/trax/SecuritySupport.java
new file mode 100755
index 0000000..a1e8f44
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/trax/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.trax;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/org/apache/xalan/xsltc/trax/SecuritySupport12.java b/src/org/apache/xalan/xsltc/trax/SecuritySupport12.java
new file mode 100755
index 0000000..c3f00db
--- /dev/null
+++ b/src/org/apache/xalan/xsltc/trax/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xalan.xsltc.trax;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/org/apache/xalan/xsltc/trax/SmartTransformerFactoryImpl.java b/src/org/apache/xalan/xsltc/trax/SmartTransformerFactoryImpl.java
index 03976e3..efaf3a6 100644
--- a/src/org/apache/xalan/xsltc/trax/SmartTransformerFactoryImpl.java
+++ b/src/org/apache/xalan/xsltc/trax/SmartTransformerFactoryImpl.java
@@ -80,7 +80,7 @@
 import javax.xml.transform.stream.StreamResult;
 import javax.xml.transform.stream.StreamSource;
 
-import org.apache.xml.utils.ObjectFactory;
+
 import org.xml.sax.XMLFilter;
 
 /**
diff --git a/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java b/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java
index 8bfd942..29933e3 100644
--- a/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java
+++ b/src/org/apache/xalan/xsltc/trax/TemplatesImpl.java
@@ -83,7 +83,7 @@
 import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
 import org.apache.xalan.xsltc.runtime.AbstractTranslet;
 import org.apache.xalan.xsltc.runtime.Hashtable;
-import org.apache.xml.utils.ObjectFactory;
+
 
 public final class TemplatesImpl implements Templates, Serializable {
 
diff --git a/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java b/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java
index 9bceb21..08a84e3 100644
--- a/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java
+++ b/src/org/apache/xalan/xsltc/trax/TransformerFactoryImpl.java
@@ -108,7 +108,7 @@
 import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
 import org.apache.xalan.xsltc.dom.XSLTCDTMManager;
 
-import org.apache.xml.utils.ObjectFactory;
+
 
 import org.xml.sax.InputSource;
 import org.xml.sax.XMLFilter;
diff --git a/src/org/apache/xml/dtm/DTMManager.java b/src/org/apache/xml/dtm/DTMManager.java
index 0346b34..7cca8c8 100644
--- a/src/org/apache/xml/dtm/DTMManager.java
+++ b/src/org/apache/xml/dtm/DTMManager.java
@@ -58,7 +58,7 @@
 
 import org.apache.xml.res.XMLErrorResources;
 import org.apache.xml.res.XMLMessages;
-import org.apache.xml.utils.ObjectFactory;
+
 import org.apache.xml.utils.PrefixResolver;
 import org.apache.xml.utils.XMLStringFactory;
 
diff --git a/src/org/apache/xml/dtm/ObjectFactory.java b/src/org/apache/xml/dtm/ObjectFactory.java
new file mode 100755
index 0000000..4610a6e
--- /dev/null
+++ b/src/org/apache/xml/dtm/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xml.dtm;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        FileInputStream fis =
+                                         ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                        fis.close();
+                    }
+	            } catch (Exception x) {
+	                fXalanProperties = null;
+	                fLastModified = -1;
+                        // assert(x instanceof FileNotFoundException
+	                //        || x instanceof SecurityException)
+	                // In both cases, ignore and continue w/ next location
+	            }
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            try {
+                FileInputStream fis =
+                           ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                fis.close();
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {
+      
+        SecurityManager security = System.getSecurityManager();
+        try{
+            if (security != null)
+                security.checkPackageAccess(className);
+        }catch(SecurityException e){
+            throw e;
+        }
+
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+            rd.close();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        public ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        public Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xml/dtm/SecuritySupport.java b/src/org/apache/xml/dtm/SecuritySupport.java
new file mode 100644
index 0000000..1dc4827
--- /dev/null
+++ b/src/org/apache/xml/dtm/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xml.dtm;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/org/apache/xml/dtm/SecuritySupport12.java b/src/org/apache/xml/dtm/SecuritySupport12.java
new file mode 100644
index 0000000..6b305ac
--- /dev/null
+++ b/src/org/apache/xml/dtm/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xml.dtm;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/org/apache/xml/dtm/ref/IncrementalSAXSource_Xerces.java b/src/org/apache/xml/dtm/ref/IncrementalSAXSource_Xerces.java
index 7674268..8eaa137 100644
--- a/src/org/apache/xml/dtm/ref/IncrementalSAXSource_Xerces.java
+++ b/src/org/apache/xml/dtm/ref/IncrementalSAXSource_Xerces.java
@@ -64,7 +64,7 @@
 import org.apache.xerces.parsers.SAXParser;
 import org.apache.xml.res.XMLErrorResources;
 import org.apache.xml.res.XMLMessages;
-import org.apache.xml.utils.ObjectFactory;
+
 
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
diff --git a/src/org/apache/xml/dtm/ref/ObjectFactory.java b/src/org/apache/xml/dtm/ref/ObjectFactory.java
new file mode 100755
index 0000000..8fb66f9
--- /dev/null
+++ b/src/org/apache/xml/dtm/ref/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xml.dtm.ref;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        FileInputStream fis =
+                                         ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                        fis.close();
+                    }
+	            } catch (Exception x) {
+	                fXalanProperties = null;
+	                fLastModified = -1;
+                        // assert(x instanceof FileNotFoundException
+	                //        || x instanceof SecurityException)
+	                // In both cases, ignore and continue w/ next location
+	            }
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            try {
+                FileInputStream fis =
+                           ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                fis.close();
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {
+      
+        SecurityManager security = System.getSecurityManager();
+        try{
+            if (security != null)
+                security.checkPackageAccess(className);
+        }catch(SecurityException e){
+            throw e;
+        }
+
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+            rd.close();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        public ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        public Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xml/dtm/ref/SecuritySupport.java b/src/org/apache/xml/dtm/ref/SecuritySupport.java
new file mode 100755
index 0000000..38eb82a
--- /dev/null
+++ b/src/org/apache/xml/dtm/ref/SecuritySupport.java
@@ -0,0 +1,160 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xml.dtm.ref;
+
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/org/apache/xml/dtm/ref/SecuritySupport12.java b/src/org/apache/xml/dtm/ref/SecuritySupport12.java
new file mode 100755
index 0000000..72534d3
--- /dev/null
+++ b/src/org/apache/xml/dtm/ref/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xml.dtm.ref;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/org/apache/xml/serializer/CharInfo.java b/src/org/apache/xml/serializer/CharInfo.java
index 3aa68fa..9e70679 100644
--- a/src/org/apache/xml/serializer/CharInfo.java
+++ b/src/org/apache/xml/serializer/CharInfo.java
@@ -71,7 +71,7 @@
 import org.apache.xml.res.XMLErrorResources;
 import org.apache.xml.res.XMLMessages;
 import org.apache.xml.utils.CharKey;
-import org.apache.xml.utils.ObjectFactory;
+
 import org.apache.xml.utils.SystemIDResolver;
 import org.apache.xml.utils.WrappedRuntimeException;
 
diff --git a/src/org/apache/xml/serializer/Encodings.java b/src/org/apache/xml/serializer/Encodings.java
index 6f36b22..d7da8e7 100644
--- a/src/org/apache/xml/serializer/Encodings.java
+++ b/src/org/apache/xml/serializer/Encodings.java
@@ -70,7 +70,7 @@
 import java.security.PrivilegedAction;
 import java.security.AccessController;
 
-import org.apache.xml.utils.ObjectFactory;
+
 
 /**
  * Provides information about encodings. Depends on the Java runtime
diff --git a/src/org/apache/xml/serializer/ObjectFactory.java b/src/org/apache/xml/serializer/ObjectFactory.java
new file mode 100755
index 0000000..2c79ad4
--- /dev/null
+++ b/src/org/apache/xml/serializer/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xml.serializer;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        FileInputStream fis =
+                                         ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                        fis.close();
+                    }
+	            } catch (Exception x) {
+	                fXalanProperties = null;
+	                fLastModified = -1;
+                        // assert(x instanceof FileNotFoundException
+	                //        || x instanceof SecurityException)
+	                // In both cases, ignore and continue w/ next location
+	            }
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            try {
+                FileInputStream fis =
+                           ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                fis.close();
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {
+      
+        SecurityManager security = System.getSecurityManager();
+        try{
+            if (security != null)
+                security.checkPackageAccess(className);
+        }catch(SecurityException e){
+            throw e;
+        }
+
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+            rd.close();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        public ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        public Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xml/serializer/SecuritySupport.java b/src/org/apache/xml/serializer/SecuritySupport.java
index cf69b16..ec0c910 100644
--- a/src/org/apache/xml/serializer/SecuritySupport.java
+++ b/src/org/apache/xml/serializer/SecuritySupport.java
@@ -113,33 +113,33 @@
      * Return an appropriate instance of this class, depending on whether
      * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
      */
-    public static SecuritySupport getInstance() {
+    static SecuritySupport getInstance() {
 	return (SecuritySupport)securitySupport;
     }
 
-    public ClassLoader getContextClassLoader() {
+    ClassLoader getContextClassLoader() {
 	return null;
     }
 
-    public ClassLoader getSystemClassLoader() {
+    ClassLoader getSystemClassLoader() {
         return null;
     }
 
-    public ClassLoader getParentClassLoader(ClassLoader cl) {
+    ClassLoader getParentClassLoader(ClassLoader cl) {
         return null;
     }
 
-    public String getSystemProperty(String propName) {
+    String getSystemProperty(String propName) {
         return System.getProperty(propName);
     }
 
-    public FileInputStream getFileInputStream(File file)
+    FileInputStream getFileInputStream(File file)
         throws FileNotFoundException
     {
         return new FileInputStream(file);
     }
 
-    public InputStream getResourceAsStream(ClassLoader cl, String name) {
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
         InputStream ris;
         if (cl == null) {
             ris = ClassLoader.getSystemResourceAsStream(name);
@@ -149,11 +149,11 @@
         return ris;
     }
     
-    public boolean getFileExists(File f) {
+    boolean getFileExists(File f) {
         return f.exists();
     }
     
-    public long getLastModified(File f) {
+    long getLastModified(File f) {
         return f.lastModified();
     }    
 }
diff --git a/src/org/apache/xml/serializer/SecuritySupport12.java b/src/org/apache/xml/serializer/SecuritySupport12.java
index 8c4713e..a338fb4 100644
--- a/src/org/apache/xml/serializer/SecuritySupport12.java
+++ b/src/org/apache/xml/serializer/SecuritySupport12.java
@@ -76,7 +76,7 @@
  */
 class SecuritySupport12 extends SecuritySupport {
 
-    public ClassLoader getContextClassLoader() {
+    ClassLoader getContextClassLoader() {
         return (ClassLoader)
                 AccessController.doPrivileged(new PrivilegedAction() {
             public Object run() {
@@ -89,7 +89,7 @@
         });
     }
 
-    public ClassLoader getSystemClassLoader() {
+    ClassLoader getSystemClassLoader() {
         return (ClassLoader)
             AccessController.doPrivileged(new PrivilegedAction() {
                 public Object run() {
@@ -102,7 +102,7 @@
             });
     }
 
-    public ClassLoader getParentClassLoader(final ClassLoader cl) {
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
         return (ClassLoader)
             AccessController.doPrivileged(new PrivilegedAction() {
                 public Object run() {
@@ -118,7 +118,7 @@
             });
     }
 
-    public String getSystemProperty(final String propName) {
+    String getSystemProperty(final String propName) {
         return (String)
             AccessController.doPrivileged(new PrivilegedAction() {
                 public Object run() {
@@ -127,7 +127,7 @@
             });
     }
 
-    public FileInputStream getFileInputStream(final File file)
+    FileInputStream getFileInputStream(final File file)
         throws FileNotFoundException
     {
         try {
@@ -142,7 +142,7 @@
         }
     }
 
-    public InputStream getResourceAsStream(final ClassLoader cl,
+    InputStream getResourceAsStream(final ClassLoader cl,
                                            final String name)
     {
         return (InputStream)
@@ -159,7 +159,7 @@
             });
     }
     
-    public boolean getFileExists(final File f) {
+    boolean getFileExists(final File f) {
     return ((Boolean)
             AccessController.doPrivileged(new PrivilegedAction() {
                 public Object run() {
@@ -168,7 +168,7 @@
             })).booleanValue();
     }
     
-    public long getLastModified(final File f) {
+    long getLastModified(final File f) {
     return ((Long)
             AccessController.doPrivileged(new PrivilegedAction() {
                 public Object run() {
diff --git a/src/org/apache/xml/serializer/SerializerFactory.java b/src/org/apache/xml/serializer/SerializerFactory.java
index e63a66b..88f8941 100644
--- a/src/org/apache/xml/serializer/SerializerFactory.java
+++ b/src/org/apache/xml/serializer/SerializerFactory.java
@@ -63,7 +63,7 @@
 
 import org.apache.xml.res.XMLErrorResources;
 import org.apache.xml.res.XMLMessages;
-import org.apache.xml.utils.ObjectFactory;
+
 import org.xml.sax.ContentHandler;
 
 /**
diff --git a/src/org/apache/xpath/compiler/FuncLoader.java b/src/org/apache/xpath/compiler/FuncLoader.java
index b31e1c6..367fa83 100644
--- a/src/org/apache/xpath/compiler/FuncLoader.java
+++ b/src/org/apache/xpath/compiler/FuncLoader.java
@@ -58,7 +58,7 @@
 
 import javax.xml.transform.TransformerException;
 
-import org.apache.xml.utils.ObjectFactory;
+
 import org.apache.xpath.functions.Function;
 
 /**
diff --git a/src/org/apache/xpath/compiler/ObjectFactory.java b/src/org/apache/xpath/compiler/ObjectFactory.java
new file mode 100755
index 0000000..09e9cd8
--- /dev/null
+++ b/src/org/apache/xpath/compiler/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xpath.compiler;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        FileInputStream fis =
+                                         ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                        fis.close();
+                    }
+	            } catch (Exception x) {
+	                fXalanProperties = null;
+	                fLastModified = -1;
+                        // assert(x instanceof FileNotFoundException
+	                //        || x instanceof SecurityException)
+	                // In both cases, ignore and continue w/ next location
+	            }
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            try {
+                FileInputStream fis =
+                           ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                fis.close();
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {
+      
+        SecurityManager security = System.getSecurityManager();
+        try{
+            if (security != null)
+                security.checkPackageAccess(className);
+        }catch(SecurityException e){
+            throw e;
+        }
+
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+            rd.close();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        public ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        public Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xpath/compiler/SecuritySupport.java b/src/org/apache/xpath/compiler/SecuritySupport.java
new file mode 100755
index 0000000..dc60e95
--- /dev/null
+++ b/src/org/apache/xpath/compiler/SecuritySupport.java
@@ -0,0 +1,159 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xpath.compiler;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Base class with security related methods that work on JDK 1.1.
+ */
+class SecuritySupport {
+
+    /*
+     * Make this of type Object so that the verifier won't try to
+     * prove its type, thus possibly trying to load the SecuritySupport12
+     * class.
+     */
+    private static final Object securitySupport;
+
+    static {
+	SecuritySupport ss = null;
+	try {
+	    Class c = Class.forName("java.security.AccessController");
+	    // if that worked, we're on 1.2.
+	    /*
+	    // don't reference the class explicitly so it doesn't
+	    // get dragged in accidentally.
+	    c = Class.forName("javax.mail.SecuritySupport12");
+	    Constructor cons = c.getConstructor(new Class[] { });
+	    ss = (SecuritySupport)cons.newInstance(new Object[] { });
+	    */
+	    /*
+	     * Unfortunately, we can't load the class using reflection
+	     * because the class is package private.  And the class has
+	     * to be package private so the APIs aren't exposed to other
+	     * code that could use them to circumvent security.  Thus,
+	     * we accept the risk that the direct reference might fail
+	     * on some JDK 1.1 JVMs, even though we would never execute
+	     * this code in such a case.  Sigh...
+	     */
+	    ss = new SecuritySupport12();
+	} catch (Exception ex) {
+	    // ignore it
+	} finally {
+	    if (ss == null)
+		ss = new SecuritySupport();
+	    securitySupport = ss;
+	}
+    }
+
+    /**
+     * Return an appropriate instance of this class, depending on whether
+     * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
+     */
+    static SecuritySupport getInstance() {
+	return (SecuritySupport)securitySupport;
+    }
+
+    ClassLoader getContextClassLoader() {
+	return null;
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return null;
+    }
+
+    ClassLoader getParentClassLoader(ClassLoader cl) {
+        return null;
+    }
+
+    String getSystemProperty(String propName) {
+        return System.getProperty(propName);
+    }
+
+    FileInputStream getFileInputStream(File file)
+        throws FileNotFoundException
+    {
+        return new FileInputStream(file);
+    }
+
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
+        InputStream ris;
+        if (cl == null) {
+            ris = ClassLoader.getSystemResourceAsStream(name);
+        } else {
+            ris = cl.getResourceAsStream(name);
+        }
+        return ris;
+    }
+    
+    boolean getFileExists(File f) {
+        return f.exists();
+    }
+    
+    long getLastModified(File f) {
+        return f.lastModified();
+    }    
+}
diff --git a/src/org/apache/xpath/compiler/SecuritySupport12.java b/src/org/apache/xpath/compiler/SecuritySupport12.java
new file mode 100755
index 0000000..21dc0a5
--- /dev/null
+++ b/src/org/apache/xpath/compiler/SecuritySupport12.java
@@ -0,0 +1,180 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2002, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xpath.compiler;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import java.util.Properties;
+
+/**
+ * This class is duplicated for each Xalan-Java subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the Xalan-Java
+ * API.
+ *
+ * Security related methods that only work on J2SE 1.2 and newer.
+ */
+class SecuritySupport12 extends SecuritySupport {
+
+    ClassLoader getContextClassLoader() {
+        return (ClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                ClassLoader cl = null;
+                try {
+                    cl = Thread.currentThread().getContextClassLoader();
+                } catch (SecurityException ex) { }
+                return cl;
+            }
+        });
+    }
+
+    ClassLoader getSystemClassLoader() {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader cl = null;
+                    try {
+                        cl = ClassLoader.getSystemClassLoader();
+                    } catch (SecurityException ex) {}
+                    return cl;
+                }
+            });
+    }
+
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
+        return (ClassLoader)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    ClassLoader parent = null;
+                    try {
+                        parent = cl.getParent();
+                    } catch (SecurityException ex) {}
+
+                    // eliminate loops in case of the boot
+                    // ClassLoader returning itself as a parent
+                    return (parent == cl) ? null : parent;
+                }
+            });
+    }
+
+    String getSystemProperty(final String propName) {
+        return (String)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return System.getProperty(propName);
+                }
+            });
+    }
+
+    FileInputStream getFileInputStream(final File file)
+        throws FileNotFoundException
+    {
+        try {
+            return (FileInputStream)
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws FileNotFoundException {
+                        return new FileInputStream(file);
+                    }
+                });
+        } catch (PrivilegedActionException e) {
+            throw (FileNotFoundException)e.getException();
+        }
+    }
+
+    InputStream getResourceAsStream(final ClassLoader cl,
+                                           final String name)
+    {
+        return (InputStream)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    InputStream ris;
+                    if (cl == null) {
+                        ris = ClassLoader.getSystemResourceAsStream(name);
+                    } else {
+                        ris = cl.getResourceAsStream(name);
+                    }
+                    return ris;
+                }
+            });
+    }
+    
+    boolean getFileExists(final File f) {
+    return ((Boolean)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Boolean(f.exists());
+                }
+            })).booleanValue();
+    }
+    
+    long getLastModified(final File f) {
+    return ((Long)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return new Long(f.lastModified());
+                }
+            })).longValue();
+    }
+        
+}
diff --git a/src/org/apache/xpath/functions/FuncSystemProperty.java b/src/org/apache/xpath/functions/FuncSystemProperty.java
index 45422e2..019a05d 100644
--- a/src/org/apache/xpath/functions/FuncSystemProperty.java
+++ b/src/org/apache/xpath/functions/FuncSystemProperty.java
@@ -60,7 +60,7 @@
 import java.io.InputStream;
 import java.util.Properties;
 
-import org.apache.xml.utils.ObjectFactory;
+
 
 import org.apache.xpath.XPathContext;
 import org.apache.xpath.objects.XNumber;
diff --git a/src/org/apache/xpath/functions/ObjectFactory.java b/src/org/apache/xpath/functions/ObjectFactory.java
new file mode 100755
index 0000000..687e8e2
--- /dev/null
+++ b/src/org/apache/xpath/functions/ObjectFactory.java
@@ -0,0 +1,665 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001, 2002 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Apache Software Foundation" must not be used to endorse or
+ *    promote products derived from this software without prior written
+ *    permission. For written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999-2001, Sun Microsystems,
+ * Inc., http://www.sun.com.  For more information on the Apache Software
+ * Foundation, please see <http://www.apache.org/>.
+ */
+
+package org.apache.xpath.functions;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+/**
+ * This class is duplicated for each JAXP subpackage so keep it in sync.
+ * It is package private and therefore is not exposed as part of the JAXP
+ * API.
+ * <p>
+ * This code is designed to implement the JAXP 1.1 spec pluggability
+ * feature and is designed to run on JDK version 1.1 and
+ * later, and to compile on JDK 1.2 and onward.  
+ * The code also runs both as part of an unbundled jar file and
+ * when bundled as part of the JDK.
+ * <p>
+ * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
+ * class and modified to be used as a general utility for creating objects 
+ * dynamically.
+ *
+ * @version $Id$
+ */
+class ObjectFactory {
+
+    //
+    // Constants
+    //
+
+    // name of default properties file to look for in JDK's jre/lib directory
+    private static final String DEFAULT_PROPERTIES_FILENAME =
+                                                     "xalan.properties";
+
+    private static final String SERVICES_PATH = "META-INF/services";
+
+    /** Set to true for debugging */
+    private static final boolean DEBUG = false;
+
+    /** cache the contents of the xalan.properties file.
+     *  Until an attempt has been made to read this file, this will
+     * be null; if the file does not exist or we encounter some other error
+     * during the read, this will be empty.
+     */
+    private static Properties fXalanProperties = null;
+
+    /***
+     * Cache the time stamp of the xalan.properties file so
+     * that we know if it's been modified and can invalidate
+     * the cache when necessary.
+     */
+    private static long fLastModified = -1;
+
+    //
+    // Public static methods
+    //
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, String fallbackClassName)
+        throws ConfigurationError {
+        return createObject(factoryId, null, fallbackClassName);
+    } // createObject(String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return instance of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Object createObject(String factoryId, 
+                                      String propertiesFilename,
+                                      String fallbackClassName)
+        throws ConfigurationError
+    {
+        Class factoryClass = lookUpFactoryClass(factoryId,
+                                                propertiesFilename,
+                                                fallbackClassName);
+
+        if (factoryClass == null) {
+            throw new ConfigurationError(
+                "Provider for " + factoryId + " cannot be found", null);
+        }
+
+        try{
+            Object instance = factoryClass.newInstance();
+            debugPrintln("created new instance of factory " + factoryId);
+            return instance;
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider for factory " + factoryId
+                    + " could not be instantiated: " + x, x);
+        }
+    } // createObject(String,String,String):Object
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object of factory, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId) 
+        throws ConfigurationError
+    {
+        return lookUpFactoryClass(factoryId, null, null);
+    } // lookUpFactoryClass(String):Class
+
+    /**
+     * Finds the implementation Class object in the specified order.  The
+     * specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return Class object that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static Class lookUpFactoryClass(String factoryId,
+                                           String propertiesFilename,
+                                           String fallbackClassName)
+        throws ConfigurationError
+    {
+        String factoryClassName = lookUpFactoryClassName(factoryId,
+                                                         propertiesFilename,
+                                                         fallbackClassName);
+        ClassLoader cl = findClassLoader();
+
+        if (factoryClassName == null) {
+            factoryClassName = fallbackClassName;
+        }
+
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(factoryClassName,
+                                                    cl,
+                                                    true);
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return providerClass;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + factoryClassName + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider "+factoryClassName+" could not be instantiated: "+x,
+                x);
+        }
+    } // lookUpFactoryClass(String,String,String):Class
+
+    /**
+     * Finds the name of the required implementation class in the specified
+     * order.  The specified order is the following:
+     * <ol>
+     *  <li>query the system property using <code>System.getProperty</code>
+     *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
+     *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
+     *  <li>use fallback classname
+     * </ol>
+     *
+     * @return name of class that provides factory service, never null
+     *
+     * @param factoryId             Name of the factory to find, same as
+     *                              a property name
+     * @param propertiesFilename The filename in the $java.home/lib directory
+     *                           of the properties file.  If none specified,
+     *                           ${java.home}/lib/xalan.properties will be used.
+     * @param fallbackClassName     Implementation class name, if nothing else
+     *                              is found.  Use null to mean no fallback.
+     *
+     * @exception ObjectFactory.ConfigurationError
+     */
+    static String lookUpFactoryClassName(String factoryId,
+                                                String propertiesFilename,
+                                                String fallbackClassName)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Use the system property first
+        try {
+            String systemProp = ss.getSystemProperty(factoryId);
+            if (systemProp != null) {
+                debugPrintln("found system property, value=" + systemProp);
+                return systemProp;
+            }
+        } catch (SecurityException se) {
+            // Ignore and continue w/ next location
+        }
+
+        // Try to read from propertiesFilename, or
+        // $java.home/lib/xalan.properties
+        String factoryClassName = null;
+        // no properties file name specified; use
+        // $JAVA_HOME/lib/xalan.properties:
+        if (propertiesFilename == null) {
+            File propertiesFile = null;
+            boolean propertiesFileExists = false;
+            try {
+                String javah = ss.getSystemProperty("java.home");
+                propertiesFilename = javah + File.separator +
+                    "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
+                propertiesFile = new File(propertiesFilename);
+                propertiesFileExists = ss.getFileExists(propertiesFile);
+            } catch (SecurityException e) {
+                // try again...
+                fLastModified = -1;
+                fXalanProperties = null;
+            }
+
+            synchronized (ObjectFactory.class) {
+                boolean loadProperties = false;
+                try {
+                    // file existed last time
+                    if(fLastModified >= 0) {
+                        if(propertiesFileExists &&
+                                (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
+                            loadProperties = true;
+                        } else {
+                            // file has stopped existing...
+                            if(!propertiesFileExists) {
+                                fLastModified = -1;
+                                fXalanProperties = null;
+                            } // else, file wasn't modified!
+                        }
+                    } else {
+                        // file has started to exist:
+                        if(propertiesFileExists) {
+                            loadProperties = true;
+                            fLastModified = ss.getLastModified(propertiesFile);
+                        } // else, nothing's changed
+                    }
+                    if(loadProperties) {
+                        // must never have attempted to read xalan.properties
+                        // before (or it's outdeated)
+                        fXalanProperties = new Properties();
+                        FileInputStream fis =
+                                         ss.getFileInputStream(propertiesFile);
+                        fXalanProperties.load(fis);
+                        fis.close();
+                    }
+	            } catch (Exception x) {
+	                fXalanProperties = null;
+	                fLastModified = -1;
+                        // assert(x instanceof FileNotFoundException
+	                //        || x instanceof SecurityException)
+	                // In both cases, ignore and continue w/ next location
+	            }
+            }
+            if(fXalanProperties != null) {
+                factoryClassName = fXalanProperties.getProperty(factoryId);
+            }
+        } else {
+            try {
+                FileInputStream fis =
+                           ss.getFileInputStream(new File(propertiesFilename));
+                Properties props = new Properties();
+                props.load(fis);
+                fis.close();
+                factoryClassName = props.getProperty(factoryId);
+            } catch (Exception x) {
+                // assert(x instanceof FileNotFoundException
+                //        || x instanceof SecurityException)
+                // In both cases, ignore and continue w/ next location
+            }
+        }
+        if (factoryClassName != null) {
+            debugPrintln("found in " + propertiesFilename + ", value="
+                          + factoryClassName);
+            return factoryClassName;
+        }
+
+        // Try Jar Service Provider Mechanism
+        return findJarServiceProviderName(factoryId);
+    } // lookUpFactoryClass(String,String):String
+
+    //
+    // Private static methods
+    //
+
+    /** Prints a message to standard error if debugging is enabled. */
+    private static void debugPrintln(String msg) {
+        if (DEBUG) {
+            System.err.println("JAXP: " + msg);
+        }
+    } // debugPrintln(String)
+
+    /**
+     * Figure out which ClassLoader to use.  For JDK 1.2 and later use
+     * the context ClassLoader.
+     */
+    static ClassLoader findClassLoader()
+        throws ConfigurationError
+    { 
+        SecuritySupport ss = SecuritySupport.getInstance();
+
+        // Figure out which ClassLoader to use for loading the provider
+        // class.  If there is a Context ClassLoader then use it.
+        ClassLoader context = ss.getContextClassLoader();
+        ClassLoader system = ss.getSystemClassLoader();
+
+        ClassLoader chain = system;
+        while (true) {
+            if (context == chain) {
+                // Assert: we are on JDK 1.1 or we have no Context ClassLoader
+                // or any Context ClassLoader in chain of system classloader
+                // (including extension ClassLoader) so extend to widest
+                // ClassLoader (always look in system ClassLoader if Xalan
+                // is in boot/extension/system classpath and in current
+                // ClassLoader otherwise); normal classloaders delegate
+                // back to system ClassLoader first so this widening doesn't
+                // change the fact that context ClassLoader will be consulted
+                ClassLoader current = ObjectFactory.class.getClassLoader();
+
+                chain = system;
+                while (true) {
+                    if (current == chain) {
+                        // Assert: Current ClassLoader in chain of
+                        // boot/extension/system ClassLoaders
+                        return system;
+                    }
+                    if (chain == null) {
+                        break;
+                    }
+                    chain = ss.getParentClassLoader(chain);
+                }
+
+                // Assert: Current ClassLoader not in chain of
+                // boot/extension/system ClassLoaders
+                return current;
+            }
+
+            if (chain == null) {
+                // boot ClassLoader reached
+                break;
+            }
+
+            // Check for any extension ClassLoaders in chain up to
+            // boot ClassLoader
+            chain = ss.getParentClassLoader(chain);
+        };
+
+        // Assert: Context ClassLoader not in chain of
+        // boot/extension/system ClassLoaders
+        return context;
+    } // findClassLoader():ClassLoader
+
+    /**
+     * Create an instance of a class using the specified ClassLoader
+     */ 
+    static Object newInstance(String className, ClassLoader cl,
+                                      boolean doFallback)
+        throws ConfigurationError
+    {
+        // assert(className != null);
+        try{
+            Class providerClass = findProviderClass(className, cl, doFallback);
+            Object instance = providerClass.newInstance();
+            debugPrintln("created new instance of " + providerClass +
+                   " using ClassLoader: " + cl);
+            return instance;
+        } catch (ClassNotFoundException x) {
+            throw new ConfigurationError(
+                "Provider " + className + " not found", x);
+        } catch (Exception x) {
+            throw new ConfigurationError(
+                "Provider " + className + " could not be instantiated: " + x,
+                x);
+        }
+    }
+
+    /**
+     * Find a Class using the specified ClassLoader
+     */ 
+    static Class findProviderClass(String className, ClassLoader cl,
+                                           boolean doFallback)
+        throws ClassNotFoundException, ConfigurationError
+    {
+      
+        SecurityManager security = System.getSecurityManager();
+        try{
+            if (security != null)
+                security.checkPackageAccess(className);
+        }catch(SecurityException e){
+            throw e;
+        }
+
+        Class providerClass;
+        if (cl == null) {
+            // XXX Use the bootstrap ClassLoader.  There is no way to
+            // load a class using the bootstrap ClassLoader that works
+            // in both JDK 1.1 and Java 2.  However, this should still
+            // work b/c the following should be true:
+            //
+            // (cl == null) iff current ClassLoader == null
+            //
+            // Thus Class.forName(String) will use the current
+            // ClassLoader which will be the bootstrap ClassLoader.
+            providerClass = Class.forName(className);
+        } else {
+            try {
+                providerClass = cl.loadClass(className);
+            } catch (ClassNotFoundException x) {
+                if (doFallback) {
+                    // Fall back to current classloader
+                    ClassLoader current = ObjectFactory.class.getClassLoader();
+                    if (current == null) {
+                        providerClass = Class.forName(className);
+                    } else if (cl != current) {
+                        cl = current;
+                        providerClass = cl.loadClass(className);
+                    } else {
+                        throw x;
+                    }
+                } else {
+                    throw x;
+                }
+            }
+        }
+
+        return providerClass;
+    }
+
+    /**
+     * Find the name of service provider using Jar Service Provider Mechanism
+     *
+     * @return instance of provider class if found or null
+     */
+    private static String findJarServiceProviderName(String factoryId)
+    {
+        SecuritySupport ss = SecuritySupport.getInstance();
+        String serviceId = SERVICES_PATH + factoryId;
+        InputStream is = null;
+
+        // First try the Context ClassLoader
+        ClassLoader cl = findClassLoader();
+
+        is = ss.getResourceAsStream(cl, serviceId);
+
+        // If no provider found then try the current ClassLoader
+        if (is == null) {
+            ClassLoader current = ObjectFactory.class.getClassLoader();
+            if (cl != current) {
+                cl = current;
+                is = ss.getResourceAsStream(cl, serviceId);
+            }
+        }
+
+        if (is == null) {
+            // No provider found
+            return null;
+        }
+
+        debugPrintln("found jar resource=" + serviceId +
+               " using ClassLoader: " + cl);
+
+        // Read the service provider name in UTF-8 as specified in
+        // the jar spec.  Unfortunately this fails in Microsoft
+        // VJ++, which does not implement the UTF-8
+        // encoding. Theoretically, we should simply let it fail in
+        // that case, since the JVM is obviously broken if it
+        // doesn't support such a basic standard.  But since there
+        // are still some users attempting to use VJ++ for
+        // development, we have dropped in a fallback which makes a
+        // second attempt using the platform's default encoding. In
+        // VJ++ this is apparently ASCII, which is a subset of
+        // UTF-8... and since the strings we'll be reading here are
+        // also primarily limited to the 7-bit ASCII range (at
+        // least, in English versions), this should work well
+        // enough to keep us on the air until we're ready to
+        // officially decommit from VJ++. [Edited comment from
+        // jkesselm]
+        BufferedReader rd;
+        try {
+            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        } catch (java.io.UnsupportedEncodingException e) {
+            rd = new BufferedReader(new InputStreamReader(is));
+        }
+        
+        String factoryClassName = null;
+        try {
+            // XXX Does not handle all possible input as specified by the
+            // Jar Service Provider specification
+            factoryClassName = rd.readLine();
+            rd.close();
+        } catch (IOException x) {
+            // No provider found
+            return null;
+        }
+
+        if (factoryClassName != null &&
+            ! "".equals(factoryClassName)) {
+            debugPrintln("found in resource, value="
+                   + factoryClassName);
+
+            // Note: here we do not want to fall back to the current
+            // ClassLoader because we want to avoid the case where the
+            // resource file was found using one ClassLoader and the
+            // provider class was instantiated using a different one.
+            return factoryClassName;
+        }
+
+        // No provider found
+        return null;
+    }
+
+    //
+    // Classes
+    //
+
+    /**
+     * A configuration error.
+     */
+    static class ConfigurationError 
+        extends Error {
+
+        //
+        // Data
+        //
+
+        /** Exception. */
+        private Exception exception;
+
+        //
+        // Constructors
+        //
+
+        /**
+         * Construct a new instance with the specified detail string and
+         * exception.
+         */
+        public ConfigurationError(String msg, Exception x) {
+            super(msg);
+            this.exception = x;
+        } // <init>(String,Exception)
+
+        //
+        // Public methods
+        //
+
+        /** Returns the exception associated to this error. */
+        public Exception getException() {
+            return exception;
+        } // getException():Exception
+
+    } // class ConfigurationError
+
+} // class ObjectFactory
diff --git a/src/org/apache/xpath/functions/SecuritySupport.java b/src/org/apache/xpath/functions/SecuritySupport.java
index 9b72c62..31ddf0f 100644
--- a/src/org/apache/xpath/functions/SecuritySupport.java
+++ b/src/org/apache/xpath/functions/SecuritySupport.java
@@ -113,33 +113,33 @@
      * Return an appropriate instance of this class, depending on whether
      * we're on a JDK 1.1 or J2SE 1.2 (or later) system.
      */
-    public static SecuritySupport getInstance() {
+    static SecuritySupport getInstance() {
 	return (SecuritySupport)securitySupport;
     }
 
-    public ClassLoader getContextClassLoader() {
+    ClassLoader getContextClassLoader() {
 	return null;
     }
 
-    public ClassLoader getSystemClassLoader() {
+    ClassLoader getSystemClassLoader() {
         return null;
     }
 
-    public ClassLoader getParentClassLoader(ClassLoader cl) {
+    ClassLoader getParentClassLoader(ClassLoader cl) {
         return null;
     }
 
-    public String getSystemProperty(String propName) {
+    String getSystemProperty(String propName) {
         return System.getProperty(propName);
     }
 
-    public FileInputStream getFileInputStream(File file)
+    FileInputStream getFileInputStream(File file)
         throws FileNotFoundException
     {
         return new FileInputStream(file);
     }
 
-    public InputStream getResourceAsStream(ClassLoader cl, String name) {
+    InputStream getResourceAsStream(ClassLoader cl, String name) {
         InputStream ris;
         if (cl == null) {
             ris = ClassLoader.getSystemResourceAsStream(name);
@@ -149,11 +149,11 @@
         return ris;
     }
     
-    public boolean getFileExists(File f) {
+    boolean getFileExists(File f) {
         return f.exists();
     }
     
-    public long getLastModified(File f) {
+    long getLastModified(File f) {
         return f.lastModified();
     }    
 }
diff --git a/src/org/apache/xpath/functions/SecuritySupport12.java b/src/org/apache/xpath/functions/SecuritySupport12.java
index 79a2eb2..702c19e 100644
--- a/src/org/apache/xpath/functions/SecuritySupport12.java
+++ b/src/org/apache/xpath/functions/SecuritySupport12.java
@@ -76,7 +76,7 @@
  */
 class SecuritySupport12 extends SecuritySupport {
 
-    public ClassLoader getContextClassLoader() {
+    ClassLoader getContextClassLoader() {
         return (ClassLoader)
                 AccessController.doPrivileged(new PrivilegedAction() {
             public Object run() {
@@ -89,7 +89,7 @@
         });
     }
 
-    public ClassLoader getSystemClassLoader() {
+    ClassLoader getSystemClassLoader() {
         return (ClassLoader)
             AccessController.doPrivileged(new PrivilegedAction() {
                 public Object run() {
@@ -102,7 +102,7 @@
             });
     }
 
-    public ClassLoader getParentClassLoader(final ClassLoader cl) {
+    ClassLoader getParentClassLoader(final ClassLoader cl) {
         return (ClassLoader)
             AccessController.doPrivileged(new PrivilegedAction() {
                 public Object run() {
@@ -118,7 +118,7 @@
             });
     }
 
-    public String getSystemProperty(final String propName) {
+    String getSystemProperty(final String propName) {
         return (String)
             AccessController.doPrivileged(new PrivilegedAction() {
                 public Object run() {
@@ -127,7 +127,7 @@
             });
     }
 
-    public FileInputStream getFileInputStream(final File file)
+    FileInputStream getFileInputStream(final File file)
         throws FileNotFoundException
     {
         try {
@@ -142,7 +142,7 @@
         }
     }
 
-    public InputStream getResourceAsStream(final ClassLoader cl,
+    InputStream getResourceAsStream(final ClassLoader cl,
                                            final String name)
     {
         return (InputStream)
@@ -159,7 +159,7 @@
             });
     }
     
-    public boolean getFileExists(final File f) {
+    boolean getFileExists(final File f) {
     return ((Boolean)
             AccessController.doPrivileged(new PrivilegedAction() {
                 public Object run() {
@@ -168,7 +168,7 @@
             })).booleanValue();
     }
     
-    public long getLastModified(final File f) {
+    long getLastModified(final File f) {
     return ((Long)
             AccessController.doPrivileged(new PrivilegedAction() {
                 public Object run() {
diff --git a/src/trax/trax.properties b/src/trax/trax.properties
deleted file mode 100644
index e593c39..0000000
--- a/src/trax/trax.properties
+++ /dev/null
@@ -1,11 +0,0 @@
-# $Revision$ $Date$
-#
-# Note: This properties file is provided for illustrative purposes
-#       only and is not part of the interface definition.
-#       This properties file is located in the implementation JAR
-#       and different implementations will specify different
-#       implementation classes and output methods.
-#
-
-# The TRaX Stylesheet processor
-trax.processor.xslt=org.apache.xalan.processor.StylesheetProcessor
