<commit_before>/*
 * Copyright (C) 2003, 2004, 2005, 2006 <NAME>.
 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 XStream Committers.
 * All rights reserved.
 *
 * The software in this package is published under the terms of the BSD
 * style license a copy of which has been included with this distribution in
 * the LICENSE.txt file.
 * 
 * Created on 26. September 2003 by <NAME>
 */
package com.thoughtworks.xstream;

import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.NotActiveException;
import java.io.ObjectInputStream;
import java.io.ObjectInputValidation;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
import java.util.regex.Pattern;

import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.ConverterLookup;
import com.thoughtworks.xstream.converters.ConverterRegistry;
import com.thoughtworks.xstream.converters.DataHolder;
import com.thoughtworks.xstream.converters.SingleValueConverter;
import com.thoughtworks.xstream.converters.SingleValueConverterWrapper;
import com.thoughtworks.xstream.converters.basic.BigDecimalConverter;
import com.thoughtworks.xstream.converters.basic.BigIntegerConverter;
import com.thoughtworks.xstream.converters.basic.BooleanConverter;
import com.thoughtworks.xstream.converters.basic.ByteConverter;
import com.thoughtworks.xstream.converters.basic.CharConverter;
import com.thoughtworks.xstream.converters.basic.DateConverter;
import com.thoughtworks.xstream.converters.basic.DoubleConverter;
import com.thoughtworks.xstream.converters.basic.FloatConverter;
import com.thoughtworks.xstream.converters.basic.IntConverter;
import com.thoughtworks.xstream.converters.basic.LongConverter;
import com.thoughtworks.xstream.converters.basic.NullConverter;
import com.thoughtworks.xstream.converters.basic.ShortConverter;
import com.thoughtworks.xstream.converters.basic.StringBufferConverter;
import com.thoughtworks.xstream.converters.basic.StringConverter;
import com.thoughtworks.xstream.converters.basic.URIConverter;
import com.thoughtworks.xstream.converters.basic.URLConverter;
import com.thoughtworks.xstream.converters.collections.ArrayConverter;
import com.thoughtworks.xstream.converters.collections.BitSetConverter;
import com.thoughtworks.xstream.converters.collections.CharArrayConverter;
import com.thoughtworks.xstream.converters.collections.CollectionConverter;
import com.thoughtworks.xstream.converters.collections.MapConverter;
import com.thoughtworks.xstream.converters.collections.PropertiesConverter;
import com.thoughtworks.xstream.converters.collections.SingletonCollectionConverter;
import com.thoughtworks.xstream.converters.collections.SingletonMapConverter;
import com.thoughtworks.xstream.converters.collections.TreeMapConverter;
import com.thoughtworks.xstream.converters.collections.TreeSetConverter;
import com.thoughtworks.xstream.converters.extended.ColorConverter;
import com.thoughtworks.xstream.converters.extended.DynamicProxyConverter;
import com.thoughtworks.xstream.converters.extended.EncodedByteArrayConverter;
import com.thoughtworks.xstream.converters.extended.FileConverter;
import com.thoughtworks.xstream.converters.extended.FontConverter;
import com.thoughtworks.xstream.converters.extended.GregorianCalendarConverter;
import com.thoughtworks.xstream.converters.extended.JavaClassConverter;
import com.thoughtworks.xstream.converters.extended.JavaFieldConverter;
import com.thoughtworks.xstream.converters.extended.JavaMethodConverter;
import com.thoughtworks.xstream.converters.extended.LocaleConverter;
import com.thoughtworks.xstream.converters.extended.LookAndFeelConverter;
import com.thoughtworks.xstream.converters.extended.SqlDateConverter;
import com.thoughtworks.xstream.converters.extended.SqlTimeConverter;
import com.thoughtworks.xstream.converters.extended.SqlTimestampConverter;
import com.thoughtworks.xstream.converters.extended.TextAttributeConverter;
import com.thoughtworks.xstream.converters.reflection.ExternalizableConverter;
import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
import com.thoughtworks.xstream.converters.reflection.SerializableConverter;
import com.thoughtworks.xstream.core.ClassLoaderReference;
import com.thoughtworks.xstream.core.DefaultConverterLookup;
import com.thoughtworks.xstream.core.JVM;
import com.thoughtworks.xstream.core.MapBackedDataHolder;
import com.thoughtworks.xstream.core.ReferenceByIdMarshallingStrategy;
import com.thoughtworks.xstream.core.ReferenceByXPathMarshallingStrategy;
import com.thoughtworks.xstream.core.TreeMarshallingStrategy;
import com.thoughtworks.xstream.core.util.CompositeClassLoader;
import com.thoughtworks.xstream.core.util.CustomObjectInputStream;
import com.thoughtworks.xstream.core.util.CustomObjectOutputStream;
import com.thoughtworks.xstream.core.util.SelfStreamingInstanceChecker;
import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.StatefulWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;
import com.thoughtworks.xstream.mapper.AnnotationConfiguration;
import com.thoughtworks.xstream.mapper.ArrayMapper;
import com.thoughtworks.xstream.mapper.AttributeAliasingMapper;
import com.thoughtworks.xstream.mapper.AttributeMapper;
import com.thoughtworks.xstream.mapper.CachingMapper;
import com.thoughtworks.xstream.mapper.ClassAliasingMapper;
import com.thoughtworks.xstream.mapper.DefaultImplementationsMapper;
import com.thoughtworks.xstream.mapper.DefaultMapper;
import com.thoughtworks.xstream.mapper.DynamicProxyMapper;
import com.thoughtworks.xstream.mapper.FieldAliasingMapper;
import com.thoughtworks.xstream.mapper.ImmutableTypesMapper;
import com.thoughtworks.xstream.mapper.ImplicitCollectionMapper;
import com.thoughtworks.xstream.mapper.LocalConversionMapper;
import com.thoughtworks.xstream.mapper.Mapper;
import com.thoughtworks.xstream.mapper.MapperWrapper;
import com.thoughtworks.xstream.mapper.OuterClassMapper;
import com.thoughtworks.xstream.mapper.PackageAliasingMapper;
import com.thoughtworks.xstream.mapper.SystemAttributeAliasingMapper;
import com.thoughtworks.xstream.mapper.XStream11XmlFriendlyMapper;


