[activemq] 01/02: Import Debian changes 5.6.0+dfsg-1+deb7u2

Markus Koschany apo at moszumanska.debian.org
Tue Apr 25 18:57:42 UTC 2017


This is an automated email from the git hooks/post-receive script.

apo pushed a commit to branch wheezy
in repository activemq.

commit e1811fcab3a951cda2950bf22e9f8906976eb718
Author: Markus Koschany <apo at debian.org>
Date:   Fri Mar 18 22:47:35 2016 +0100

    Import Debian changes 5.6.0+dfsg-1+deb7u2
    
    activemq (5.6.0+dfsg-1+deb7u2) wheezy-security; urgency=high
    
      * Team upload.
      * Fix CVE-2015-5254:
        Apache ActiveMQ 5.x before 5.13.0 does not restrict the classes that can be
        serialized in the broker, which allows remote attackers to execute
        arbitrary code via a crafted serialized Java Message Service (JMS)
        ObjectMessage object.
---
 .gitignore                         |    1 -
 debian/changelog                   |   11 +
 debian/patches/CVE-2015-5254.patch | 3034 ++++++++++++++++++++++++++++++++++++
 debian/patches/series              |    1 +
 debian/source/local-options        |    1 -
 5 files changed, 3046 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore
index 60b9923..1af5e76 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
-.pc
 *~
 *.swp
 .idea
diff --git a/debian/changelog b/debian/changelog
index b262759..5aec11b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,14 @@
+activemq (5.6.0+dfsg-1+deb7u2) wheezy-security; urgency=high
+
+  * Team upload.
+  * Fix CVE-2015-5254:
+    Apache ActiveMQ 5.x before 5.13.0 does not restrict the classes that can be
+    serialized in the broker, which allows remote attackers to execute
+    arbitrary code via a crafted serialized Java Message Service (JMS)
+    ObjectMessage object.
+
+ -- Markus Koschany <apo at debian.org>  Fri, 18 Mar 2016 22:47:35 +0100
+
 activemq (5.6.0+dfsg-1+deb7u1) wheezy-security; urgency=high
 
   * Team upload.
