Index: src/java/com/thoughtworks/xstream/XStream.java =================================================================== --- src/java/com/thoughtworks/xstream/XStream.java (revision 871) +++ src/java/com/thoughtworks/xstream/XStream.java (working copy) @@ -1105,7 +1105,7 @@ public ObjectOutputStream createObjectOutputStream( final HierarchicalStreamWriter writer, String rootNodeName) throws IOException { final StatefulWriter statefulWriter = new StatefulWriter(writer); - statefulWriter.startNode(rootNodeName); + statefulWriter.startNode(rootNodeName, null); return new CustomObjectOutputStream(new CustomObjectOutputStream.StreamCallback() { public void writeToStream(Object object) { marshal(object, statefulWriter); Index: src/java/com/thoughtworks/xstream/io/xml/XppDomWriter.java =================================================================== --- src/java/com/thoughtworks/xstream/io/xml/XppDomWriter.java (revision 871) +++ src/java/com/thoughtworks/xstream/io/xml/XppDomWriter.java (working copy) @@ -34,6 +34,10 @@ elementStack.addLast(configuration); } + public void startNode(String name, Class clazz) { + startNode(name); + } + public void setValue(String text) { top().setValue(text); } Index: src/java/com/thoughtworks/xstream/io/xml/Dom4JWriter.java =================================================================== --- src/java/com/thoughtworks/xstream/io/xml/Dom4JWriter.java (revision 871) +++ src/java/com/thoughtworks/xstream/io/xml/Dom4JWriter.java (working copy) @@ -36,7 +36,7 @@ throw new StreamException(e); } } - + public void startNode(String name) { if (elementStack.size() > 0) { try { @@ -50,6 +50,10 @@ children = false; } + public void startNode(String name, Class clazz) { + startNode(name); + } + public void setValue(String text) { char[] value = text.toCharArray(); if (value.length > 0) { Index: src/java/com/thoughtworks/xstream/io/xml/DomWriter.java =================================================================== --- src/java/com/thoughtworks/xstream/io/xml/DomWriter.java (revision 871) +++ src/java/com/thoughtworks/xstream/io/xml/DomWriter.java (working copy) @@ -33,7 +33,7 @@ document = rootElement.getOwnerDocument(); current = rootElement; } - + public void startNode(String name) { final Element child = document.createElement(escapeXmlName(name)); if (current == null) { @@ -44,6 +44,10 @@ current = child; } + public void startNode(String name, Class clazz) { + startNode(name); + } + public void addAttribute(String name, String value) { current.setAttribute(escapeXmlName(name), value); } Index: src/java/com/thoughtworks/xstream/io/xml/JDomWriter.java =================================================================== --- src/java/com/thoughtworks/xstream/io/xml/JDomWriter.java (revision 871) +++ src/java/com/thoughtworks/xstream/io/xml/JDomWriter.java (working copy) @@ -54,6 +54,10 @@ elementStack.add(0, element); } + public void startNode(String name, Class clazz) { + startNode(name); + } + public void setValue(String text) { top().addContent(this.documentFactory.text(text)); } Index: src/java/com/thoughtworks/xstream/io/xml/SaxWriter.java =================================================================== --- src/java/com/thoughtworks/xstream/io/xml/SaxWriter.java (revision 871) +++ src/java/com/thoughtworks/xstream/io/xml/SaxWriter.java (working copy) @@ -576,6 +576,10 @@ } } + public void startNode(String name, Class clazz) { + startNode(name); + } + public void addAttribute(String name, String value) { if (this.startTagInProgress) { String escapedName = escapeXmlName(name); Index: src/java/com/thoughtworks/xstream/io/xml/XomWriter.java =================================================================== --- src/java/com/thoughtworks/xstream/io/xml/XomWriter.java (revision 871) +++ src/java/com/thoughtworks/xstream/io/xml/XomWriter.java (working copy) @@ -17,13 +17,17 @@ super(replacer); this.node = parentElement; } - + public void startNode(String name) { Element newNode = new Element(escapeXmlName(name)); node.appendChild(newNode); node = newNode; } + public void startNode(String name, Class clazz) { + startNode(name); + } + public void addAttribute(String name, String value) { node.addAttribute(new Attribute(escapeXmlName(name), value)); } Index: src/java/com/thoughtworks/xstream/io/xml/PrettyPrintWriter.java =================================================================== --- src/java/com/thoughtworks/xstream/io/xml/PrettyPrintWriter.java (revision 871) +++ src/java/com/thoughtworks/xstream/io/xml/PrettyPrintWriter.java (working copy) @@ -67,7 +67,6 @@ this(writer, new char[]{' ', ' '}); } - public void startNode(String name) { String escapedName = escapeXmlName(name); tagIsEmpty = false; @@ -81,6 +80,10 @@ tagIsEmpty = true; } + public void startNode(String name, Class clazz) { + startNode(name); + } + public void setValue(String text) { readyForNewLine = false; tagIsEmpty = false; Index: src/java/com/thoughtworks/xstream/io/xml/StaxWriter.java =================================================================== --- src/java/com/thoughtworks/xstream/io/xml/StaxWriter.java (revision 871) +++ src/java/com/thoughtworks/xstream/io/xml/StaxWriter.java (working copy) @@ -164,6 +164,11 @@ } } + public void startNode(String name, Class clazz) { + startNode(name); + } + + public HierarchicalStreamWriter underlyingWriter() { return this; } Index: src/java/com/thoughtworks/xstream/io/binary/BinaryStreamWriter.java =================================================================== --- src/java/com/thoughtworks/xstream/io/binary/BinaryStreamWriter.java (revision 871) +++ src/java/com/thoughtworks/xstream/io/binary/BinaryStreamWriter.java (working copy) @@ -23,6 +23,10 @@ write(new Token.StartNode(idRegistry.getId(name))); } + public void startNode(String name, Class clazz) { + startNode(name); + } + public void addAttribute(String name, String value) { write(new Token.Attribute(idRegistry.getId(name), value)); } Index: src/java/com/thoughtworks/xstream/io/StatefulWriter.java =================================================================== --- src/java/com/thoughtworks/xstream/io/StatefulWriter.java (revision 871) +++ src/java/com/thoughtworks/xstream/io/StatefulWriter.java (working copy) @@ -65,6 +65,16 @@ } public void startNode(final String name) { + startNodeCommon(); + super.startNode(name); + } + + public void startNode(final String name, final Class clazz) { + startNodeCommon(); + super.startNode(name, clazz); + } + + private void startNodeCommon() { checkClosed(); if (state == STATE_VALUE) { // legal XML, but not in XStream ... ? @@ -73,7 +83,6 @@ state = STATE_NODE_START; ++balance; attributes.push(new HashSet()); - super.startNode(name); } public void addAttribute(String name, String value) { Index: src/java/com/thoughtworks/xstream/io/HierarchicalStreamWriter.java =================================================================== --- src/java/com/thoughtworks/xstream/io/HierarchicalStreamWriter.java (revision 871) +++ src/java/com/thoughtworks/xstream/io/HierarchicalStreamWriter.java (working copy) @@ -7,6 +7,8 @@ void startNode(String name); + void startNode(String name, Class clazz); + void addAttribute(String name, String value); /** Index: src/java/com/thoughtworks/xstream/io/path/PathTrackingWriter.java =================================================================== --- src/java/com/thoughtworks/xstream/io/path/PathTrackingWriter.java (revision 871) +++ src/java/com/thoughtworks/xstream/io/path/PathTrackingWriter.java (working copy) @@ -22,9 +22,14 @@ public void startNode(String name) { pathTracker.pushElement(name); - super.startNode(name); + super.startNode(name); } + public void startNode(String name, Class clazz) { + pathTracker.pushElement(name); + super.startNode(name, clazz); + } + public void endNode() { super.endNode(); pathTracker.popElement(); Index: src/java/com/thoughtworks/xstream/io/WriterWrapper.java =================================================================== --- src/java/com/thoughtworks/xstream/io/WriterWrapper.java (revision 871) +++ src/java/com/thoughtworks/xstream/io/WriterWrapper.java (working copy) @@ -17,6 +17,10 @@ wrapped.startNode(name); } + public void startNode(String name, Class clazz) { + wrapped.startNode(name, clazz); + } + public void endNode() { wrapped.endNode(); } Index: src/java/com/thoughtworks/xstream/core/TreeMarshaller.java =================================================================== --- src/java/com/thoughtworks/xstream/core/TreeMarshaller.java (revision 871) +++ src/java/com/thoughtworks/xstream/core/TreeMarshaller.java (working copy) @@ -68,7 +68,7 @@ writer.startNode(mapper.serializedClass(null)); writer.endNode(); } else { - writer.startNode(mapper.serializedClass(item.getClass())); + writer.startNode(mapper.serializedClass(item.getClass()), item.getClass()); convertAnother(item); writer.endNode(); } Index: src/java/com/thoughtworks/xstream/converters/basic/NullConverter.java =================================================================== --- src/java/com/thoughtworks/xstream/converters/basic/NullConverter.java (revision 871) +++ src/java/com/thoughtworks/xstream/converters/basic/NullConverter.java (working copy) @@ -19,7 +19,7 @@ } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - writer.startNode("null"); + writer.startNode("null", null); writer.endNode(); } Index: src/java/com/thoughtworks/xstream/converters/reflection/ExternalizableConverter.java =================================================================== --- src/java/com/thoughtworks/xstream/converters/reflection/ExternalizableConverter.java (revision 871) +++ src/java/com/thoughtworks/xstream/converters/reflection/ExternalizableConverter.java (working copy) @@ -45,7 +45,7 @@ writer.startNode("null"); writer.endNode(); } else { - writer.startNode(mapper.serializedClass(object.getClass())); + writer.startNode(mapper.serializedClass(object.getClass()), object.getClass()); context.convertAnother(object); writer.endNode(); } Index: src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java =================================================================== --- src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java (revision 871) +++ src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java (working copy) @@ -87,7 +87,7 @@ if (!mapper.shouldSerializeMember(definedIn, aliasName)) { return; } - writer.startNode(mapper.serializedMember(definedIn, aliasName)); + writer.startNode(mapper.serializedMember(definedIn, aliasName), fieldType); Class actualType = newObj.getClass(); Index: src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java =================================================================== --- src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java (revision 871) +++ src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java (working copy) @@ -62,7 +62,7 @@ public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { Class type = source.getClass(); boolean hasFactory = Factory.class.isAssignableFrom(type); - writer.startNode("type"); + writer.startNode("type", type); context.convertAnother(type.getSuperclass()); writer.endNode(); writer.startNode("interfaces"); @@ -71,7 +71,7 @@ if (interfaces[i] == Factory.class) { continue; } - writer.startNode(mapper.serializedClass(interfaces[i].getClass())); + writer.startNode(mapper.serializedClass(interfaces[i].getClass()), interfaces[i].getClass()); context.convertAnother(interfaces[i]); writer.endNode(); } @@ -85,14 +85,14 @@ } boolean isInterceptor = MethodInterceptor.class.isAssignableFrom(callbacks[0].getClass()); - writer.startNode(mapper.serializedClass(callbacks[0].getClass())); + writer.startNode(mapper.serializedClass(callbacks[0].getClass()), callbacks[0].getClass()); context.convertAnother(callbacks[0]); writer.endNode(); try { final Field field = type.getDeclaredField("serialVersionUID"); field.setAccessible(true); long serialVersionUID = field.getLong(null); - writer.startNode("serialVersionUID"); + writer.startNode("serialVersionUID", String.class); writer.setValue(String.valueOf(serialVersionUID)); writer.endNode(); } catch (NoSuchFieldException e) { Index: src/java/com/thoughtworks/xstream/converters/reflection/SerializableConverter.java =================================================================== --- src/java/com/thoughtworks/xstream/converters/reflection/SerializableConverter.java (revision 871) +++ src/java/com/thoughtworks/xstream/converters/reflection/SerializableConverter.java (working copy) @@ -84,7 +84,7 @@ writer.startNode(ELEMENT_NULL); writer.endNode(); } else { - writer.startNode(mapper.serializedClass(object.getClass())); + writer.startNode(mapper.serializedClass(object.getClass()), object.getClass()); context.convertAnother(object); writer.endNode(); } Index: src/java/com/thoughtworks/xstream/converters/javabean/JavaBeanConverter.java =================================================================== --- src/java/com/thoughtworks/xstream/converters/javabean/JavaBeanConverter.java (revision 871) +++ src/java/com/thoughtworks/xstream/converters/javabean/JavaBeanConverter.java (working copy) @@ -60,7 +60,7 @@ } private void writeField(String propertyName, Class fieldType, Object newObj) { - writer.startNode(classMapper.serializedMember(source.getClass(), propertyName)); + writer.startNode(classMapper.serializedMember(source.getClass(), propertyName), fieldType); Class actualType = newObj.getClass(); Index: src/java/com/thoughtworks/xstream/converters/collections/ArrayConverter.java =================================================================== --- src/java/com/thoughtworks/xstream/converters/collections/ArrayConverter.java (revision 871) +++ src/java/com/thoughtworks/xstream/converters/collections/ArrayConverter.java (working copy) @@ -33,6 +33,7 @@ Object item = Array.get(source, i); writeItem(item, context, writer); } + } public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { Index: src/java/com/thoughtworks/xstream/converters/collections/AbstractCollectionConverter.java =================================================================== --- src/java/com/thoughtworks/xstream/converters/collections/AbstractCollectionConverter.java (revision 871) +++ src/java/com/thoughtworks/xstream/converters/collections/AbstractCollectionConverter.java (working copy) @@ -36,14 +36,18 @@ public abstract Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context); + + protected void writeItem(Object item, MarshallingContext context, HierarchicalStreamWriter writer) { // PUBLISHED API METHOD! If changing signature, ensure backwards compatability. if (item == null) { // todo: this is duplicated in TreeMarshaller.start() - writer.startNode(mapper().serializedClass(null)); + String name = mapper().serializedClass(null); + writer.startNode(name); writer.endNode(); } else { - writer.startNode(mapper().serializedClass(item.getClass())); + String name = mapper().serializedClass(item.getClass()); + writer.startNode(name, item.getClass()); context.convertAnother(item); writer.endNode(); }