/**
 * Simple facade to XStream library, a Java-XML serialization tool. <p/>
 * <p>
 * <hr>
 * <b>Example</b><blockquote>
 *
 * <pre>
 * XStream xstream = new XStream();
 * String xml = xstream.toXML(myObject); // serialize to XML
 * Object myObject2 = xstream.fromXML(xml); // deserialize from XML
 * </pre>
 *
 * </blockquote>
 * <hr>
 * <p/>
 * <h3>Aliasing classes</h3>
 * <p/>
 * <p>
 * To create shorter XML, you can specify aliases for classes using the <code>alias()</code>
 * method. For example, you can shorten all occurrences of element
 * <code>&lt;com.blah.MyThing&gt;</code> to <code>&lt;my-thing&gt;</code> by registering an
 * alias for the class.
 * <p>
 * <hr>
 * <blockquote>
 *
 * <pre>
 * xstream.alias(&quot;my-thing&quot;, MyThing.class);
 * </pre>
 *
 * </blockquote>
 * <hr>
 * <p/>
 * <h3>Converters</h3>
 * <p/>
 * <p>
 * XStream contains a map of {@link com.thoughtworks.xstream.converters.Converter} instances, each
 * of which acts as a strategy for converting a particular type of class to XML and back again. Out
 * of the box, XStream contains converters for most basic types (String, Date, int, boolean, etc)
 * and collections (Map, List, Set, Properties, etc). For other objects reflection is used to
 * serialize each field recursively.
 * </p>
 * <p/>
 * <p>
 * Extra converters can be registered using the <code>registerConverter()</code> method. Some
 * non-standard converters are supplied in the {@link com.thoughtworks.xstream.converters.extended}
 * package and you can create your own by implementing the
 * {@link com.thoughtworks.xstream.converters.Converter} interface.
 * </p>
 * <p/>
 * <p>
 * <hr>
 * <b>Example</b><blockquote>
 *
 * <pre>
 * xstream.registerConverter(new SqlTimestampConverter());
 * xstream.registerConverter(new DynamicProxyConverter());
 * </pre>
 *
 * </blockquote>
 * <hr>
 * <p>
 * The converters can be registered with an explicit priority. By default they are registered with 
 * XStream.PRIORITY_NORMAL. Converters of same priority will be used in the reverse sequence
 * they have been registered. The default converter, i.e. the converter which will be used if
 * no other registered converter is suitable, can be registered with priority
 * XStream.PRIORITY_VERY_LOW. XStream uses by default the
 * {@link com.thoughtworks.xstream.converters.reflection.ReflectionConverter} as the fallback
 * converter.
 * </p>
 * <p/>
 * <p>
 * <hr>
 * <b>Example</b><blockquote>
 *
 * <pre>
 * xstream.registerConverter(new CustomDefaultConverter(), XStream.PRIORITY_VERY_LOW);
 * </pre>
 *
 * </blockquote>
 * <hr>
 * <p/>
 * <h3>Object graphs</h3>
 * <p/>
 * <p>
 * XStream has support for object graphs; a deserialized object graph will keep references intact,
 * including circular references.
 * </p>
 * <p/>
 * <p>
 * XStream can signify references in XML using either relative/absolute XPath or IDs. The mode can be changed using
 * <code>setMode()</code>:
 * </p>
 * <p/>
 * <table border='1'>
 * <tr>
 * <td><code>xstream.setMode(XStream.XPATH_RELATIVE_REFERENCES);</code></td>
 * <td><i>(Default)</i> Uses XPath relative references to signify duplicate references. This produces XML
 * with the least clutter.</td>
 * </tr>
 * <tr>
 * <td><code>xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);</code></td>
 * <td>Uses XPath absolute references to signify duplicate
 * references. This produces XML with the least clutter.</td>
 * </tr>
 * <tr>
 * <td><code>xstream.setMode(XStream.SINGLE_NODE_XPATH_RELATIVE_REFERENCES);</code></td>
 * <td>Uses XPath relative references to signify duplicate references. The XPath expression ensures that
 * a single node only is selected always.</td>
 * </tr>
 * <tr>
 * <td><code>xstream.setMode(XStream.SINGLE_NODE_XPATH_ABSOLUTE_REFERENCES);</code></td>
 * <td>Uses XPath absolute references to signify duplicate references.  The XPath expression ensures that
 * a single node only is selected always.</td>
 * </tr>
 * <tr>
 * <td><code>xstream.setMode(XStream.ID_REFERENCES);</code></td>
 * <td>Uses ID references to signify duplicate references. In some scenarios, such as when using
 * hand-written XML, this is easier to work with.</td>
 * </tr>
 * <tr>
 * <td><code>xstream.setMode(XStream.NO_REFERENCES);</code></td>
 * <td>This disables object graph support and treats the object structure like a tree. Duplicate
 * references are treated as two separate objects and circular references cause an exception. This
 * is slightly faster and uses less memory than the other two modes.</td>
 * </tr>
 * </table>
 * <h3>Thread safety</h3>
 * <p>
 * The XStream instance is thread-safe. That is, once the XStream instance has been created and
 * configured, it may be shared across multiple threads allowing objects to be
 * serialized/deserialized concurrently. <em>Note, that this only applies if annotations are not 
 * auto-detected on -the-fly.</em>
 * </p>
 * <h3>Implicit collections</h3>
 * <p/>
 * <p>
 * To avoid the need for special tags for collections, you can define implicit collections using one
 * of the <code>addImplicitCollection</code> methods.
 * </p>
 *
 * @author <NAME>
 * @author J&ouml;<NAME>
 * @author <NAME>
 * @author <NAME>
 */