diff --git a/debian/patches/CVE-2015-5254.patch b/debian/patches/CVE-2015-5254.patch
new file mode 100644
index 0000000..2e653e6
--- /dev/null
+++ b/debian/patches/CVE-2015-5254.patch
@@ -0,0 +1,3034 @@
+From: Markus Koschany <apo at debian.org>
+Date: Wed, 16 Mar 2016 18:35:42 +0100
+Subject: CVE-2015-5254
+
+Apache ActiveMQ 5.x before 5.13.0 does not restrict the classes that can be
+serialized in the broker, which allows remote attackers to execute arbitrary
+code via a crafted serialized Java Message Service (JMS) ObjectMessage object.
+
+Origin: https://git-wip-us.apache.org/repos/asf?p=activemq.git;h=6f03921b31d9fefeddb0f4fa63150ed1f94a14b1
+Origin: https://git-wip-us.apache.org/repos/asf?p=activemq.git;h=73a0caf758f9e4916783a205c7e422b4db27905c
+Origin: http://pkgs.fedoraproject.org/cgit/activemq.git/diff/activemq-5.6.0-CVE-2015-5254.patch?id=e3ef8a1b62d10273a814090be9168aa3019ace72
+Debian-Bug: https://bugs.debian.org/809733
+---
+ .../java/com/thoughtworks/xstream/XStream.java     | 1928 ++++++++++++++++++++
+ .../xstream/mapper/FieldAliasingMapper.java        |   99 +
+ .../xstream/mapper/SecurityMapper.java             |   79 +
+ .../xstream/security/AnyTypePermission.java        |   32 +
+ .../xstream/security/ArrayTypePermission.java      |   32 +
+ .../xstream/security/ExplicitTypePermission.java   |   54 +
+ .../xstream/security/ForbiddenClassException.java  |   27 +
+ .../xstream/security/InterfaceTypePermission.java  |   33 +
+ .../xstream/security/NoPermission.java             |   39 +
+ .../xstream/security/NoTypePermission.java         |   36 +
+ .../xstream/security/NullPermission.java           |   26 +
+ .../xstream/security/PrimitiveTypePermission.java  |   34 +
+ .../xstream/security/ProxyTypePermission.java      |   37 +
+ .../xstream/security/RegExpTypePermission.java     |   48 +
+ .../xstream/security/TypeHierarchyPermission.java  |   32 +
+ .../xstream/security/TypePermission.java           |   25 +
+ .../xstream/security/WildcardTypePermission.java   |   84 +
+ .../transport/stomp/JmsFrameTranslator.java        |    5 +-
+ .../activemq/transport/stomp/XStreamSupport.java   |   47 +
+ .../util/ClassLoadingAwareObjectInputStream.java   |   48 +-
+ .../transport/xstream/XStreamWireFormat.java       |   29 +-
+ .../java/org/apache/activemq/web/MessageQuery.java |    4 +-
+ 22 files changed, 2769 insertions(+), 9 deletions(-)
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/XStream.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/mapper/SecurityMapper.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/security/AnyTypePermission.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/security/ArrayTypePermission.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/security/ExplicitTypePermission.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/security/ForbiddenClassException.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/security/InterfaceTypePermission.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/security/NoPermission.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/security/NoTypePermission.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/security/NullPermission.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/security/PrimitiveTypePermission.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/security/ProxyTypePermission.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/security/RegExpTypePermission.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/security/TypeHierarchyPermission.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/security/TypePermission.java
+ create mode 100644 activemq-core/src/main/java/com/thoughtworks/xstream/security/WildcardTypePermission.java
+ create mode 100644 activemq-core/src/main/java/org/apache/activemq/transport/stomp/XStreamSupport.java
+
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/XStream.java b/activemq-core/src/main/java/com/thoughtworks/xstream/XStream.java
+new file mode 100644
+index 0000000..29c047a
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/XStream.java
+@@ -0,0 +1,1928 @@
++/*
++ * Copyright (C) 2003, 2004, 2005, 2006 Joe Walnes.
++ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 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 Joe Walnes
++ */
++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.SelfStreamingInstanceChecker;
++import com.thoughtworks.xstream.converters.reflection.SerializableConverter;
++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.ClassLoaderReference;
++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.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;
++import com.thoughtworks.xstream.security.AnyTypePermission;
++import com.thoughtworks.xstream.security.ExplicitTypePermission;
++import com.thoughtworks.xstream.security.NoPermission;
++import com.thoughtworks.xstream.security.NoTypePermission;
++import com.thoughtworks.xstream.security.RegExpTypePermission;
++import com.thoughtworks.xstream.security.TypeHierarchyPermission;
++import com.thoughtworks.xstream.security.TypePermission;
++import com.thoughtworks.xstream.security.WildcardTypePermission;
++import com.thoughtworks.xstream.mapper.SecurityMapper;
++
++
++/**
++ * 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><com.blah.MyThing></code> to <code><my-thing></code> by registering an
++ * alias for the class.
++ * <p>
++ * <hr>
++ * <blockquote>
++ *
++ * <pre>
++ * xstream.alias("my-thing", 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 Joe Walnes
++ * @author Jörg Schaible
++ * @author Mauro Talevi
++ * @author Guilherme Silveira
++ */
++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;
++    private SecurityMapper securityMapper;
++
++    private transient JVM jvm = new JVM();
++
++    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. The instance will use the {@link XppDriver} as default and
++     * tries to determine the best match for the {@link ReflectionProvider} on its own.
++     * 
++     * @throws InitializationException in case of an initialization problem
++     */
++    public XStream() {
++        this(null, (Mapper)null, new XppDriver());
++    }
++
++    /**
++     * Constructs an XStream with a special {@link ReflectionProvider}. The instance will use
++     * the {@link XppDriver} as default.
++     * 
++     * @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}. The instance will
++     * tries to determine the best match for the {@link ReflectionProvider} on its own.
++     * 
++     * @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}.
++     * 
++     * @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} and
++     * {@link ReflectionProvider} and additionally with a prepared {@link Mapper}.
++     * 
++     * @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 ClassLoaderReference(new CompositeClassLoader()),
++            mapper, new DefaultConverterLookup(), null);
++    }
++
++    /**
++     * Constructs an XStream with a special {@link HierarchicalStreamDriver} and
++     * {@link ReflectionProvider} and additionally with a prepared {@link ClassLoader} to use.
++     * 
++     * @throws InitializationException in case of an initialization problem
++     * @since 1.3
++     */
++    public XStream(
++        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
++        ClassLoader classLoader) {
++        this(reflectionProvider, driver, classLoader, null);
++    }
++
++    /**
++     * Constructs an XStream with a special {@link HierarchicalStreamDriver} and
++     * {@link ReflectionProvider} and additionally with a prepared {@link Mapper} and the
++     * {@link ClassLoader} in use.
++     * <p>
++     * Note, if the class loader should be changed later again, you should provide a
++     * {@link ClassLoaderReference} as {@link ClassLoader} that is also use in the
++     * {@link Mapper} chain.
++     * </p>
++     * 
++     * @throws InitializationException in case of an initialization problem
++     * @since 1.3
++     */
++    public XStream(
++        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
++        ClassLoader classLoader, Mapper mapper) {
++        this(
++            reflectionProvider, driver, classLoader, mapper, new DefaultConverterLookup(), null);
++    }
++
++    /**
++     * Constructs an XStream with a special {@link HierarchicalStreamDriver},
++     * {@link ReflectionProvider}, a prepared {@link Mapper} and the {@link ClassLoader} in use
++     * and an own {@link ConverterRegistry}.
++     * <p>
++     * Note, if the class loader should be changed later again, you should provide a
++     * {@link ClassLoaderReference} as {@link ClassLoader} that is also use in the
++     * {@link Mapper} chain.
++     * </p>
++     * 
++     * @throws InitializationException in case of an initialization problem
++     * @since 1.3
++     */
++    public XStream(
++        ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver,
++        ClassLoader classLoader, Mapper mapper, ConverterLookup converterLookup,
++        ConverterRegistry converterRegistry) {
++        jvm = new JVM();
++        if (reflectionProvider == null) {
++            reflectionProvider = jvm.bestReflectionProvider();
++        }
++        this.reflectionProvider = reflectionProvider;
++        this.hierarchicalStreamDriver = driver;
++        this.classLoaderReference = classLoader instanceof ClassLoaderReference
++            ? (ClassLoaderReference)classLoader
++            : new ClassLoaderReference(classLoader);
++        this.converterLookup = converterLookup;
++        this.converterRegistry = converterRegistry != null
++            ? converterRegistry
++            : (converterLookup instanceof ConverterRegistry
++                ? (ConverterRegistry)converterLookup
++                : null);
++        this.mapper = mapper == null ? buildMapper() : mapper;
++
++        setupMappers();
++        setupAliases();
++        setupDefaultImplementations();
++        setupConverters();
++        setupImmutableTypes();
++        setMode(XPATH_RELATIVE_REFERENCES);
++    }
++
++    private Mapper buildMapper() {
++        Mapper mapper = new DefaultMapper(classLoaderReference);
++        if (useXStream11XmlFriendlyMapper()) {
++            mapper = new XStream11XmlFriendlyMapper(mapper);
++        }
++        mapper = new DynamicProxyMapper(mapper);
++        mapper = new PackageAliasingMapper(mapper);
++        mapper = new ClassAliasingMapper(mapper);
++        mapper = new FieldAliasingMapper(mapper);
++        mapper = new AttributeAliasingMapper(mapper);
++        mapper = new SystemAttributeAliasingMapper(mapper);
++        mapper = new ImplicitCollectionMapper(mapper);
++        mapper = new OuterClassMapper(mapper);
++        mapper = new ArrayMapper(mapper);
++        mapper = new DefaultImplementationsMapper(mapper);
++        mapper = new AttributeMapper(mapper, converterLookup, reflectionProvider);
++        if (JVM.is15()) {
++            mapper = buildMapperDynamically(
++                "com.thoughtworks.xstream.mapper.EnumMapper", new Class[]{Mapper.class},
++                new Object[]{mapper});
++        }
++        mapper = new LocalConversionMapper(mapper);
++        mapper = new ImmutableTypesMapper(mapper);
++        if (JVM.is15()) {
++            mapper = buildMapperDynamically(ANNOTATION_MAPPER_TYPE, new Class[]{
++                Mapper.class, ConverterRegistry.class, ConverterLookup.class,
++                ClassLoader.class, ReflectionProvider.class, JVM.class}, new Object[]{
++                mapper, converterLookup, converterLookup, classLoaderReference,
++                reflectionProvider, jvm});
++        }
++        mapper = wrapMapper((MapperWrapper)mapper);
++        mapper = new CachingMapper(mapper);
++        return mapper;
++    }
++
++    private Mapper buildMapperDynamically(String className, Class[] constructorParamTypes,
++        Object[] constructorParamValues) {
++        try {
++            Class type = Class.forName(className, false, classLoaderReference.getReference());
++            Constructor constructor = type.getConstructor(constructorParamTypes);
++            return (Mapper)constructor.newInstance(constructorParamValues);
++        } catch (Exception e) {
++            throw new com.thoughtworks.xstream.InitializationException(
++                "Could not instantiate mapper : " + className, e);
++        }
++    }
++
++    protected MapperWrapper wrapMapper(MapperWrapper next) {
++        return next;
++    }
++
++    protected boolean useXStream11XmlFriendlyMapper() {
++        return false;
++    }
++
++    private void setupMappers() {
++        packageAliasingMapper = (PackageAliasingMapper)this.mapper
++            .lookupMapperOfType(PackageAliasingMapper.class);
++        classAliasingMapper = (ClassAliasingMapper)this.mapper
++            .lookupMapperOfType(ClassAliasingMapper.class);
++        fieldAliasingMapper = (FieldAliasingMapper)this.mapper
++            .lookupMapperOfType(FieldAliasingMapper.class);
++        attributeMapper = (AttributeMapper)this.mapper
++            .lookupMapperOfType(AttributeMapper.class);
++        attributeAliasingMapper = (AttributeAliasingMapper)this.mapper
++            .lookupMapperOfType(AttributeAliasingMapper.class);
++        systemAttributeAliasingMapper = (SystemAttributeAliasingMapper)this.mapper
++            .lookupMapperOfType(SystemAttributeAliasingMapper.class);
++        implicitCollectionMapper = (ImplicitCollectionMapper)this.mapper
++            .lookupMapperOfType(ImplicitCollectionMapper.class);
++        defaultImplementationsMapper = (DefaultImplementationsMapper)this.mapper
++            .lookupMapperOfType(DefaultImplementationsMapper.class);
++        immutableTypesMapper = (ImmutableTypesMapper)this.mapper
++            .lookupMapperOfType(ImmutableTypesMapper.class);
++        localConversionMapper = (LocalConversionMapper)this.mapper
++            .lookupMapperOfType(LocalConversionMapper.class);
++        annotationConfiguration = (AnnotationConfiguration)this.mapper
++            .lookupMapperOfType(AnnotationConfiguration.class);
++    }
++
++    protected void setupAliases() {
++        if (classAliasingMapper == null) {
++            return;
++        }
++
++        alias("null", Mapper.Null.class);
++        alias("int", Integer.class);
++        alias("float", Float.class);
++        alias("double", Double.class);
++        alias("long", Long.class);
++        alias("short", Short.class);
++        alias("char", Character.class);
++        alias("byte", Byte.class);
++        alias("boolean", Boolean.class);
++        alias("number", Number.class);
++        alias("object", Object.class);
++        alias("big-int", BigInteger.class);
++        alias("big-decimal", BigDecimal.class);
++
++        alias("string-buffer", StringBuffer.class);
++        alias("string", String.class);
++        alias("java-class", Class.class);
++        alias("method", Method.class);
++        alias("constructor", Constructor.class);
++        alias("field", Field.class);
++        alias("date", Date.class);
++        alias("uri", URI.class);
++        alias("url", URL.class);
++        alias("bit-set", BitSet.class);
++
++        alias("map", Map.class);
++        alias("entry", Map.Entry.class);
++        alias("properties", Properties.class);
++        alias("list", List.class);
++        alias("set", Set.class);
++        alias("sorted-set", SortedSet.class);
++
++        alias("linked-list", LinkedList.class);
++        alias("vector", Vector.class);
++        alias("tree-map", TreeMap.class);
++        alias("tree-set", TreeSet.class);
++        alias("hashtable", Hashtable.class);
++        
++        alias("empty-list", Collections.EMPTY_LIST.getClass());
++        alias("empty-map", Collections.EMPTY_MAP.getClass());
++        alias("empty-set", Collections.EMPTY_SET.getClass());
++        alias("singleton-list", Collections.singletonList(this).getClass());
++        alias("singleton-map", Collections.singletonMap(this, null).getClass());
++        alias("singleton-set", Collections.singleton(this).getClass());
++
++        if (jvm.supportsAWT()) {
++            // Instantiating these two classes starts the AWT system, which is undesirable.
++            // Calling loadClass ensures a reference to the class is found but they are not
++            // instantiated.
++            alias("awt-color", jvm.loadClass("java.awt.Color"));
++            alias("awt-font", jvm.loadClass("java.awt.Font"));
++            alias("awt-text-attribute", jvm.loadClass("java.awt.font.TextAttribute"));
++        }
++
++        if (jvm.supportsSQL()) {
++            alias("sql-timestamp", jvm.loadClass("java.sql.Timestamp"));
++            alias("sql-time", jvm.loadClass("java.sql.Time"));
++            alias("sql-date", jvm.loadClass("java.sql.Date"));
++        }
++
++        alias("file", File.class);
++        alias("locale", Locale.class);
++        alias("gregorian-calendar", Calendar.class);
++
++        if (JVM.is14()) {
++            aliasDynamically("auth-subject", "javax.security.auth.Subject");
++            alias("linked-hash-map", jvm.loadClass("java.util.LinkedHashMap"));
++            alias("linked-hash-set", jvm.loadClass("java.util.LinkedHashSet"));
++            alias("trace", jvm.loadClass("java.lang.StackTraceElement"));
++            alias("currency", jvm.loadClass("java.util.Currency"));
++            aliasType("charset", jvm.loadClass("java.nio.charset.Charset"));
++        }
++
++        if (JVM.is15()) {
++            aliasDynamically("duration", "javax.xml.datatype.Duration");
++            alias("enum-set", jvm.loadClass("java.util.EnumSet"));
++            alias("enum-map", jvm.loadClass("java.util.EnumMap"));
++            alias("string-builder", jvm.loadClass("java.lang.StringBuilder"));
++            alias("uuid", jvm.loadClass("java.util.UUID"));
++        }
++    }
++
++    private void aliasDynamically(String alias, String className) {
++        Class type = jvm.loadClass(className);
++        if (type != null) {
++            alias(alias, type);
++        }
++    }
++
++    protected void setupDefaultImplementations() {
++        if (defaultImplementationsMapper == null) {
++            return;
++        }
++        addDefaultImplementation(HashMap.class, Map.class);
++        addDefaultImplementation(ArrayList.class, List.class);
++        addDefaultImplementation(HashSet.class, Set.class);
++        addDefaultImplementation(TreeSet.class, SortedSet.class);
++        addDefaultImplementation(GregorianCalendar.class, Calendar.class);
++    }
++
++    protected void setupConverters() {
++        final ReflectionConverter reflectionConverter = new ReflectionConverter(
++            mapper, reflectionProvider);
++        registerConverter(reflectionConverter, PRIORITY_VERY_LOW);
++
++        registerConverter(
++            new SerializableConverter(mapper, reflectionProvider, classLoaderReference), PRIORITY_LOW);
++        registerConverter(new ExternalizableConverter(mapper, classLoaderReference), PRIORITY_LOW);
++
++        registerConverter(new NullConverter(), PRIORITY_VERY_HIGH);
++        registerConverter(new IntConverter(), PRIORITY_NORMAL);
++        registerConverter(new FloatConverter(), PRIORITY_NORMAL);
++        registerConverter(new DoubleConverter(), PRIORITY_NORMAL);
++        registerConverter(new LongConverter(), PRIORITY_NORMAL);
++        registerConverter(new ShortConverter(), PRIORITY_NORMAL);
++        registerConverter((Converter)new CharConverter(), PRIORITY_NORMAL);
++        registerConverter(new BooleanConverter(), PRIORITY_NORMAL);
++        registerConverter(new ByteConverter(), PRIORITY_NORMAL);
++
++        registerConverter(new StringConverter(), PRIORITY_NORMAL);
++        registerConverter(new StringBufferConverter(), PRIORITY_NORMAL);
++        registerConverter(new DateConverter(), PRIORITY_NORMAL);
++        registerConverter(new BitSetConverter(), PRIORITY_NORMAL);
++        registerConverter(new URIConverter(), PRIORITY_NORMAL);
++        registerConverter(new URLConverter(), PRIORITY_NORMAL);
++        registerConverter(new BigIntegerConverter(), PRIORITY_NORMAL);
++        registerConverter(new BigDecimalConverter(), PRIORITY_NORMAL);
++
++        registerConverter(new ArrayConverter(mapper), PRIORITY_NORMAL);
++        registerConverter(new CharArrayConverter(), PRIORITY_NORMAL);
++        registerConverter(new CollectionConverter(mapper), PRIORITY_NORMAL);
++        registerConverter(new MapConverter(mapper), PRIORITY_NORMAL);
++        registerConverter(new TreeMapConverter(mapper), PRIORITY_NORMAL);
++        registerConverter(new TreeSetConverter(mapper), PRIORITY_NORMAL);
++        registerConverter(new SingletonCollectionConverter(mapper), PRIORITY_NORMAL);
++        registerConverter(new SingletonMapConverter(mapper), PRIORITY_NORMAL);
++        registerConverter(new PropertiesConverter(), PRIORITY_NORMAL);
++        registerConverter((Converter)new EncodedByteArrayConverter(), PRIORITY_NORMAL);
++
++        registerConverter(new FileConverter(), PRIORITY_NORMAL);
++        if (jvm.supportsSQL()) {
++            registerConverter(new SqlTimestampConverter(), PRIORITY_NORMAL);
++            registerConverter(new SqlTimeConverter(), PRIORITY_NORMAL);
++            registerConverter(new SqlDateConverter(), PRIORITY_NORMAL);
++        }
++        registerConverter(
++            new DynamicProxyConverter(mapper, classLoaderReference), PRIORITY_NORMAL);
++        registerConverter(new JavaClassConverter(classLoaderReference), PRIORITY_NORMAL);
++        registerConverter(new JavaMethodConverter(classLoaderReference), PRIORITY_NORMAL);
++        registerConverter(new JavaFieldConverter(classLoaderReference), PRIORITY_NORMAL);
++        if (jvm.supportsAWT()) {
++            registerConverter(new FontConverter(), PRIORITY_NORMAL);
++            registerConverter(new ColorConverter(), PRIORITY_NORMAL);
++            registerConverter(new TextAttributeConverter(), PRIORITY_NORMAL);
++        }
++        if (jvm.supportsSwing()) {
++            registerConverter(
++                new LookAndFeelConverter(mapper, reflectionProvider), PRIORITY_NORMAL);
++        }
++        registerConverter(new LocaleConverter(), PRIORITY_NORMAL);
++        registerConverter(new GregorianCalendarConverter(), PRIORITY_NORMAL);
++
++        if (JVM.is14()) {
++            // late bound converters - allows XStream to be compiled on earlier JDKs
++            registerConverterDynamically(
++                "com.thoughtworks.xstream.converters.extended.SubjectConverter",
++                PRIORITY_NORMAL, new Class[]{Mapper.class}, new Object[]{mapper});
++            registerConverterDynamically(
++                "com.thoughtworks.xstream.converters.extended.ThrowableConverter",
++                PRIORITY_NORMAL, new Class[]{Converter.class},
++                new Object[]{reflectionConverter});
++            registerConverterDynamically(
++                "com.thoughtworks.xstream.converters.extended.StackTraceElementConverter",
++                PRIORITY_NORMAL, null, null);
++            registerConverterDynamically(
++                "com.thoughtworks.xstream.converters.extended.CurrencyConverter",
++                PRIORITY_NORMAL, null, null);
++            registerConverterDynamically(
++                "com.thoughtworks.xstream.converters.extended.RegexPatternConverter",
++                PRIORITY_NORMAL, new Class[]{Converter.class},
++                new Object[]{reflectionConverter});
++            registerConverterDynamically(
++                "com.thoughtworks.xstream.converters.extended.CharsetConverter",
++                PRIORITY_NORMAL, null, null);
++        }
++
++        if (JVM.is15()) {
++            // late bound converters - allows XStream to be compiled on earlier JDKs
++            if (jvm.loadClass("javax.xml.datatype.Duration") != null) {
++                registerConverterDynamically(
++                    "com.thoughtworks.xstream.converters.extended.DurationConverter",
++                    PRIORITY_NORMAL, null, null);
++            }
++            registerConverterDynamically(
++                "com.thoughtworks.xstream.converters.enums.EnumConverter", PRIORITY_NORMAL,
++                null, null);
++            registerConverterDynamically(
++                "com.thoughtworks.xstream.converters.enums.EnumSetConverter", PRIORITY_NORMAL,
++                new Class[]{Mapper.class}, new Object[]{mapper});
++            registerConverterDynamically(
++                "com.thoughtworks.xstream.converters.enums.EnumMapConverter", PRIORITY_NORMAL,
++                new Class[]{Mapper.class}, new Object[]{mapper});
++            registerConverterDynamically(
++                "com.thoughtworks.xstream.converters.basic.StringBuilderConverter",
++                PRIORITY_NORMAL, null, null);
++            registerConverterDynamically(
++                "com.thoughtworks.xstream.converters.basic.UUIDConverter", PRIORITY_NORMAL,
++                null, null);
++        }
++
++        registerConverter(
++            new SelfStreamingInstanceChecker(reflectionConverter, this), PRIORITY_NORMAL);
++    }
++
++    private void registerConverterDynamically(String className, int priority,
++        Class[] constructorParamTypes, Object[] constructorParamValues) {
++        try {
++            Class type = Class.forName(className, false, classLoaderReference.getReference());
++            Constructor constructor = type.getConstructor(constructorParamTypes);
++            Object instance = constructor.newInstance(constructorParamValues);
++            if (instance instanceof Converter) {
++                registerConverter((Converter)instance, priority);
++            } else if (instance instanceof SingleValueConverter) {
++                registerConverter((SingleValueConverter)instance, priority);
++            }
++        } catch (Exception e) {
++            throw new com.thoughtworks.xstream.InitializationException(
++                "Could not instantiate converter : " + className, e);
++        }
++    }
++
++    protected void setupImmutableTypes() {
++        if (immutableTypesMapper == null) {
++            return;
++        }
++
++        // primitives are always immutable
++        addImmutableType(boolean.class);
++        addImmutableType(Boolean.class);
++        addImmutableType(byte.class);
++        addImmutableType(Byte.class);
++        addImmutableType(char.class);
++        addImmutableType(Character.class);
++        addImmutableType(double.class);
++        addImmutableType(Double.class);
++        addImmutableType(float.class);
++        addImmutableType(Float.class);
++        addImmutableType(int.class);
++        addImmutableType(Integer.class);
++        addImmutableType(long.class);
++        addImmutableType(Long.class);
++        addImmutableType(short.class);
++        addImmutableType(Short.class);
++
++        // additional types
++        addImmutableType(Mapper.Null.class);
++        addImmutableType(BigDecimal.class);
++        addImmutableType(BigInteger.class);
++        addImmutableType(String.class);
++        addImmutableType(URI.class);
++        addImmutableType(URL.class);
++        addImmutableType(File.class);
++        addImmutableType(Class.class);
++
++        addImmutableType(Collections.EMPTY_LIST.getClass());
++        addImmutableType(Collections.EMPTY_SET.getClass());
++        addImmutableType(Collections.EMPTY_MAP.getClass());
++
++        if (jvm.supportsAWT()) {
++            addImmutableTypeDynamically("java.awt.font.TextAttribute");
++        }
++
++        if (JVM.is14()) {
++            // late bound types - allows XStream to be compiled on earlier JDKs
++            addImmutableTypeDynamically("java.nio.charset.Charset");
++            addImmutableTypeDynamically("java.util.Currency");
++        }
++    }
++
++    private void addImmutableTypeDynamically(String className) {
++        Class type = jvm.loadClass(className);
++        if (type != null) {
++            addImmutableType(type);
++        }
++    }
++
++    public void setMarshallingStrategy(MarshallingStrategy marshallingStrategy) {
++        this.marshallingStrategy = marshallingStrategy;
++    }
++
++    /**
++     * Serialize an object to a pretty-printed XML String.
++     * 
++     * @throws XStreamException if the object cannot be serialized
++     */
++    public String toXML(Object obj) {
++        Writer writer = new StringWriter();
++        toXML(obj, writer);
++        return writer.toString();
++    }
++
++    /**
++     * Serialize an object to the given Writer as pretty-printed XML. The Writer will be flushed
++     * afterwards and in case of an exception.
++     * 
++     * @throws XStreamException if the object cannot be serialized
++     */
++    public void toXML(Object obj, Writer out) {
++        HierarchicalStreamWriter writer = hierarchicalStreamDriver.createWriter(out);
++        try {
++            marshal(obj, writer);
++        } finally {
++            writer.flush();
++        }
++    }
++
++    /**
++     * Serialize an object to the given OutputStream as pretty-printed XML. The OutputStream
++     * will be flushed afterwards and in case of an exception.
++     * 
++     * @throws XStreamException if the object cannot be serialized
++     */
++    public void toXML(Object obj, OutputStream out) {
++        HierarchicalStreamWriter writer = hierarchicalStreamDriver.createWriter(out);
++        try {
++            marshal(obj, writer);
++        } finally {
++            writer.flush();
++        }
++    }
++
++    /**
++     * Serialize and object to a hierarchical data structure (such as XML).
++     * 
++     * @throws XStreamException if the object cannot be serialized
++     */
++    public void marshal(Object obj, HierarchicalStreamWriter writer) {
++        marshal(obj, writer, null);
++    }
++
++    /**
++     * Serialize and object to a hierarchical data structure (such as XML).
++     * 
++     * @param dataHolder Extra data you can use to pass to your converters. Use this as you
++     *            want. If not present, XStream shall create one lazily as needed.
++     * @throws XStreamException if the object cannot be serialized
++     */
++    public void marshal(Object obj, HierarchicalStreamWriter writer, DataHolder dataHolder) {
++        marshallingStrategy.marshal(writer, obj, converterLookup, mapper, dataHolder);
++    }
++
++    /**
++     * Deserialize an object from an XML String.
++     * 
++     * @throws XStreamException if the object cannot be deserialized
++     */
++    public Object fromXML(String xml) {
++        return fromXML(new StringReader(xml));
++    }
++
++    /**
++     * Deserialize an object from an XML Reader.
++     * 
++     * @throws XStreamException if the object cannot be deserialized
++     */
++    public Object fromXML(Reader reader) {
++        return unmarshal(hierarchicalStreamDriver.createReader(reader), null);
++    }
++
++    /**
++     * Deserialize an object from an XML InputStream.
++     * 
++     * @throws XStreamException if the object cannot be deserialized
++     */
++    public Object fromXML(InputStream input) {
++        return unmarshal(hierarchicalStreamDriver.createReader(input), null);
++    }
++
++    /**
++     * Deserialize an object from a URL.
++     * 
++     * Depending on the parser implementation, some might take the file path as SystemId to
++     * resolve additional references.
++     * 
++     * @throws XStreamException if the object cannot be deserialized
++     * @since 1.4
++     */
++    public Object fromXML(URL url) {
++        return unmarshal(hierarchicalStreamDriver.createReader(url), null);
++    }
++
++    /**
++     * Deserialize an object from a file.
++     * 
++     * Depending on the parser implementation, some might take the file path as SystemId to
++     * resolve additional references.
++     * 
++     * @throws XStreamException if the object cannot be deserialized
++     * @since 1.4
++     */
++    public Object fromXML(File file) {
++        return unmarshal(hierarchicalStreamDriver.createReader(file), null);
++    }
++
++    /**
++     * Deserialize an object from an XML String, populating the fields of the given root object
++     * instead of instantiating a new one. Note, that this is a special use case! With the
++     * ReflectionConverter XStream will write directly into the raw memory area of the existing
++     * object. Use with care!
++     * 
++     * @throws XStreamException if the object cannot be deserialized
++     */
++    public Object fromXML(String xml, Object root) {
++        return fromXML(new StringReader(xml), root);
++    }
++
++    /**
++     * Deserialize an object from an XML Reader, populating the fields of the given root object
++     * instead of instantiating a new one. Note, that this is a special use case! With the
++     * ReflectionConverter XStream will write directly into the raw memory area of the existing
++     * object. Use with care!
++     * 
++     * @throws XStreamException if the object cannot be deserialized
++     */
++    public Object fromXML(Reader xml, Object root) {
++        return unmarshal(hierarchicalStreamDriver.createReader(xml), root);
++    }
++
++    /**
++     * Deserialize an object from a URL, populating the fields of the given root
++     * object instead of instantiating a new one. Note, that this is a special use case! With
++     * the ReflectionConverter XStream will write directly into the raw memory area of the
++     * existing object. Use with care!
++     * 
++     * Depending on the parser implementation, some might take the file path as SystemId to
++     * resolve additional references.
++     * 
++     * @throws XStreamException if the object cannot be deserialized
++     * @since 1.4
++     */
++    public Object fromXML(URL url, Object root) {
++        return unmarshal(hierarchicalStreamDriver.createReader(url), root);
++    }
++
++    /**
++     * Deserialize an object from a file, populating the fields of the given root
++     * object instead of instantiating a new one. Note, that this is a special use case! With
++     * the ReflectionConverter XStream will write directly into the raw memory area of the
++     * existing object. Use with care!
++     * 
++     * Depending on the parser implementation, some might take the file path as SystemId to
++     * resolve additional references.
++     * 
++     * @throws XStreamException if the object cannot be deserialized
++     * @since 1.4
++     */
++    public Object fromXML(File file, Object root) {
++        return unmarshal(hierarchicalStreamDriver.createReader(file), root);
++    }
++
++    /**
++     * Deserialize an object from an XML InputStream, populating the fields of the given root
++     * object instead of instantiating a new one. Note, that this is a special use case! With
++     * the ReflectionConverter XStream will write directly into the raw memory area of the
++     * existing object. Use with care!
++     * 
++     * @throws XStreamException if the object cannot be deserialized
++     */
++    public Object fromXML(InputStream input, Object root) {
++        return unmarshal(hierarchicalStreamDriver.createReader(input), root);
++    }
++
++    /**
++     * Deserialize an object from a hierarchical data structure (such as XML).
++     * 
++     * @throws XStreamException if the object cannot be deserialized
++     */
++    public Object unmarshal(HierarchicalStreamReader reader) {
++        return unmarshal(reader, null, null);
++    }
++
++    /**
++     * Deserialize an object from a hierarchical data structure (such as XML), populating the
++     * fields of the given root object instead of instantiating a new one. Note, that this is a
++     * special use case! With the ReflectionConverter XStream will write directly into the raw
++     * memory area of the existing object. Use with care!
++     * 
++     * @throws XStreamException if the object cannot be deserialized
++     */
++    public Object unmarshal(HierarchicalStreamReader reader, Object root) {
++        return unmarshal(reader, root, null);
++    }
++
++    /**
++     * Deserialize an object from a hierarchical data structure (such as XML).
++     * 
++     * @param root If present, the passed in object will have its fields populated, as opposed
++     *            to XStream creating a new instance. Note, that this is a special use case!
++     *            With the ReflectionConverter XStream will write directly into the raw memory
++     *            area of the existing object. Use with care!
++     * @param dataHolder Extra data you can use to pass to your converters. Use this as you
++     *            want. If not present, XStream shall create one lazily as needed.
++     * @throws XStreamException if the object cannot be deserialized
++     */
++    public Object unmarshal(HierarchicalStreamReader reader, Object root, DataHolder dataHolder) {
++        try {
++            return marshallingStrategy.unmarshal(
++                root, reader, dataHolder, converterLookup, mapper);
++
++        } catch (ConversionException e) {
++            Package pkg = getClass().getPackage();
++            e.add("version", pkg != null ? pkg.getImplementationVersion() : "not available");
++            throw e;
++        }
++    }
++
++    /**
++     * Alias a Class to a shorter name to be used in XML elements.
++     * 
++     * @param name Short name
++     * @param type Type to be aliased
++     * @throws InitializationException if no {@link ClassAliasingMapper} is available
++     */
++    public void alias(String name, Class type) {
++        if (classAliasingMapper == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + ClassAliasingMapper.class.getName()
++                + " available");
++        }
++        classAliasingMapper.addClassAlias(name, type);
++    }
++
++    /**
++     * Alias a type to a shorter name to be used in XML elements. Any class that is assignable
++     * to this type will be aliased to the same name.
++     * 
++     * @param name Short name
++     * @param type Type to be aliased
++     * @since 1.2
++     * @throws InitializationException if no {@link ClassAliasingMapper} is available
++     */
++    public void aliasType(String name, Class type) {
++        if (classAliasingMapper == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + ClassAliasingMapper.class.getName()
++                + " available");
++        }
++        classAliasingMapper.addTypeAlias(name, type);
++    }
++
++    /**
++     * Alias a Class to a shorter name to be used in XML elements.
++     * 
++     * @param name Short name
++     * @param type Type to be aliased
++     * @param defaultImplementation Default implementation of type to use if no other specified.
++     * @throws InitializationException if no {@link DefaultImplementationsMapper} or no
++     *             {@link ClassAliasingMapper} is available
++     */
++    public void alias(String name, Class type, Class defaultImplementation) {
++        alias(name, type);
++        addDefaultImplementation(defaultImplementation, type);
++    }
++
++    /**
++     * Alias a package to a shorter name to be used in XML elements.
++     * 
++     * @param name Short name
++     * @param pkgName package to be aliased
++     * @throws InitializationException if no {@link DefaultImplementationsMapper} or no
++     *             {@link PackageAliasingMapper} is available
++     * @since 1.3.1
++     */
++    public void aliasPackage(String name, String pkgName) {
++        if (packageAliasingMapper == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + PackageAliasingMapper.class.getName()
++                + " available");
++        }
++        packageAliasingMapper.addPackageAlias(name, pkgName);
++    }
++
++    /**
++     * Create an alias for a field name.
++     * 
++     * @param alias the alias itself
++     * @param definedIn the type that declares the field
++     * @param fieldName the name of the field
++     * @throws InitializationException if no {@link FieldAliasingMapper} is available
++     */
++    public void aliasField(String alias, Class definedIn, String fieldName) {
++        if (fieldAliasingMapper == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + FieldAliasingMapper.class.getName()
++                + " available");
++        }
++        fieldAliasingMapper.addFieldAlias(alias, definedIn, fieldName);
++    }
++
++    /**
++     * Create an alias for an attribute
++     * 
++     * @param alias the alias itself
++     * @param attributeName the name of the attribute
++     * @throws InitializationException if no {@link AttributeAliasingMapper} is available
++     */
++    public void aliasAttribute(String alias, String attributeName) {
++        if (attributeAliasingMapper == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + AttributeAliasingMapper.class.getName()
++                + " available");
++        }
++        attributeAliasingMapper.addAliasFor(attributeName, alias);
++    }
++
++    /**
++     * Create an alias for a system attribute. XStream will not write a system attribute if its
++     * alias is set to <code>null</code>. However, this is not reversible, i.e. deserialization
++     * of the result is likely to fail afterwards and will not produce an object equal to the
++     * originally written one.
++     * 
++     * @param alias the alias itself (may be <code>null</code>)
++     * @param systemAttributeName the name of the system attribute
++     * @throws InitializationException if no {@link SystemAttributeAliasingMapper} is available
++     * @since 1.3.1
++     */
++    public void aliasSystemAttribute(String alias, String systemAttributeName) {
++        if (systemAttributeAliasingMapper == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + SystemAttributeAliasingMapper.class.getName()
++                + " available");
++        }
++        systemAttributeAliasingMapper.addAliasFor(systemAttributeName, alias);
++    }
++
++    /**
++     * Create an alias for an attribute.
++     * 
++     * @param definedIn the type where the attribute is defined
++     * @param attributeName the name of the attribute
++     * @param alias the alias itself
++     * @throws InitializationException if no {@link AttributeAliasingMapper} is available
++     * @since 1.2.2
++     */
++    public void aliasAttribute(Class definedIn, String attributeName, String alias) {
++        aliasField(alias, definedIn, attributeName);
++        useAttributeFor(definedIn, attributeName);
++    }
++
++    /**
++     * Use an attribute for a field or a specific type.
++     * 
++     * @param fieldName the name of the field
++     * @param type the Class of the type to be rendered as XML attribute
++     * @throws InitializationException if no {@link AttributeMapper} is available
++     * @since 1.2
++     */
++    public void useAttributeFor(String fieldName, Class type) {
++        if (attributeMapper == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + AttributeMapper.class.getName()
++                + " available");
++        }
++        attributeMapper.addAttributeFor(fieldName, type);
++    }
++
++    /**
++     * Use an attribute for a field declared in a specific type.
++     * 
++     * @param fieldName the name of the field
++     * @param definedIn the Class containing such field
++     * @throws InitializationException if no {@link AttributeMapper} is available
++     * @since 1.2.2
++     */
++    public void useAttributeFor(Class definedIn, String fieldName) {
++        if (attributeMapper == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + AttributeMapper.class.getName()
++                + " available");
++        }
++        attributeMapper.addAttributeFor(definedIn, fieldName);
++    }
++
++    /**
++     * Use an attribute for an arbitrary type.
++     * 
++     * @param type the Class of the type to be rendered as XML attribute
++     * @throws InitializationException if no {@link AttributeMapper} is available
++     * @since 1.2
++     */
++    public void useAttributeFor(Class type) {
++        if (attributeMapper == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + AttributeMapper.class.getName()
++                + " available");
++        }
++        attributeMapper.addAttributeFor(type);
++    }
++
++    /**
++     * Associate a default implementation of a class with an object. Whenever XStream encounters
++     * an instance of this type, it will use the default implementation instead. For example,
++     * java.util.ArrayList is the default implementation of java.util.List.
++     * 
++     * @param defaultImplementation
++     * @param ofType
++     * @throws InitializationException if no {@link DefaultImplementationsMapper} is available
++     */
++    public void addDefaultImplementation(Class defaultImplementation, Class ofType) {
++        if (defaultImplementationsMapper == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + DefaultImplementationsMapper.class.getName()
++                + " available");
++        }
++        defaultImplementationsMapper.addDefaultImplementation(defaultImplementation, ofType);
++    }
++
++    /**
++     * Add immutable types. The value of the instances of these types will always be written
++     * into the stream even if they appear multiple times.
++     * 
++     * @throws InitializationException if no {@link ImmutableTypesMapper} is available
++     */
++    public void addImmutableType(Class type) {
++        if (immutableTypesMapper == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + ImmutableTypesMapper.class.getName()
++                + " available");
++        }
++        immutableTypesMapper.addImmutableType(type);
++    }
++
++    public void registerConverter(Converter converter) {
++        registerConverter(converter, PRIORITY_NORMAL);
++    }
++
++    public void registerConverter(Converter converter, int priority) {
++        if (converterRegistry != null) {
++            converterRegistry.registerConverter(converter, priority);
++        }
++    }
++
++    public void registerConverter(SingleValueConverter converter) {
++        registerConverter(converter, PRIORITY_NORMAL);
++    }
++
++    public void registerConverter(SingleValueConverter converter, int priority) {
++        if (converterRegistry != null) {
++            converterRegistry.registerConverter(
++                new SingleValueConverterWrapper(converter), priority);
++        }
++    }
++
++    /**
++     * Register a local {@link Converter} for a field.
++     * 
++     * @param definedIn the class type the field is defined in
++     * @param fieldName the field name
++     * @param converter the converter to use
++     * @since 1.3
++     */
++    public void registerLocalConverter(Class definedIn, String fieldName, Converter converter) {
++        if (localConversionMapper == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + LocalConversionMapper.class.getName()
++                + " available");
++        }
++        localConversionMapper.registerLocalConverter(definedIn, fieldName, converter);
++    }
++
++    /**
++     * Register a local {@link SingleValueConverter} for a field.
++     * 
++     * @param definedIn the class type the field is defined in
++     * @param fieldName the field name
++     * @param converter the converter to use
++     * @since 1.3
++     */
++    public void registerLocalConverter(Class definedIn, String fieldName,
++        SingleValueConverter converter) {
++        registerLocalConverter(
++            definedIn, fieldName, (Converter)new SingleValueConverterWrapper(converter));
++    }
++
++    /**
++     * Retrieve the {@link Mapper}. This is by default a chain of {@link MapperWrapper
++     * MapperWrappers}.
++     * 
++     * @return the mapper
++     * @since 1.2
++     */
++    public Mapper getMapper() {
++        return mapper;
++    }
++
++    /**
++     * Retrieve the {@link ReflectionProvider} in use.
++     * 
++     * @return the mapper
++     * @since 1.2.1
++     */
++    public ReflectionProvider getReflectionProvider() {
++        return reflectionProvider;
++    }
++
++    public ConverterLookup getConverterLookup() {
++        return converterLookup;
++    }
++
++    /**
++     * Change mode for dealing with duplicate references. Valid values are
++     * <code>XPATH_ABSOLUTE_REFERENCES</code>, <code>XPATH_RELATIVE_REFERENCES</code>,
++     * <code>XStream.ID_REFERENCES</code> and <code>XStream.NO_REFERENCES</code>.
++     * 
++     * @throws IllegalArgumentException if the mode is not one of the declared types
++     * @see #XPATH_ABSOLUTE_REFERENCES
++     * @see #XPATH_RELATIVE_REFERENCES
++     * @see #ID_REFERENCES
++     * @see #NO_REFERENCES
++     */
++    public void setMode(int mode) {
++        switch (mode) {
++        case NO_REFERENCES:
++            setMarshallingStrategy(new TreeMarshallingStrategy());
++            break;
++        case ID_REFERENCES:
++            setMarshallingStrategy(new ReferenceByIdMarshallingStrategy());
++            break;
++        case XPATH_RELATIVE_REFERENCES:
++            setMarshallingStrategy(new ReferenceByXPathMarshallingStrategy(
++                ReferenceByXPathMarshallingStrategy.RELATIVE));
++            break;
++        case XPATH_ABSOLUTE_REFERENCES:
++            setMarshallingStrategy(new ReferenceByXPathMarshallingStrategy(
++                ReferenceByXPathMarshallingStrategy.ABSOLUTE));
++            break;
++        case SINGLE_NODE_XPATH_RELATIVE_REFERENCES:
++            setMarshallingStrategy(new ReferenceByXPathMarshallingStrategy(
++                  ReferenceByXPathMarshallingStrategy.RELATIVE 
++                | ReferenceByXPathMarshallingStrategy.SINGLE_NODE));
++            break;
++        case SINGLE_NODE_XPATH_ABSOLUTE_REFERENCES:
++            setMarshallingStrategy(new ReferenceByXPathMarshallingStrategy(
++                  ReferenceByXPathMarshallingStrategy.ABSOLUTE 
++                | ReferenceByXPathMarshallingStrategy.SINGLE_NODE));
++            break;
++        default:
++            throw new IllegalArgumentException("Unknown mode : " + mode);
++        }
++    }
++
++    /**
++     * Adds a default implicit collection which is used for any unmapped XML tag.
++     * 
++     * @param ownerType class owning the implicit collection
++     * @param fieldName name of the field in the ownerType. This field must be a concrete
++     *            collection type or matching the default implementation type of the collection
++     *            type.
++     */
++    public void addImplicitCollection(Class ownerType, String fieldName) {
++        addImplicitCollection(ownerType, fieldName, null, null);
++    }
++
++    /**
++     * Adds implicit collection which is used for all items of the given itemType.
++     * 
++     * @param ownerType class owning the implicit collection
++     * @param fieldName name of the field in the ownerType. This field must be a concrete
++     *            collection type or matching the default implementation type of the collection
++     *            type.
++     * @param itemType type of the items to be part of this collection
++     * @throws InitializationException if no {@link ImplicitCollectionMapper} is available
++     */
++    public void addImplicitCollection(Class ownerType, String fieldName, Class itemType) {
++        addImplicitCollection(ownerType, fieldName, null, itemType);
++    }
++
++    /**
++     * Adds implicit collection which is used for all items of the given element name defined by
++     * itemFieldName.
++     * 
++     * @param ownerType class owning the implicit collection
++     * @param fieldName name of the field in the ownerType. This field must be a concrete
++     *            collection type or matching the default implementation type of the collection
++     *            type.
++     * @param itemFieldName element name of the implicit collection
++     * @param itemType item type to be aliases be the itemFieldName
++     * @throws InitializationException if no {@link ImplicitCollectionMapper} is available
++     */
++    public void addImplicitCollection(Class ownerType, String fieldName, String itemFieldName,
++        Class itemType) {
++        addImplicitMap(ownerType, fieldName, itemFieldName, itemType, null);
++    }
++
++    /**
++     * Adds an implicit array.
++     * 
++     * @param ownerType class owning the implicit array
++     * @param fieldName name of the array field
++     * @since 1.4 
++     */
++    public void addImplicitArray(Class ownerType, String fieldName) {
++        addImplicitCollection(ownerType, fieldName);
++    }
++
++    /**
++     * Adds an implicit array which is used for all items of the given itemType when the array
++     * type matches.
++     * 
++     * @param ownerType class owning the implicit array
++     * @param fieldName name of the array field in the ownerType
++     * @param itemType type of the items to be part of this array
++     * @throws InitializationException if no {@link ImplicitCollectionMapper} is available or the
++     * array type does not match the itemType
++     * @since 1.4 
++     */
++    public void addImplicitArray(Class ownerType, String fieldName, Class itemType) {
++        addImplicitCollection(ownerType, fieldName, itemType);
++    }
++
++    /**
++     * Adds an implicit array which is used for all items of the given element name defined by
++     * itemName.
++     * 
++     * @param ownerType class owning the implicit array
++     * @param fieldName name of the array field in the ownerType
++     * @param itemName alias name of the items
++     * @throws InitializationException if no {@link ImplicitCollectionMapper} is available
++     * @since 1.4 
++     */
++    public void addImplicitArray(Class ownerType, String fieldName, String itemName) {
++        addImplicitCollection(ownerType, fieldName, itemName, null);
++    }
++
++    /**
++     * Adds an implicit map.
++     * 
++     * @param ownerType class owning the implicit map
++     * @param fieldName name of the field in the ownerType. This field must be a concrete
++     *            map type or matching the default implementation type of the map
++     *            type.
++     * @param itemType type of the items to be part of this map as value
++     * @param keyFieldName the name of the filed of the itemType that is used for the key in the map
++     * @since 1.4 
++     */
++    public void addImplicitMap(Class ownerType, String fieldName, Class itemType, String keyFieldName) {
++        addImplicitMap(ownerType, fieldName, null, itemType, keyFieldName);
++    }
++
++    /**
++     * Adds an implicit map.
++     * 
++     * @param ownerType class owning the implicit map
++     * @param fieldName name of the field in the ownerType. This field must be a concrete
++     *            map type or matching the default implementation type of the map
++     *            type.
++     * @param itemType type of the items to be part of this map as value
++     * @param keyFieldName the name of the filed of the itemType that is used for the key in the map
++     * @since 1.4 
++     */
++    public void addImplicitMap(Class ownerType, String fieldName, String itemFieldName, 
++        Class itemType, String keyFieldName) {
++        if (implicitCollectionMapper == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + ImplicitCollectionMapper.class.getName()
++                + " available");
++        }
++        implicitCollectionMapper.add(ownerType, fieldName, itemFieldName, itemType, keyFieldName);
++    }
++
++    /**
++     * Create a DataHolder that can be used to pass data to the converters. The DataHolder is
++     * provided with a call to {@link #marshal(Object, HierarchicalStreamWriter, DataHolder)} or
++     * {@link #unmarshal(HierarchicalStreamReader, Object, DataHolder)}.
++     * 
++     * @return a new {@link DataHolder}
++     */
++    public DataHolder newDataHolder() {
++        return new MapBackedDataHolder();
++    }
++
++    /**
++     * Creates an ObjectOutputStream that serializes a stream of objects to the writer using
++     * XStream.
++     * <p>
++     * To change the name of the root element (from <object-stream>), use
++     * {@link #createObjectOutputStream(java.io.Writer, String)}.
++     * </p>
++     * 
++     * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter,
++     *      String)
++     * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader)
++     * @since 1.0.3
++     */
++    public ObjectOutputStream createObjectOutputStream(Writer writer) throws IOException {
++        return createObjectOutputStream(
++            hierarchicalStreamDriver.createWriter(writer), "object-stream");
++    }
++
++    /**
++     * Creates an ObjectOutputStream that serializes a stream of objects to the writer using
++     * XStream.
++     * <p>
++     * To change the name of the root element (from <object-stream>), use
++     * {@link #createObjectOutputStream(java.io.Writer, String)}.
++     * </p>
++     * 
++     * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter,
++     *      String)
++     * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader)
++     * @since 1.0.3
++     */
++    public ObjectOutputStream createObjectOutputStream(HierarchicalStreamWriter writer)
++        throws IOException {
++        return createObjectOutputStream(writer, "object-stream");
++    }
++
++    /**
++     * Creates an ObjectOutputStream that serializes a stream of objects to the writer using
++     * XStream.
++     * 
++     * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter,
++     *      String)
++     * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader)
++     * @since 1.0.3
++     */
++    public ObjectOutputStream createObjectOutputStream(Writer writer, String rootNodeName)
++        throws IOException {
++        return createObjectOutputStream(
++            hierarchicalStreamDriver.createWriter(writer), rootNodeName);
++    }
++
++    /**
++     * Creates an ObjectOutputStream that serializes a stream of objects to the OutputStream
++     * using XStream.
++     * <p>
++     * To change the name of the root element (from <object-stream>), use
++     * {@link #createObjectOutputStream(java.io.Writer, String)}.
++     * </p>
++     * 
++     * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter,
++     *      String)
++     * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader)
++     * @since 1.3
++     */
++    public ObjectOutputStream createObjectOutputStream(OutputStream out) throws IOException {
++        return createObjectOutputStream(
++            hierarchicalStreamDriver.createWriter(out), "object-stream");
++    }
++
++    /**
++     * Creates an ObjectOutputStream that serializes a stream of objects to the OutputStream
++     * using XStream.
++     * 
++     * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter,
++     *      String)
++     * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader)
++     * @since 1.3
++     */
++    public ObjectOutputStream createObjectOutputStream(OutputStream out, String rootNodeName)
++        throws IOException {
++        return createObjectOutputStream(
++            hierarchicalStreamDriver.createWriter(out), rootNodeName);
++    }
++
++    /**
++     * Creates an ObjectOutputStream that serializes a stream of objects to the writer using
++     * XStream.
++     * <p>
++     * Because an ObjectOutputStream can contain multiple items and XML only allows a single
++     * root node, the stream must be written inside an enclosing node.
++     * </p>
++     * <p>
++     * It is necessary to call ObjectOutputStream.close() when done, otherwise the stream will
++     * be incomplete.
++     * </p>
++     * <h3>Example</h3>
++     * 
++     * <pre>
++     *  ObjectOutputStream out = xstream.createObjectOutputStream(aWriter, "things");
++     *   out.writeInt(123);
++     *   out.writeObject("Hello");
++     *   out.writeObject(someObject)
++     *   out.close();
++     * </pre>
++     * 
++     * @param writer The writer to serialize the objects to.
++     * @param rootNodeName The name of the root node enclosing the stream of objects.
++     * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader)
++     * @since 1.0.3
++     */
++    public ObjectOutputStream createObjectOutputStream(final HierarchicalStreamWriter writer,
++        String rootNodeName) throws IOException {
++        final StatefulWriter statefulWriter = new StatefulWriter(writer);
++        statefulWriter.startNode(rootNodeName, null);
++        return new CustomObjectOutputStream(new CustomObjectOutputStream.StreamCallback() {
++            public void writeToStream(Object object) {
++                marshal(object, statefulWriter);
++            }
++
++            public void writeFieldsToStream(Map fields) throws NotActiveException {
++                throw new NotActiveException("not in call to writeObject");
++            }
++
++            public void defaultWriteObject() throws NotActiveException {
++                throw new NotActiveException("not in call to writeObject");
++            }
++
++            public void flush() {
++                statefulWriter.flush();
++            }
++
++            public void close() {
++                if (statefulWriter.state() != StatefulWriter.STATE_CLOSED) {
++                    statefulWriter.endNode();
++                    statefulWriter.close();
++                }
++            }
++        });
++    }
++
++    /**
++     * Creates an ObjectInputStream that deserializes a stream of objects from a reader using
++     * XStream.
++     * 
++     * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader)
++     * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter,
++     *      String)
++     * @since 1.0.3
++     */
++    public ObjectInputStream createObjectInputStream(Reader xmlReader) throws IOException {
++        return createObjectInputStream(hierarchicalStreamDriver.createReader(xmlReader));
++    }
++
++    /**
++     * Creates an ObjectInputStream that deserializes a stream of objects from an InputStream
++     * using XStream.
++     * 
++     * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader)
++     * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter,
++     *      String)
++     * @since 1.3
++     */
++    public ObjectInputStream createObjectInputStream(InputStream in) throws IOException {
++        return createObjectInputStream(hierarchicalStreamDriver.createReader(in));
++    }
++
++    /**
++     * Creates an ObjectInputStream that deserializes a stream of objects from a reader using
++     * XStream. <h3>Example</h3>
++     * 
++     * <pre>
++     * ObjectInputStream in = xstream.createObjectOutputStream(aReader);
++     * int a = out.readInt();
++     * Object b = out.readObject();
++     * Object c = out.readObject();
++     * </pre>
++     * 
++     * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter,
++     *      String)
++     * @since 1.0.3
++     */
++    public ObjectInputStream createObjectInputStream(final HierarchicalStreamReader reader)
++        throws IOException {
++        return new CustomObjectInputStream(new CustomObjectInputStream.StreamCallback() {
++            public Object readFromStream() throws EOFException {
++                if (!reader.hasMoreChildren()) {
++                    throw new EOFException();
++                }
++                reader.moveDown();
++                Object result = unmarshal(reader);
++                reader.moveUp();
++                return result;
++            }
++
++            public Map readFieldsFromStream() throws IOException {
++                throw new NotActiveException("not in call to readObject");
++            }
++
++            public void defaultReadObject() throws NotActiveException {
++                throw new NotActiveException("not in call to readObject");
++            }
++
++            public void registerValidation(ObjectInputValidation validation, int priority)
++                throws NotActiveException {
++                throw new NotActiveException("stream inactive");
++            }
++
++            public void close() {
++                reader.close();
++            }
++        }, classLoaderReference);
++    }
++
++    /**
++     * Change the ClassLoader XStream uses to load classes. Creating an XStream instance it will
++     * register for all kind of classes and types of the current JDK, but not for any 3rd party
++     * type. To ensure that all other types are loaded with your class loader, you should call
++     * this method as early as possible - or consider to provide the class loader directly in
++     * the constructor.
++     * 
++     * @since 1.1.1
++     */
++    public void setClassLoader(ClassLoader classLoader) {
++        classLoaderReference.setReference(classLoader);
++    }
++
++    /**
++     * Retrieve the ClassLoader XStream uses to load classes.
++     * 
++     * @since 1.1.1
++     */
++    public ClassLoader getClassLoader() {
++        return classLoaderReference.getReference();
++    }
++
++    /**
++     * Add pattern for unknown element names to ignore.
++     *
++     * @param pattern the name pattern as regular expression
++     * @since 1.4.5
++     */
++    private void ignoreUnknownElements(Pattern pattern) {
++        if (fieldAliasingMapper == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + FieldAliasingMapper.class.getName()
++                + " available");
++        }
++        fieldAliasingMapper.addFieldsToIgnore(pattern);
++    }
++
++    /**
++     * Process the annotations of the given types and configure the XStream.
++     * 
++     * @param types the types with XStream annotations
++     * @since 1.3
++     */
++    public void processAnnotations(final Class[] types) {
++        if (annotationConfiguration == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + ANNOTATION_MAPPER_TYPE
++                + " available");
++        }
++        annotationConfiguration.processAnnotations(types);
++    }
++
++    /**
++     * Process the annotations of the given type and configure the XStream. A call of this
++     * method will automatically turn the auto-detection mode for annotations off.
++     * 
++     * @param type the type with XStream annotations
++     * @since 1.3
++     */
++    public void processAnnotations(final Class type) {
++        processAnnotations(new Class[]{type});
++    }
++
++    /**
++     * Set the auto-detection mode of the AnnotationMapper. Note that auto-detection implies
++     * that the XStream is configured while it is processing the XML steams. This is a potential
++     * concurrency problem. Also is it technically not possible to detect all class aliases at
++     * deserialization. You have been warned!
++     * 
++     * @param mode <code>true</code> if annotations are auto-detected
++     * @since 1.3
++     */
++    public void autodetectAnnotations(boolean mode) {
++        if (annotationConfiguration != null) {
++            annotationConfiguration.autodetectAnnotations(mode);
++        }
++    }
++
++    /**
++     * Add a new security permission.
++     * 
++     * <p>
++     * Permissions are evaluated in the added sequence. An instance of {@link NoTypePermission} or
++     * {@link AnyTypePermission} will implicitly wipe any existing permission.
++     * </p>
++     * 
++     * @param permission the permission to add
++     * @since 1.4.7
++     */
++    public void addPermission(TypePermission permission) {
++        if (securityMapper != null) {
++            securityMapper.addPermission(permission);
++        }
++    }
++
++     public void allowTypesByWildcard(String[] patterns) {
++                 addPermission(new WildcardTypePermission(patterns));
++     }
++
++    /**
++     * Add security permission for explicit types by name.
++     * 
++     * @param names the type names to allow
++     * @since 1.4.7
++     */
++    public void allowTypes(String[] names) {
++        addPermission(new ExplicitTypePermission(names));
++    }
++
++    /**
++     * Add security permission for explicit types.
++     *
++     * @param types the types to allow
++     * @since 1.4.7
++     */
++    public void allowTypes(Class[] types) {
++        addPermission(new ExplicitTypePermission(types));
++    }
++    /**
++     * Prevents a field from being serialized. To omit a field you must always provide the
++     * declaring type and not necessarily the type that is converted.
++     *
++     * @since 1.1.3
++     * @throws InitializationException if no {@link FieldAliasingMapper} is available
++     */
++    public void omitField(Class definedIn, String fieldName) {
++        if (fieldAliasingMapper == null) {
++            throw new com.thoughtworks.xstream.InitializationException("No "
++                + FieldAliasingMapper.class.getName()
++                + " available");
++        }
++        fieldAliasingMapper.omitField(definedIn, fieldName);
++    }
++
++    /**
++     * Add security permission for a type hierarchy.
++     *
++     * @param type the base type to allow
++     * @since 1.4.7
++     */
++    public void allowTypeHierarchy(Class type) {
++        addPermission(new TypeHierarchyPermission(type));
++    }
++     /**
++     * Ignore all unknown elements.
++     *
++     * @since 1.4.5
++     */
++    public void ignoreUnknownElements() {
++        ignoreUnknownElements(IGNORE_ALL);
++    }
++
++    /**
++     * @deprecated As of 1.3, use {@link InitializationException} instead
++     */
++    public static class InitializationException extends XStreamException {
++        /**
++         * @deprecated As of 1.3, use {@link InitializationException} instead
++         */
++        public InitializationException(String message, Throwable cause) {
++            super(message, cause);
++        }
++
++        /**
++         * @deprecated As of 1.3, use {@link InitializationException} instead
++         */
++        public InitializationException(String message) {
++            super(message);
++        }
++    }
++
++    private Object readResolve() {
++        jvm = new JVM();
++        return this;
++    }
++
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java b/activemq-core/src/main/java/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java
+new file mode 100644
+index 0000000..7e627c2
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java
+@@ -0,0 +1,99 @@
++/*
++ * Copyright (C) 2005 Joe Walnes.
++ * Copyright (C) 2006, 2007, 2008, 2009, 2013, 2014 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 09. April 2005 by Joe Walnes
++ */
++package com.thoughtworks.xstream.mapper;
++
++import com.thoughtworks.xstream.core.util.FastField;
++
++import java.util.HashMap;
++import java.util.HashSet;
++import java.util.Iterator;
++import java.util.LinkedHashSet;
++import java.util.Map;
++import java.util.Set;
++import java.util.regex.Pattern;
++
++/**
++ * Mapper that allows a field of a specific class to be replaced with a shorter alias, or omitted
++ * entirely.
++ *
++ * @author Joe Walnes
++ */
++public class FieldAliasingMapper extends MapperWrapper {
++
++    protected final Map fieldToAliasMap = new HashMap();
++    protected final Map aliasToFieldMap = new HashMap();
++    protected final Set fieldsToOmit = new HashSet();
++    protected final Set unknownFieldsToIgnore = new LinkedHashSet();
++
++    public FieldAliasingMapper(Mapper wrapped) {
++        super(wrapped);
++    }
++
++    public void addFieldAlias(String alias, Class type, String fieldName) {
++        fieldToAliasMap.put(key(type, fieldName), alias);
++        aliasToFieldMap.put(key(type, alias), fieldName);
++    }
++    
++    public void addFieldsToIgnore(final Pattern pattern) {
++        unknownFieldsToIgnore.add(pattern);
++    }
++
++    private Object key(Class type, String name) {
++        return new FastField(type, name);
++    }
++
++    public String serializedMember(Class type, String memberName) {
++        String alias = getMember(type, memberName, fieldToAliasMap);
++        if (alias == null) {
++            return super.serializedMember(type, memberName);
++        } else {
++            return alias;
++        }
++    }
++
++    public String realMember(Class type, String serialized) {
++        String real = getMember(type, serialized, aliasToFieldMap);
++        if (real == null) {
++            return super.realMember(type, serialized);
++        } else {
++            return real;
++        }
++    }
++
++    private String getMember(Class type, String name, Map map) {
++        String member = null;
++        for (Class declaringType = type; 
++                member == null && declaringType != Object.class && declaringType != null; 
++                declaringType = declaringType.getSuperclass()) {
++            member = (String) map.get(key(declaringType, name));
++        }
++        return member;
++    }
++
++    public boolean shouldSerializeMember(Class definedIn, String fieldName) {
++        if (fieldsToOmit.contains(key(definedIn, fieldName))) {
++            return false;
++        } else if (definedIn == Object.class && !unknownFieldsToIgnore.isEmpty()) {
++            for(Iterator iter = unknownFieldsToIgnore.iterator(); iter.hasNext();) {
++                Pattern pattern = (Pattern)iter.next();
++                if (pattern.matcher(fieldName).matches()) {
++                    return false;
++                }
++            }
++        }
++        return true;
++    }
++
++    public void omitField(Class definedIn, String fieldName) {
++        fieldsToOmit.add(key(definedIn, fieldName));
++    }
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/mapper/SecurityMapper.java b/activemq-core/src/main/java/com/thoughtworks/xstream/mapper/SecurityMapper.java
+new file mode 100644
+index 0000000..d650c92
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/mapper/SecurityMapper.java
+@@ -0,0 +1,79 @@
++/*
++ * Copyright (C) 2014 XStream Committers.
++ * All rights reserved.
++ *
++ * Created on 08. January 2014 by Joerg Schaible
++ */
++package com.thoughtworks.xstream.mapper;
++
++import java.util.ArrayList;
++import java.util.Arrays;
++import java.util.List;
++
++import com.thoughtworks.xstream.security.AnyTypePermission;
++import com.thoughtworks.xstream.security.ForbiddenClassException;
++import com.thoughtworks.xstream.security.NoTypePermission;
++import com.thoughtworks.xstream.security.TypePermission;
++
++
++/**
++ * A Mapper implementation injecting a security layer based on permission rules for any type required in the
++ * unmarshalling process.
++ * 
++ * @author Jörg Schaible
++ * @since 1.4.7
++ */
++public class SecurityMapper extends MapperWrapper {
++
++    private final List permissions;
++
++    /**
++     * Construct a SecurityMapper.
++     * 
++     * @param wrapped the mapper chain
++     * @since 1.4.7
++     */
++    public SecurityMapper(final Mapper wrapped) {
++        this(wrapped, (TypePermission[])null);
++    }
++
++    /**
++     * Construct a SecurityMapper.
++     * 
++     * @param wrapped the mapper chain
++     * @param permissions the predefined permissions
++     * @since 1.4.7
++     */
++    public SecurityMapper(final Mapper wrapped, final TypePermission[] permissions) {
++        super(wrapped);
++        this.permissions = permissions == null //
++            ? new ArrayList()
++            : new ArrayList(Arrays.asList(permissions));
++    }
++
++    /**
++     * Add a new permission.
++     * <p>
++     * Permissions are evaluated in the added sequence. An instance of {@link NoTypePermission} or
++     * {@link AnyTypePermission} will implicitly wipe any existing permission.
++     * </p>
++     * 
++     * @param permission the permission to add.
++     * @since 1.4.7
++     */
++    public void addPermission(final TypePermission permission) {
++        if (permission.equals(NoTypePermission.NONE) || permission.equals(AnyTypePermission.ANY))
++            permissions.clear();
++        permissions.add(0, permission);
++    }
++
++    public Class realClass(final String elementName) {
++        final Class type = super.realClass(elementName);
++        for (int i = 0; i < permissions.size(); ++i) {
++            final TypePermission permission = (TypePermission)permissions.get(i);
++            if (permission.allows(type))
++                return type;
++        }
++        throw new ForbiddenClassException(type);
++    }
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/security/AnyTypePermission.java b/activemq-core/src/main/java/com/thoughtworks/xstream/security/AnyTypePermission.java
+new file mode 100644
+index 0000000..d1524a9
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/security/AnyTypePermission.java
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (C) 2014 XStream Committers.
++ * All rights reserved.
++ *
++ * Created on 08. January 2014 by Joerg Schaible
++ */
++package com.thoughtworks.xstream.security;
++
++/**
++ * Permission for any type and <code>null</code>.
++ * 
++ * @author Jörg Schaible
++ * @since 1.4.7
++ */
++public class AnyTypePermission implements TypePermission {
++    /**
++     * @since 1.4.7
++     */
++    public static final TypePermission ANY = new AnyTypePermission();
++
++    public boolean allows(Class type) {
++        return true;
++    }
++
++    public int hashCode() {
++        return 3;
++    }
++
++    public boolean equals(Object obj) {
++        return obj != null && obj.getClass() == AnyTypePermission.class;
++    }
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/security/ArrayTypePermission.java b/activemq-core/src/main/java/com/thoughtworks/xstream/security/ArrayTypePermission.java
+new file mode 100644
+index 0000000..1e856ec
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/security/ArrayTypePermission.java
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (C) 2014 XStream Committers.
++ * All rights reserved.
++ *
++ * Created on 09. January 2014 by Joerg Schaible
++ */
++package com.thoughtworks.xstream.security;
++
++/**
++ * Permission for any array type.
++ * 
++ * @author Jörg Schaible
++ * @since 1.4.7
++ */
++public class ArrayTypePermission implements TypePermission {
++    /**
++     * @since 1.4.7
++     */
++    public static final TypePermission ARRAYS = new ArrayTypePermission();
++
++    public boolean allows(Class type) {
++        return type != null && type.isArray();
++    }
++
++    public int hashCode() {
++        return 13;
++    }
++
++    public boolean equals(Object obj) {
++        return obj != null && obj.getClass() == ArrayTypePermission.class;
++    }
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/security/ExplicitTypePermission.java b/activemq-core/src/main/java/com/thoughtworks/xstream/security/ExplicitTypePermission.java
+new file mode 100644
+index 0000000..196380b
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/security/ExplicitTypePermission.java
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (C) 2014 XStream Committers.
++ * All rights reserved.
++ *
++ * Created on 09. January 2014 by Joerg Schaible
++ */
++package com.thoughtworks.xstream.security;
++
++import java.util.Arrays;
++import java.util.Collections;
++import java.util.HashSet;
++import java.util.Set;
++
++
++/**
++ * Explicit permission for a type with a name matching one in the provided list.
++ * 
++ * @author Jörg Schaible
++ * @since 1.4.7
++ */
++public class ExplicitTypePermission implements TypePermission {
++
++    final Set names;
++
++    /**
++     * @since 1.4.7
++     */
++    public ExplicitTypePermission(final Class[] types) {
++        this(new Object() {
++            public String[] getNames() {
++                if (types == null)
++                    return null;
++                String[] names = new String[types.length];
++                for (int i = 0; i < types.length; ++i)
++                    names[i] = types[i].getName();
++                return names;
++            }
++        }.getNames());
++    }
++
++    /**
++     * @since 1.4.7
++     */
++    public ExplicitTypePermission(String[] names) {
++        this.names = names == null ? Collections.EMPTY_SET : new HashSet(Arrays.asList(names));
++    }
++
++    public boolean allows(Class type) {
++        if (type == null)
++            return false;
++        return names.contains(type.getName());
++    }
++
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/security/ForbiddenClassException.java b/activemq-core/src/main/java/com/thoughtworks/xstream/security/ForbiddenClassException.java
+new file mode 100644
+index 0000000..017fc30
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/security/ForbiddenClassException.java
+@@ -0,0 +1,27 @@
++/*
++ * Copyright (C) 2014 XStream Committers.
++ * All rights reserved.
++ *
++ * Created on 08. January 2014 by Joerg Schaible
++ */
++package com.thoughtworks.xstream.security;
++
++import com.thoughtworks.xstream.XStreamException;
++
++/**
++ * Exception thrown for a forbidden class.
++ * 
++ * @author Jörg Schaible
++ * @since 1.4.7
++ */
++public class ForbiddenClassException extends XStreamException {
++
++    /**
++     * Construct a ForbiddenClassException.
++     * @param type the forbidden class
++     * @since 1.4.7
++     */
++    public ForbiddenClassException(Class type) {
++        super(type == null ? "null" : type.getName());
++    }
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/security/InterfaceTypePermission.java b/activemq-core/src/main/java/com/thoughtworks/xstream/security/InterfaceTypePermission.java
+new file mode 100644
+index 0000000..c5b8002
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/security/InterfaceTypePermission.java
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (C) 2014 XStream Committers.
++ * All rights reserved.
++ *
++ * Created on 27. January 2014 by Joerg Schaible
++ */
++package com.thoughtworks.xstream.security;
++
++/**
++ * Permission for any interface type.
++ * 
++ * @author Jörg Schaible
++ * @since 1.4.7
++ */
++public class InterfaceTypePermission implements TypePermission {
++    /**
++     * @since 1.4.7
++     */
++    public static final TypePermission INTERFACES = new InterfaceTypePermission();
++
++    public boolean allows(Class type) {
++        return type != null && type.isInterface();
++    }
++
++    public int hashCode() {
++        return 31;
++    }
++
++    public boolean equals(Object obj) {
++        return obj != null && obj.getClass() == InterfaceTypePermission.class;
++    }
++
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/security/NoPermission.java b/activemq-core/src/main/java/com/thoughtworks/xstream/security/NoPermission.java
+new file mode 100644
+index 0000000..17115b0
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/security/NoPermission.java
+@@ -0,0 +1,39 @@
++/*
++ * Copyright (C) 2014 XStream Committers.
++ * All rights reserved.
++ *
++ * Created on 09. January 2014 by Joerg Schaible
++ */
++package com.thoughtworks.xstream.security;
++
++/**
++ * Wrapper to negate another type permission.
++ * <p>
++ * If the wrapped {@link TypePermission} allows the type, this instance will throw a {@link ForbiddenClassException}
++ * instead. An instance of this permission cannot be used to allow a type.
++ * </p>
++ * 
++ * @author Jörg Schaible
++ * @since 1.4.7
++ */
++public class NoPermission implements TypePermission {
++
++    private final TypePermission permission;
++
++    /**
++     * Construct a NoPermission.
++     * 
++     * @param permission the permission to negate or <code>null</code> to forbid any type
++     * @since 1.4.7
++     */
++    public NoPermission(final TypePermission permission) {
++        this.permission = permission;
++    }
++
++    public boolean allows(final Class type) {
++        if (permission == null || permission.allows(type)) {
++            throw new ForbiddenClassException(type);
++        }
++        return false;
++    }
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/security/NoTypePermission.java b/activemq-core/src/main/java/com/thoughtworks/xstream/security/NoTypePermission.java
+new file mode 100644
+index 0000000..802537b
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/security/NoTypePermission.java
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (C) 2014 XStream Committers.
++ * All rights reserved.
++ *
++ * Created on 08. January 2014 by Joerg Schaible
++ */
++package com.thoughtworks.xstream.security;
++
++/**
++ * No permission for any type.
++ * <p>
++ * Can be used to skip any existing default permission.
++ * </p>
++ * 
++ * @author Jörg Schaible
++ * @since 1.4.7
++ */
++public class NoTypePermission implements TypePermission {
++
++    /**
++     * @since 1.4.7
++     */
++    public static final TypePermission NONE = new NoTypePermission();
++
++    public boolean allows(Class type) {
++        throw new ForbiddenClassException(type);
++    }
++
++    public int hashCode() {
++        return 1;
++    }
++
++    public boolean equals(Object obj) {
++        return obj != null && obj.getClass() == NoTypePermission.class;
++    }
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/security/NullPermission.java b/activemq-core/src/main/java/com/thoughtworks/xstream/security/NullPermission.java
+new file mode 100644
+index 0000000..d241641
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/security/NullPermission.java
+@@ -0,0 +1,26 @@
++/*
++ * Copyright (C) 2014 XStream Committers.
++ * All rights reserved.
++ *
++ * Created on 09. January 2014 by Joerg Schaible
++ */
++package com.thoughtworks.xstream.security;
++
++import com.thoughtworks.xstream.mapper.Mapper;
++
++/**
++ * Permission for <code>null</code> or XStream's null replacement type.
++ * 
++ * @author Jörg Schaible
++ * @since 1.4.7
++ */
++public class NullPermission implements TypePermission {
++    /**
++     * @since 1.4.7
++     */
++    public static final TypePermission NULL = new NullPermission();
++
++    public boolean allows(Class type) {
++        return type == null || type == Mapper.Null.class;
++    }
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/security/PrimitiveTypePermission.java b/activemq-core/src/main/java/com/thoughtworks/xstream/security/PrimitiveTypePermission.java
+new file mode 100644
+index 0000000..fb69b95
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/security/PrimitiveTypePermission.java
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (C) 2014 XStream Committers.
++ * All rights reserved.
++ *
++ * Created on 09. January 2014 by Joerg Schaible
++ */
++package com.thoughtworks.xstream.security;
++
++import com.thoughtworks.xstream.core.util.Primitives;
++
++/**
++ * Permission for any primitive type and its boxed counterpart (incl. void).
++ * 
++ * @author Jörg Schaible
++ * @since 1.4.7
++ */
++public class PrimitiveTypePermission implements TypePermission {
++    /**
++     * @since 1.4.7
++     */
++    public static final TypePermission PRIMITIVES = new PrimitiveTypePermission();
++
++    public boolean allows(Class type) {
++        return type != null && type.isPrimitive() || Primitives.isBoxed(type);
++    }
++
++    public int hashCode() {
++        return 7;
++    }
++
++    public boolean equals(Object obj) {
++        return obj != null && obj.getClass() == PrimitiveTypePermission.class;
++    }
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/security/ProxyTypePermission.java b/activemq-core/src/main/java/com/thoughtworks/xstream/security/ProxyTypePermission.java
+new file mode 100644
+index 0000000..1f3d3be
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/security/ProxyTypePermission.java
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2014 XStream Committers.
++ * All rights reserved.
++ *
++ * Created on 19. January 2014 by Joerg Schaible
++ */
++package com.thoughtworks.xstream.security;
++
++import java.lang.reflect.Proxy;
++
++import com.thoughtworks.xstream.mapper.DynamicProxyMapper;
++
++
++/**
++ * Permission for any array type.
++ * 
++ * @author Jörg Schaible
++ * @since 1.4.7
++ */
++public class ProxyTypePermission implements TypePermission {
++    /**
++     * @since 1.4.7
++     */
++    public static final TypePermission PROXIES = new ProxyTypePermission();
++
++    public boolean allows(final Class type) {
++        return type != null && (Proxy.isProxyClass(type) || type == DynamicProxyMapper.DynamicProxy.class);
++    }
++
++    public int hashCode() {
++        return 17;
++    }
++
++    public boolean equals(final Object obj) {
++        return obj != null && obj.getClass() == ProxyTypePermission.class;
++    }
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/security/RegExpTypePermission.java b/activemq-core/src/main/java/com/thoughtworks/xstream/security/RegExpTypePermission.java
+new file mode 100644
+index 0000000..31ddbd6
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/security/RegExpTypePermission.java
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (C) 2014 XStream Committers.
++ * All rights reserved.
++ *
++ * Created on 09. January 2014 by Joerg Schaible
++ */
++package com.thoughtworks.xstream.security;
++
++import java.util.regex.Pattern;
++
++
++/**
++ * Permission for any type with a name matching one of the provided regular expressions.
++ * 
++ * @author Jörg Schaible
++ * @since 1.4.7
++ */
++public class RegExpTypePermission implements TypePermission {
++
++    private final Pattern[] patterns;
++
++    public RegExpTypePermission(final String[] patterns) {
++        this(getPatterns(patterns));
++    }
++
++    public RegExpTypePermission(final Pattern[] patterns) {
++        this.patterns = patterns == null ? new Pattern[0] : patterns;
++    }
++
++    public boolean allows(final Class type) {
++        if (type != null) {
++            final String name = type.getName();
++            for (int i = 0; i < patterns.length; ++i)
++                if (patterns[i].matcher(name).matches())
++                    return true;
++        }
++        return false;
++    }
++
++    private static Pattern[] getPatterns(final String[] patterns) {
++        if (patterns == null)
++            return null;
++        final Pattern[] array = new Pattern[patterns.length];
++        for (int i = 0; i < array.length; ++i)
++            array[i] = Pattern.compile(patterns[i]);
++        return array;
++    }
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/security/TypeHierarchyPermission.java b/activemq-core/src/main/java/com/thoughtworks/xstream/security/TypeHierarchyPermission.java
+new file mode 100644
+index 0000000..d476ddf
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/security/TypeHierarchyPermission.java
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (C) 2014 XStream Committers.
++ * All rights reserved.
++ *
++ * Created on 23. January 2014 by Joerg Schaible
++ */
++package com.thoughtworks.xstream.security;
++
++/**
++ * Permission for a type hierarchy with a name matching one in the provided list.
++ * 
++ * @author Jörg Schaible
++ * @since 1.4.7
++ */
++public class TypeHierarchyPermission implements TypePermission {
++
++    private Class type;
++
++    /**
++     * @since 1.4.7
++     */
++    public TypeHierarchyPermission(Class type) {
++        this.type = type;
++    }
++
++    public boolean allows(Class type) {
++        if (type == null)
++            return false;
++        return this.type.isAssignableFrom(type);
++    }
++
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/security/TypePermission.java b/activemq-core/src/main/java/com/thoughtworks/xstream/security/TypePermission.java
+new file mode 100644
+index 0000000..03f02ec
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/security/TypePermission.java
+@@ -0,0 +1,25 @@
++/*
++ * Copyright (C) 2014 XStream Committers.
++ * All rights reserved.
++ *
++ * Created on 08. January 2014 by Joerg Schaible
++ */
++package com.thoughtworks.xstream.security;
++
++/**
++ * Definition of a type permission. 
++ * 
++ * @author Jörg Schaible
++ * @since 1.4.7
++ */
++public interface TypePermission {
++    /**
++     * Check permission for a provided type.
++     * 
++     * @param type the type to check
++     * @return <code>true</code> if provided type is allowed, <code>false</code> if permission does not handle the type
++     * @throws ForbiddenClassException if provided type is explicitly forbidden
++     * @since 1.4.7
++     */
++    boolean allows(Class type);
++}
+diff --git a/activemq-core/src/main/java/com/thoughtworks/xstream/security/WildcardTypePermission.java b/activemq-core/src/main/java/com/thoughtworks/xstream/security/WildcardTypePermission.java
+new file mode 100644
+index 0000000..9da8249
+--- /dev/null
++++ b/activemq-core/src/main/java/com/thoughtworks/xstream/security/WildcardTypePermission.java
+@@ -0,0 +1,84 @@
++/*
++ * Copyright (C) 2014 XStream Committers.
++ * All rights reserved.
++ *
++ * Created on 09. January 2014 by Joerg Schaible
++ */
++package com.thoughtworks.xstream.security;
++
++/**
++ * Permission for any type with a name matching one of the provided wildcard expressions.
++ * 
++ * <p>
++ * Supported are patterns with path expressions using dot as separator:
++ * </p>
++ * <ul>
++ * <li>?: one non-control character except separator, e.g. for 'java.net.Inet?Address'</li>
++ * <li>*: arbitrary number of non-control characters except separator, e.g. for types in a package like 'java.lang.*'</li>
++ * <li>**: arbitrary number of non-control characters including separator, e.g. for types in a package and subpackages like 'java.lang.**'</li>
++ * </ul>
++ * <p>
++ * The complete range of UTF-8 characters is supported except control characters.
++ * </p>
++ * 
++ * @author Jörg Schaible
++ * @since 1.4.7
++ */
++public class WildcardTypePermission extends RegExpTypePermission {
++
++    /**
++     * @since 1.4.7
++     */
++    public WildcardTypePermission(final String[] patterns) {
++        super(getRegExpPatterns(patterns));
++    }
++
++    private static String[] getRegExpPatterns(final String[] wildcards) {
++        if (wildcards == null)
++            return null;
++        final String[] regexps = new String[wildcards.length];
++        for (int i = 0; i < wildcards.length; ++i) {
++            final String wildcardExpression = wildcards[i];
++            final StringBuffer result = new StringBuffer(wildcardExpression.length() * 2);
++            result.append("(?u)");
++            final int length = wildcardExpression.length();
++            for (int j = 0; j < length; j++) {
++                final char ch = wildcardExpression.charAt(j);
++                switch (ch) {
++                case '\\':
++                case '.':
++                case '+':
++                case '|':
++                case '[':
++                case ']':
++                case '(':
++                case ')':
++                case '^':
++                case '$':
++                    result.append('\\').append(ch);
++                    break;
++
++                case '?':
++                    result.append('.');
++                    break;
++
++                case '*':
++                    // see "General Category Property" in http://www.unicode.org/reports/tr18/
++                    if (j + 1 < length && wildcardExpression.charAt(j + 1) == '*') {
++                        result.append("[\\P{C}]*");
++                        j++;
++                    } else {
++                        result.append("[\\P{C}&&[^").append('.').append("]]*");
++                    }
++                    break;
++
++                default:
++                    result.append(ch);
++                    break;
++                }
++            }
++            regexps[i] = result.toString();
++        }
++        return regexps;
++    }
++}
+diff --git a/activemq-core/src/main/java/org/apache/activemq/transport/stomp/JmsFrameTranslator.java b/activemq-core/src/main/java/org/apache/activemq/transport/stomp/JmsFrameTranslator.java
+index 5274b34..4fd18b0 100644
+--- a/activemq-core/src/main/java/org/apache/activemq/transport/stomp/JmsFrameTranslator.java
++++ b/activemq-core/src/main/java/org/apache/activemq/transport/stomp/JmsFrameTranslator.java
+@@ -84,7 +84,7 @@ public class JmsFrameTranslator extends LegacyFrameTranslator implements
+                     msg = createMapMessage(in);
+                     break;
+                 default:
+-                    throw new Exception("Unkown transformation: " + transformation);
++                    throw new Exception("Unknown transformation: " + transformation);
+                 }
+             } catch (Throwable e) {
+                 command.getHeaders().put(Stomp.Headers.TRANSFORMATION_ERROR, e.getMessage());
+@@ -243,7 +243,8 @@ public class JmsFrameTranslator extends LegacyFrameTranslator implements
+         }
+ 
+         if (xstream == null) {
+-            xstream = new XStream();
++            xstream = XStreamSupport.createXStream();
++            xstream.ignoreUnknownElements();
+         }
+         return xstream;
+ 
+diff --git a/activemq-core/src/main/java/org/apache/activemq/transport/stomp/XStreamSupport.java b/activemq-core/src/main/java/org/apache/activemq/transport/stomp/XStreamSupport.java
+new file mode 100644
+index 0000000..abcca72
+--- /dev/null
++++ b/activemq-core/src/main/java/org/apache/activemq/transport/stomp/XStreamSupport.java
+@@ -0,0 +1,47 @@
++/**
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements.  See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache License, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License.  You may obtain a copy of the License at
++ *
++ *      http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++package org.apache.activemq.transport.stomp;
++
++import com.thoughtworks.xstream.XStream;
++import com.thoughtworks.xstream.security.AnyTypePermission;
++import com.thoughtworks.xstream.security.NoTypePermission;
++import com.thoughtworks.xstream.security.PrimitiveTypePermission;
++import org.apache.activemq.util.ClassLoadingAwareObjectInputStream;
++
++import java.util.Collection;
++import java.util.Map;
++
++public class XStreamSupport {
++
++    public static XStream createXStream() {
++        XStream stream = new XStream();
++        stream.addPermission(NoTypePermission.NONE);
++        stream.addPermission(PrimitiveTypePermission.PRIMITIVES);
++        stream.allowTypeHierarchy(Collection.class);
++        stream.allowTypeHierarchy(Map.class);
++        stream.allowTypes(new Class[]{String.class});
++        if (ClassLoadingAwareObjectInputStream.isAllAllowed()) {
++            stream.addPermission(AnyTypePermission.ANY);
++        } else {
++            for (String packageName : ClassLoadingAwareObjectInputStream.serializablePackages) {
++                stream.allowTypesByWildcard(new String[]{packageName + ".**"});
++            }
++        }
++        return stream;
++    }
++
++}
+diff --git a/activemq-core/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java b/activemq-core/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java
+index 82da30c..6a2864f 100644
+--- a/activemq-core/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java
++++ b/activemq-core/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java
+@@ -21,7 +21,10 @@ import java.io.InputStream;
+ import java.io.ObjectInputStream;
+ import java.io.ObjectStreamClass;
+ import java.lang.reflect.Proxy;
++import java.util.Arrays;
++import java.util.Collection;
+ import java.util.HashMap;
++import java.util.Map;
+ 
+ @SuppressWarnings("rawtypes")
+ public class ClassLoadingAwareObjectInputStream extends ObjectInputStream {
+@@ -29,6 +32,12 @@ public class ClassLoadingAwareObjectInputStream extends ObjectInputStream {
+     private static final ClassLoader FALLBACK_CLASS_LOADER =
+         ClassLoadingAwareObjectInputStream.class.getClassLoader();
+ 
++    public static final String[] serializablePackages;
++
++    static {
++        serializablePackages = System.getProperty("org.apache.activemq.SERIALIZABLE_PACKAGES", "java.lang,java.util,org.apache.activemq,org.fusesource.hawtbuf,com.thoughtworks.xstream.mapper").split(",");
++    }
++
+     /**
+      * Maps primitive type names to corresponding class objects.
+      */
+@@ -40,7 +49,9 @@ public class ClassLoadingAwareObjectInputStream extends ObjectInputStream {
+ 
+     protected Class<?> resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException {
+         ClassLoader cl = Thread.currentThread().getContextClassLoader();
+-        return load(classDesc.getName(), cl);
++        Class clazz = load(classDesc.getName(), cl);
++        checkSecurity(clazz);
++        return clazz;
+     }
+ 
+     protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
+@@ -50,18 +61,47 @@ public class ClassLoadingAwareObjectInputStream extends ObjectInputStream {
+             cinterfaces[i] = load(interfaces[i], cl);
+         }
+ 
++        Class clazz = null;
+         try {
+-            return Proxy.getProxyClass(cl, cinterfaces);
++            clazz = Proxy.getProxyClass(cl, cinterfaces);
+         } catch (IllegalArgumentException e) {
+             try {
+-                return Proxy.getProxyClass(FALLBACK_CLASS_LOADER, cinterfaces);
++                clazz = Proxy.getProxyClass(FALLBACK_CLASS_LOADER, cinterfaces);
+             } catch (IllegalArgumentException e1) {
+             }
+ 
+-            throw new ClassNotFoundException(null, e);
++        }
++
++        if (clazz != null) {
++            checkSecurity(clazz);
++            return clazz;
++        } else {
++            throw new ClassNotFoundException(null);
+         }
+     }
+ 
++    public static boolean isAllAllowed() {
++        return serializablePackages.length == 1 && serializablePackages[0].equals("*");
++    }
++
++    private void checkSecurity(Class clazz) throws ClassNotFoundException {
++        if (!clazz.isPrimitive()) {
++            if (clazz.getPackage() != null && !isAllAllowed()) {
++               boolean found = false;
++               for (String packageName : serializablePackages) {
++                   if (clazz.getPackage().getName().equals(packageName) || clazz.getPackage().getName().startsWith(packageName + ".")) {
++                       found = true;
++                       break;
++                   }
++               }
++
++               if (!found) {
++                   throw new ClassNotFoundException("Forbidden " + clazz + "! This class is not allowed to be serialized. Add package with 'org.apache.activemq.SERIALIZABLE_PACKAGES' system property.");
++               }
++            }
++         }
++     }
++
+     private Class<?> load(String className, ClassLoader cl) throws ClassNotFoundException {
+         try {
+             return Class.forName(className, false, cl);
+diff --git a/activemq-optional/src/main/java/org/apache/activemq/transport/xstream/XStreamWireFormat.java b/activemq-optional/src/main/java/org/apache/activemq/transport/xstream/XStreamWireFormat.java
+index 91ae036..1b83e2e 100755
+--- a/activemq-optional/src/main/java/org/apache/activemq/transport/xstream/XStreamWireFormat.java
++++ b/activemq-optional/src/main/java/org/apache/activemq/transport/xstream/XStreamWireFormat.java
+@@ -17,9 +17,15 @@
+ package org.apache.activemq.transport.xstream;
+ 
+ import com.thoughtworks.xstream.XStream;
++import com.thoughtworks.xstream.converters.Converter;
++import com.thoughtworks.xstream.converters.MarshallingContext;
++import com.thoughtworks.xstream.converters.UnmarshallingContext;
++import com.thoughtworks.xstream.io.HierarchicalStreamReader;
++import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+ import org.apache.activemq.command.Command;
+ import org.apache.activemq.command.MarshallAware;
+ import org.apache.activemq.command.MessageDispatch;
++import org.apache.activemq.transport.stomp.XStreamSupport;
+ import org.apache.activemq.transport.util.TextWireFormat;
+ import org.apache.activemq.wireformat.WireFormat;
+ 
+@@ -105,7 +111,28 @@ public class XStreamWireFormat extends TextWireFormat {
+     // Implementation methods
+     // -------------------------------------------------------------------------
+     protected XStream createXStream() {
+-        return new XStream();
++        final XStream xstream = XStreamSupport.createXStream();
++        xstream.ignoreUnknownElements();
++        xstream.registerConverter(new Converter() {
++            final Converter delegate = xstream.getConverterLookup().lookupConverterForType(ByteSequence.class);
++            @Override
++            public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
++                ByteSequence byteSequence = (ByteSequence)o;
++                byteSequence.compact();
++                delegate.marshal(byteSequence, hierarchicalStreamWriter, marshallingContext);
++            }
++
++            @Override
++            public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
++                return delegate.unmarshal(hierarchicalStreamReader, unmarshallingContext);
++            }
++
++            @Override
++            public boolean canConvert(Class aClass) {
++                return aClass == ByteSequence.class;
++            }
++        });
++        return xstream;
+     }
+ 
+ }
+diff --git a/activemq-web/src/main/java/org/apache/activemq/web/MessageQuery.java b/activemq-web/src/main/java/org/apache/activemq/web/MessageQuery.java
+index 1d0ec06..a6cbd51 100644
+--- a/activemq-web/src/main/java/org/apache/activemq/web/MessageQuery.java
++++ b/activemq-web/src/main/java/org/apache/activemq/web/MessageQuery.java
+@@ -80,9 +80,9 @@ public class MessageQuery extends QueueBrowseQuery {
+         if (message instanceof ObjectMessage) {
+             try {
+                 return ((ObjectMessage) message).getObject();
+-            } catch (JMSException e) {
++            } catch (Exception e) {
+                 //message could not be parsed, make the reason available
+-                return e;
++                return new String("Cannot display ObjectMessage body. Reason: " + e.getMessage());
+             }
+         }
+         if (message instanceof MapMessage) {
diff --git a/debian/patches/series b/debian/patches/series
index febce4e..87c90b0 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -10,3 +10,4 @@ exclude_leveldb.diff
 CVE-2014-3600.patch
 CVE-2014-3612.patch
 CVE-2014-3576.patch
+CVE-2015-5254.patch
diff --git a/debian/source/local-options b/debian/source/local-options
deleted file mode 100644
index 2ee6f0f..0000000
--- a/debian/source/local-options
+++ /dev/null
@@ -1 +0,0 @@
-abort-on-upstream-changes

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/activemq.git



More information about the pkg-java-commits mailing list