public class XStream {

    // CAUTION: The sequence of the fields is intentional for an optimal XML output of a
    // self-serialization!
    private ReflectionProvider reflectionProvider;
    private HierarchicalStreamDriver hierarchicalStreamDriver;
    private ClassLoaderReference classLoaderReference;
    private MarshallingStrategy marshallingStrategy;
    private ConverterLookup converterLookup;
    private ConverterRegistry converterRegistry;
    private Mapper mapper;

    private PackageAliasingMapper packageAliasingMapper;
    private ClassAliasingMapper classAliasingMapper;
    private FieldAliasingMapper fieldAliasingMapper;
    private AttributeAliasingMapper attributeAliasingMapper;
    private SystemAttributeAliasingMapper systemAttributeAliasingMapper;
    private AttributeMapper attributeMapper;
    private DefaultImplementationsMapper defaultImplementationsMapper;
    private ImmutableTypesMapper immutableTypesMapper;
    private ImplicitCollectionMapper implicitCollectionMapper;
    private LocalConversionMapper localConversionMapper;
    private AnnotationConfiguration annotationConfiguration;

    public static final int NO_REFERENCES = 1001;
    public static final int ID_REFERENCES = 1002;
    public static final int XPATH_RELATIVE_REFERENCES = 1003;
    public static final int XPATH_ABSOLUTE_REFERENCES = 1004;
    public static final int SINGLE_NODE_XPATH_RELATIVE_REFERENCES = 1005;
    public static final int SINGLE_NODE_XPATH_ABSOLUTE_REFERENCES = 1006;

    public static final int PRIORITY_VERY_HIGH = 10000;
    public static final int PRIORITY_NORMAL = 0;
    public static final int PRIORITY_LOW = -10;
    public static final int PRIORITY_VERY_LOW = -20;

    private static final String ANNOTATION_MAPPER_TYPE = "com.thoughtworks.xstream.mapper.AnnotationMapper";
    private static final Pattern IGNORE_ALL = Pattern.compile(".*");

    /**
     * Constructs a default XStream.
     * <p>
     * The instance will use the {@link XppDriver} as default and tries to determine the best
     * match for the {@link ReflectionProvider} on its own.
     * </p>
     * 
     * @throws InitializationException in case of an initialization problem
     */
    public XStream() {
        this(null, (Mapper)null, new XppDriver());
    }

    /**
     * Constructs an XStream with a special {@link ReflectionProvider}.
     * <p>
     * The instance will use the {@link XppDriver} as default.
     * </p>
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching reflection provider
     * @throws InitializationException in case of an initialization problem
     */
    public XStream(ReflectionProvider reflectionProvider) {
        this(reflectionProvider, (Mapper)null, new XppDriver());
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver}.
     * <p>
     * The instance will tries to determine the best match for the {@link ReflectionProvider} on
     * its own.
     * </p>
     * 
     * @param hierarchicalStreamDriver the driver instance
     * @throws InitializationException in case of an initialization problem
     */
    public XStream(HierarchicalStreamDriver hierarchicalStreamDriver) {
        this(null, (Mapper)null, hierarchicalStreamDriver);
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver} and
     * {@link ReflectionProvider}.
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching Provider
     * @param hierarchicalStreamDriver the driver instance
     * @throws InitializationException in case of an initialization problem
     */
    public XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver hierarchicalStreamDriver) {
        this(reflectionProvider, (Mapper)null, hierarchicalStreamDriver);
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver},
     * {@link ReflectionProvider} and a prepared {@link Mapper} chain.
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching Provider
     * @param mapper the instance with the {@link Mapper} chain or <em>null</em> for the default
     *            chain
     * @param driver the driver instance
     * @throws InitializationException in case of an initialization problem
     * @deprecated As of 1.3, use
     *             {@link #XStream(ReflectionProvider, HierarchicalStreamDriver, ClassLoader, Mapper)}
     *             instead
     */
    public XStream(
        ReflectionProvider reflectionProvider, Mapper mapper, HierarchicalStreamDriver driver) {
        this(reflectionProvider, driver, new CompositeClassLoader(), mapper);
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver},
     * {@link ReflectionProvider} and a {@link ClassLoaderReference}.
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching Provider
     * @param driver the driver instance
     * @param classLoaderReference the reference to the {@link ClassLoader} to use
     * @throws InitializationException in case of an initialization problem
     * @since upcoming
     */
    public XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
        ClassLoaderReference classLoaderReference) {
        this(reflectionProvider, driver, classLoaderReference, null);
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver},
     * {@link ReflectionProvider} and the {@link ClassLoader} to use.
     * 
     * @throws InitializationException in case of an initialization problem
     * @since 1.3
     * @deprecated As of upcoming use
     *             {@link #XStream(ReflectionProvider, HierarchicalStreamDriver, ClassLoaderReference)}
     */
    public XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
        ClassLoader classLoader) {
        this(reflectionProvider, driver, classLoader, null);
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver},
     * {@link ReflectionProvider}, a prepared {@link Mapper} chain and the {@link ClassLoader}
     * to use.
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching Provider
     * @param driver the driver instance
     * @param classLoader the {@link ClassLoader} to use
     * @param mapper the instance with the {@link Mapper} chain or <em>null</em> for the default
     *            chain
     * @throws InitializationException in case of an initialization problem
     * @since 1.3
     * @deprecated As of upcoming use
     *             {@link #XStream(ReflectionProvider, HierarchicalStreamDriver, ClassLoaderReference, Mapper)}
     */
    public XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
        ClassLoader classLoader, Mapper mapper) {
        this(
            reflectionProvider, driver, new ClassLoaderReference(classLoader), mapper, new DefaultConverterLookup());
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver},
     * {@link ReflectionProvider}, a prepared {@link Mapper} chain and the
     * {@link ClassLoaderReference}.
     * <p>
     * The {@link ClassLoaderReference} should also be used for the {@link Mapper} chain.
     * </p>
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching Provider
     * @param driver the driver instance
     * @param classLoaderReference the reference to the {@link ClassLoader} to use
     * @param mapper the instance with the {@link Mapper} chain or <em>null</em> for the default
     *            chain
     * @throws InitializationException in case of an initialization problem
     * @since upcoming
     */
    public XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
        ClassLoaderReference classLoaderReference, Mapper mapper) {
        this(
            reflectionProvider, driver, classLoaderReference, mapper, new DefaultConverterLookup());
    }
    
    private XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
        ClassLoaderReference classLoader, Mapper mapper, DefaultConverterLookup defaultConverterLookup) {
        this(
            reflectionProvider, driver, classLoader, mapper, defaultConverterLookup,
            defaultConverterLookup);
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver},
     * {@link ReflectionProvider}, a prepared {@link Mapper} chain, the
     * {@link ClassLoaderReference} and an own {@link ConverterLookup} and
     * {@link ConverterRegistry}.
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching Provider
     * @param driver the driver instance
     * @param classLoader the {@link ClassLoader} to use
     * @param mapper the instance with the {@link Mapper} chain or <em>null</em> for the default
     *            chain
     * @param converterLookup the instance that is used to lookup the converters
     * @param converterRegistry an instance to manage the converter instances
     * @throws InitializationException in case of an initialization problem
     * @since 1.3
     * @deprecated As of upcoming use
     *             {@link #XStream(ReflectionProvider, HierarchicalStreamDriver, ClassLoaderReference, Mapper, ConverterLookup, ConverterRegistry)}
     */
    public XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
        ClassLoader classLoader, Mapper mapper, ConverterLookup converterLookup,
        ConverterRegistry converterRegistry) {
        this(reflectionProvider, driver, new ClassLoaderReference(classLoader), mapper, converterLookup, converterRegistry);
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver},
     * {@link ReflectionProvider}, a prepared {@link Mapper} chain, the
     * {@link ClassLoaderReference} and an own {@link ConverterLookup} and
     * {@link ConverterRegistry}.
     * <p>
     * The {@link ClassLoaderReference} should also be used for the {@link Mapper} chain.
     * </p>
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching Provider
     * @param driver the driver instance
     * @param classLoaderReference the reference to the {@link ClassLoader} to use
     * @param mapper the instance with the {@link Mapper} chain or <em>null</em> for the default
     *            chain
     * @param converterLookup the instance that is used to lookup the converters
     * @param converterRegistry an instance to manage the converter instances
     * @throws InitializationException in case of an initialization problem
     * @since upcoming
     */
    public XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
        ClassLoaderReference classLoaderReference, Mapper mapper, ConverterLookup converterLookup,<commit_msg>Improve javadoc.<commit_after>/*
 * Copyright (C) 2003, 2004, 2005, 2006 <NAME>.
 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 XStream Committers.
 * All rights reserved.
 *
 * The software in this package is published under the terms of the BSD
 * style license a copy of which has been included with this distribution in
 * the LICENSE.txt file.
 * 
 * Created on 26. September 2003 by <NAME>
 */
package com.thoughtworks.xstream;

import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.NotActiveException;
import java.io.ObjectInputStream;
import java.io.ObjectInputValidation;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
import java.util.regex.Pattern;

import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.ConverterLookup;
import com.thoughtworks.xstream.converters.ConverterRegistry;
import com.thoughtworks.xstream.converters.DataHolder;
import com.thoughtworks.xstream.converters.SingleValueConverter;
import com.thoughtworks.xstream.converters.SingleValueConverterWrapper;
import com.thoughtworks.xstream.converters.basic.BigDecimalConverter;
import com.thoughtworks.xstream.converters.basic.BigIntegerConverter;
import com.thoughtworks.xstream.converters.basic.BooleanConverter;
import com.thoughtworks.xstream.converters.basic.ByteConverter;
import com.thoughtworks.xstream.converters.basic.CharConverter;
import com.thoughtworks.xstream.converters.basic.DateConverter;
import com.thoughtworks.xstream.converters.basic.DoubleConverter;
import com.thoughtworks.xstream.converters.basic.FloatConverter;
import com.thoughtworks.xstream.converters.basic.IntConverter;
import com.thoughtworks.xstream.converters.basic.LongConverter;
import com.thoughtworks.xstream.converters.basic.NullConverter;
import com.thoughtworks.xstream.converters.basic.ShortConverter;
import com.thoughtworks.xstream.converters.basic.StringBufferConverter;
import com.thoughtworks.xstream.converters.basic.StringConverter;
import com.thoughtworks.xstream.converters.basic.URIConverter;
import com.thoughtworks.xstream.converters.basic.URLConverter;
import com.thoughtworks.xstream.converters.collections.ArrayConverter;
import com.thoughtworks.xstream.converters.collections.BitSetConverter;
import com.thoughtworks.xstream.converters.collections.CharArrayConverter;
import com.thoughtworks.xstream.converters.collections.CollectionConverter;
import com.thoughtworks.xstream.converters.collections.MapConverter;
import com.thoughtworks.xstream.converters.collections.PropertiesConverter;
import com.thoughtworks.xstream.converters.collections.SingletonCollectionConverter;
import com.thoughtworks.xstream.converters.collections.SingletonMapConverter;
import com.thoughtworks.xstream.converters.collections.TreeMapConverter;
import com.thoughtworks.xstream.converters.collections.TreeSetConverter;
import com.thoughtworks.xstream.converters.extended.ColorConverter;
import com.thoughtworks.xstream.converters.extended.DynamicProxyConverter;
import com.thoughtworks.xstream.converters.extended.EncodedByteArrayConverter;
import com.thoughtworks.xstream.converters.extended.FileConverter;
import com.thoughtworks.xstream.converters.extended.FontConverter;
import com.thoughtworks.xstream.converters.extended.GregorianCalendarConverter;
import com.thoughtworks.xstream.converters.extended.JavaClassConverter;
import com.thoughtworks.xstream.converters.extended.JavaFieldConverter;
import com.thoughtworks.xstream.converters.extended.JavaMethodConverter;
import com.thoughtworks.xstream.converters.extended.LocaleConverter;
import com.thoughtworks.xstream.converters.extended.LookAndFeelConverter;
import com.thoughtworks.xstream.converters.extended.SqlDateConverter;
import com.thoughtworks.xstream.converters.extended.SqlTimeConverter;
import com.thoughtworks.xstream.converters.extended.SqlTimestampConverter;
import com.thoughtworks.xstream.converters.extended.TextAttributeConverter;
import com.thoughtworks.xstream.converters.reflection.ExternalizableConverter;
import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
import com.thoughtworks.xstream.converters.reflection.SerializableConverter;
import com.thoughtworks.xstream.core.ClassLoaderReference;
import com.thoughtworks.xstream.core.DefaultConverterLookup;
import com.thoughtworks.xstream.core.JVM;
import com.thoughtworks.xstream.core.MapBackedDataHolder;
import com.thoughtworks.xstream.core.ReferenceByIdMarshallingStrategy;
import com.thoughtworks.xstream.core.ReferenceByXPathMarshallingStrategy;
import com.thoughtworks.xstream.core.TreeMarshallingStrategy;
import com.thoughtworks.xstream.core.util.CompositeClassLoader;
import com.thoughtworks.xstream.core.util.CustomObjectInputStream;
import com.thoughtworks.xstream.core.util.CustomObjectOutputStream;
import com.thoughtworks.xstream.core.util.SelfStreamingInstanceChecker;
import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.StatefulWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;
import com.thoughtworks.xstream.mapper.AnnotationConfiguration;
import com.thoughtworks.xstream.mapper.ArrayMapper;
import com.thoughtworks.xstream.mapper.AttributeAliasingMapper;
import com.thoughtworks.xstream.mapper.AttributeMapper;
import com.thoughtworks.xstream.mapper.CachingMapper;
import com.thoughtworks.xstream.mapper.ClassAliasingMapper;
import com.thoughtworks.xstream.mapper.DefaultImplementationsMapper;
import com.thoughtworks.xstream.mapper.DefaultMapper;
import com.thoughtworks.xstream.mapper.DynamicProxyMapper;
import com.thoughtworks.xstream.mapper.FieldAliasingMapper;
import com.thoughtworks.xstream.mapper.ImmutableTypesMapper;
import com.thoughtworks.xstream.mapper.ImplicitCollectionMapper;
import com.thoughtworks.xstream.mapper.LocalConversionMapper;
import com.thoughtworks.xstream.mapper.Mapper;
import com.thoughtworks.xstream.mapper.MapperWrapper;
import com.thoughtworks.xstream.mapper.OuterClassMapper;
import com.thoughtworks.xstream.mapper.PackageAliasingMapper;
import com.thoughtworks.xstream.mapper.SystemAttributeAliasingMapper;
import com.thoughtworks.xstream.mapper.XStream11XmlFriendlyMapper;


/**
 * Simple facade to XStream library, a Java-XML serialization tool. <p/>
 * <p>
 * <hr>
 * <b>Example</b><blockquote>
 *
 * <pre>
 * XStream xstream = new XStream();
 * String xml = xstream.toXML(myObject); // serialize to XML
 * Object myObject2 = xstream.fromXML(xml); // deserialize from XML
 * </pre>
 *
 * </blockquote>
 * <hr>
 * <p/>
 * <h3>Aliasing classes</h3>
 * <p/>
 * <p>
 * To create shorter XML, you can specify aliases for classes using the <code>alias()</code>
 * method. For example, you can shorten all occurrences of element
 * <code>&lt;com.blah.MyThing&gt;</code> to <code>&lt;my-thing&gt;</code> by registering an
 * alias for the class.
 * <p>
 * <hr>
 * <blockquote>
 *
 * <pre>
 * xstream.alias(&quot;my-thing&quot;, MyThing.class);
 * </pre>
 *
 * </blockquote>
 * <hr>
 * <p/>
 * <h3>Converters</h3>
 * <p/>
 * <p>
 * XStream contains a map of {@link com.thoughtworks.xstream.converters.Converter} instances, each
 * of which acts as a strategy for converting a particular type of class to XML and back again. Out
 * of the box, XStream contains converters for most basic types (String, Date, int, boolean, etc)
 * and collections (Map, List, Set, Properties, etc). For other objects reflection is used to
 * serialize each field recursively.
 * </p>
 * <p/>
 * <p>
 * Extra converters can be registered using the <code>registerConverter()</code> method. Some
 * non-standard converters are supplied in the {@link com.thoughtworks.xstream.converters.extended}
 * package and you can create your own by implementing the
 * {@link com.thoughtworks.xstream.converters.Converter} interface.
 * </p>
 * <p/>
 * <p>
 * <hr>
 * <b>Example</b><blockquote>
 *
 * <pre>
 * xstream.registerConverter(new SqlTimestampConverter());
 * xstream.registerConverter(new DynamicProxyConverter());
 * </pre>
 *
 * </blockquote>
 * <hr>
 * <p>
 * The converters can be registered with an explicit priority. By default they are registered with 
 * XStream.PRIORITY_NORMAL. Converters of same priority will be used in the reverse sequence
 * they have been registered. The default converter, i.e. the converter which will be used if
 * no other registered converter is suitable, can be registered with priority
 * XStream.PRIORITY_VERY_LOW. XStream uses by default the
 * {@link com.thoughtworks.xstream.converters.reflection.ReflectionConverter} as the fallback
 * converter.
 * </p>
 * <p/>
 * <p>
 * <hr>
 * <b>Example</b><blockquote>
 *
 * <pre>
 * xstream.registerConverter(new CustomDefaultConverter(), XStream.PRIORITY_VERY_LOW);
 * </pre>
 *
 * </blockquote>
 * <hr>
 * <p/>
 * <h3>Object graphs</h3>
 * <p/>
 * <p>
 * XStream has support for object graphs; a deserialized object graph will keep references intact,
 * including circular references.
 * </p>
 * <p/>
 * <p>
 * XStream can signify references in XML using either relative/absolute XPath or IDs. The mode can be changed using
 * <code>setMode()</code>:
 * </p>
 * <p/>
 * <table border='1'>
 * <tr>
 * <td><code>xstream.setMode(XStream.XPATH_RELATIVE_REFERENCES);</code></td>
 * <td><i>(Default)</i> Uses XPath relative references to signify duplicate references. This produces XML
 * with the least clutter.</td>
 * </tr>
 * <tr>
 * <td><code>xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);</code></td>
 * <td>Uses XPath absolute references to signify duplicate
 * references. This produces XML with the least clutter.</td>
 * </tr>
 * <tr>
 * <td><code>xstream.setMode(XStream.SINGLE_NODE_XPATH_RELATIVE_REFERENCES);</code></td>
 * <td>Uses XPath relative references to signify duplicate references. The XPath expression ensures that
 * a single node only is selected always.</td>
 * </tr>
 * <tr>
 * <td><code>xstream.setMode(XStream.SINGLE_NODE_XPATH_ABSOLUTE_REFERENCES);</code></td>
 * <td>Uses XPath absolute references to signify duplicate references.  The XPath expression ensures that
 * a single node only is selected always.</td>
 * </tr>
 * <tr>
 * <td><code>xstream.setMode(XStream.ID_REFERENCES);</code></td>
 * <td>Uses ID references to signify duplicate references. In some scenarios, such as when using
 * hand-written XML, this is easier to work with.</td>
 * </tr>
 * <tr>
 * <td><code>xstream.setMode(XStream.NO_REFERENCES);</code></td>
 * <td>This disables object graph support and treats the object structure like a tree. Duplicate
 * references are treated as two separate objects and circular references cause an exception. This
 * is slightly faster and uses less memory than the other two modes.</td>
 * </tr>
 * </table>
 * <h3>Thread safety</h3>
 * <p>
 * The XStream instance is thread-safe. That is, once the XStream instance has been created and
 * configured, it may be shared across multiple threads allowing objects to be
 * serialized/deserialized concurrently. <em>Note, that this only applies if annotations are not 
 * auto-detected on -the-fly.</em>
 * </p>
 * <h3>Implicit collections</h3>
 * <p/>
 * <p>
 * To avoid the need for special tags for collections, you can define implicit collections using one
 * of the <code>addImplicitCollection</code> methods.
 * </p>
 *
 * @author <NAME>
 * @author J&ouml;<NAME>
 * @author <NAME>
 * @author <NAME>
 */
public class XStream {

    // CAUTION: The sequence of the fields is intentional for an optimal XML output of a
    // self-serialization!
    private ReflectionProvider reflectionProvider;
    private HierarchicalStreamDriver hierarchicalStreamDriver;
    private ClassLoaderReference classLoaderReference;
    private MarshallingStrategy marshallingStrategy;
    private ConverterLookup converterLookup;
    private ConverterRegistry converterRegistry;
    private Mapper mapper;

    private PackageAliasingMapper packageAliasingMapper;
    private ClassAliasingMapper classAliasingMapper;
    private FieldAliasingMapper fieldAliasingMapper;
    private AttributeAliasingMapper attributeAliasingMapper;
    private SystemAttributeAliasingMapper systemAttributeAliasingMapper;
    private AttributeMapper attributeMapper;
    private DefaultImplementationsMapper defaultImplementationsMapper;
    private ImmutableTypesMapper immutableTypesMapper;
    private ImplicitCollectionMapper implicitCollectionMapper;
    private LocalConversionMapper localConversionMapper;
    private AnnotationConfiguration annotationConfiguration;

    public static final int NO_REFERENCES = 1001;
    public static final int ID_REFERENCES = 1002;
    public static final int XPATH_RELATIVE_REFERENCES = 1003;
    public static final int XPATH_ABSOLUTE_REFERENCES = 1004;
    public static final int SINGLE_NODE_XPATH_RELATIVE_REFERENCES = 1005;
    public static final int SINGLE_NODE_XPATH_ABSOLUTE_REFERENCES = 1006;

    public static final int PRIORITY_VERY_HIGH = 10000;
    public static final int PRIORITY_NORMAL = 0;
    public static final int PRIORITY_LOW = -10;
    public static final int PRIORITY_VERY_LOW = -20;

    private static final String ANNOTATION_MAPPER_TYPE = "com.thoughtworks.xstream.mapper.AnnotationMapper";
    private static final Pattern IGNORE_ALL = Pattern.compile(".*");

    /**
     * Constructs a default XStream.
     * <p>
     * The instance will use the {@link XppDriver} as default and tries to determine the best
     * match for the {@link ReflectionProvider} on its own.
     * </p>
     * 
     * @throws InitializationException in case of an initialization problem
     */
    public XStream() {
        this(null, (Mapper)null, new XppDriver());
    }

    /**
     * Constructs an XStream with a special {@link ReflectionProvider}.
     * <p>
     * The instance will use the {@link XppDriver} as default.
     * </p>
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching reflection provider
     * @throws InitializationException in case of an initialization problem
     */
    public XStream(ReflectionProvider reflectionProvider) {
        this(reflectionProvider, (Mapper)null, new XppDriver());
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver}.
     * <p>
     * The instance will tries to determine the best match for the {@link ReflectionProvider} on
     * its own.
     * </p>
     * 
     * @param hierarchicalStreamDriver the driver instance
     * @throws InitializationException in case of an initialization problem
     */
    public XStream(HierarchicalStreamDriver hierarchicalStreamDriver) {
        this(null, (Mapper)null, hierarchicalStreamDriver);
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver} and
     * {@link ReflectionProvider}.
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching Provider
     * @param hierarchicalStreamDriver the driver instance
     * @throws InitializationException in case of an initialization problem
     */
    public XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver hierarchicalStreamDriver) {
        this(reflectionProvider, (Mapper)null, hierarchicalStreamDriver);
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver},
     * {@link ReflectionProvider} and a prepared {@link Mapper} chain.
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching Provider
     * @param mapper the instance with the {@link Mapper} chain or <em>null</em> for the default
     *            chain
     * @param driver the driver instance
     * @throws InitializationException in case of an initialization problem
     * @deprecated As of 1.3, use
     *             {@link #XStream(ReflectionProvider, HierarchicalStreamDriver, ClassLoader, Mapper)}
     *             instead
     */
    public XStream(
        ReflectionProvider reflectionProvider, Mapper mapper, HierarchicalStreamDriver driver) {
        this(reflectionProvider, driver, new CompositeClassLoader(), mapper);
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver},
     * {@link ReflectionProvider} and a {@link ClassLoaderReference}.
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching Provider
     * @param driver the driver instance
     * @param classLoaderReference the reference to the {@link ClassLoader} to use
     * @throws InitializationException in case of an initialization problem
     * @since upcoming
     */
    public XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
        ClassLoaderReference classLoaderReference) {
        this(reflectionProvider, driver, classLoaderReference, null);
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver},
     * {@link ReflectionProvider} and the {@link ClassLoader} to use.
     * 
     * @throws InitializationException in case of an initialization problem
     * @since 1.3
     * @deprecated As of upcoming use
     *             {@link #XStream(ReflectionProvider, HierarchicalStreamDriver, ClassLoaderReference)}
     */
    public XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
        ClassLoader classLoader) {
        this(reflectionProvider, driver, classLoader, null);
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver},
     * {@link ReflectionProvider}, a prepared {@link Mapper} chain and the {@link ClassLoader}
     * to use.
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching Provider
     * @param driver the driver instance
     * @param classLoader the {@link ClassLoader} to use
     * @param mapper the instance with the {@link Mapper} chain or <em>null</em> for the default
     *            chain
     * @throws InitializationException in case of an initialization problem
     * @since 1.3
     * @deprecated As of upcoming use
     *             {@link #XStream(ReflectionProvider, HierarchicalStreamDriver, ClassLoaderReference, Mapper)}
     */
    public XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
        ClassLoader classLoader, Mapper mapper) {
        this(
            reflectionProvider, driver, new ClassLoaderReference(classLoader), mapper, new DefaultConverterLookup());
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver},
     * {@link ReflectionProvider}, a prepared {@link Mapper} chain and the
     * {@link ClassLoaderReference}.
     * <p>
     * The {@link ClassLoaderReference} should also be used for the {@link Mapper} chain.
     * </p>
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching Provider
     * @param driver the driver instance
     * @param classLoaderReference the reference to the {@link ClassLoader} to use
     * @param mapper the instance with the {@link Mapper} chain or <em>null</em> for the default
     *            chain
     * @throws InitializationException in case of an initialization problem
     * @since upcoming
     */
    public XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
        ClassLoaderReference classLoaderReference, Mapper mapper) {
        this(
            reflectionProvider, driver, classLoaderReference, mapper, new DefaultConverterLookup());
    }
    
    private XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
        ClassLoaderReference classLoader, Mapper mapper, DefaultConverterLookup defaultConverterLookup) {
        this(
            reflectionProvider, driver, classLoader, mapper, defaultConverterLookup,
            defaultConverterLookup);
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver},
     * {@link ReflectionProvider}, a prepared {@link Mapper} chain, the
     * {@link ClassLoaderReference} and an own {@link ConverterLookup} and
     * {@link ConverterRegistry}.
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching Provider
     * @param driver the driver instance
     * @param classLoader the {@link ClassLoader} to use
     * @param mapper the instance with the {@link Mapper} chain or <em>null</em> for the default
     *            chain
     * @param converterLookup the instance that is used to lookup the converters
     * @param converterRegistry an instance to manage the converter instances
     * @throws InitializationException in case of an initialization problem
     * @since 1.3
     * @deprecated As of upcoming use
     *             {@link #XStream(ReflectionProvider, HierarchicalStreamDriver, ClassLoaderReference, Mapper, ConverterLookup, ConverterRegistry)}
     */
    public XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
        ClassLoader classLoader, Mapper mapper, ConverterLookup converterLookup,
        ConverterRegistry converterRegistry) {
        this(reflectionProvider, driver, new ClassLoaderReference(classLoader), mapper, converterLookup, converterRegistry);
    }

    /**
     * Constructs an XStream with a special {@link HierarchicalStreamDriver},
     * {@link ReflectionProvider}, a prepared {@link Mapper} chain, the
     * {@link ClassLoaderReference} and an own {@link ConverterLookup} and
     * {@link ConverterRegistry}.
     * <p>
     * The ClassLoaderReference should also be used for the Mapper chain. The ConverterLookup
     * should access the ConverterRegistry if you intent to register {@link Converter} instances
     * with XStream facade or you are using annotations.
     * </p>
     * 
     * @param reflectionProvider the reflection provider to use or <em>null</em> for best
     *            matching Provider
     * @param driver the driver instance
     * @param classLoaderReference the reference to the {@link ClassLoader} to use
     * @param mapper the instance with the {@link Mapper} chain or <em>null</em> for the default
     *            chain
     * @param converterLookup the instance that is used to lookup the converters
     * @param converterRegistry an instance to manage the converter instances or <em>null</em>
     *            to prevent any further registry (including annotations)
     * @throws InitializationException in case of an initialization problem
     * @since upcoming
     */
    public XStream(
        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
        ClassLoaderReference classLoaderReference, Mapper mapper, ConverterLookup converterLookup,
{'fraction_non_alphanumeric': 0.08905051683894631, 'fraction_numerical': 0.00458486162054018, 'mean_word_length': 4.267866944779888, 'pattern_counts': {'":': 0, '<': 365, '<?xml version=': 0, '>': 365, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2364995', 'n_tokens_mistral': 13606, 'n_tokens_neox': 13040, 'n_words': 3743}