changeset 827:50a9a4db3500

4864117: RFE: Make XMLDecoder API more reusable Reviewed-by: peterz, loneid
author malenkov
date Mon, 22 Dec 2008 17:42:49 +0300
parents 5784f5dfe3ac
children 2b8a0d8b5cbb
files src/share/classes/com/sun/beans/ObjectHandler.java src/share/classes/com/sun/beans/decoder/AccessorElementHandler.java src/share/classes/com/sun/beans/decoder/ArrayElementHandler.java src/share/classes/com/sun/beans/decoder/BooleanElementHandler.java src/share/classes/com/sun/beans/decoder/ByteElementHandler.java src/share/classes/com/sun/beans/decoder/CharElementHandler.java src/share/classes/com/sun/beans/decoder/ClassElementHandler.java src/share/classes/com/sun/beans/decoder/DocumentHandler.java src/share/classes/com/sun/beans/decoder/DoubleElementHandler.java src/share/classes/com/sun/beans/decoder/ElementHandler.java src/share/classes/com/sun/beans/decoder/FalseElementHandler.java src/share/classes/com/sun/beans/decoder/FieldElementHandler.java src/share/classes/com/sun/beans/decoder/FloatElementHandler.java src/share/classes/com/sun/beans/decoder/IntElementHandler.java src/share/classes/com/sun/beans/decoder/JavaElementHandler.java src/share/classes/com/sun/beans/decoder/LongElementHandler.java src/share/classes/com/sun/beans/decoder/MethodElementHandler.java src/share/classes/com/sun/beans/decoder/NewElementHandler.java src/share/classes/com/sun/beans/decoder/NullElementHandler.java src/share/classes/com/sun/beans/decoder/ObjectElementHandler.java src/share/classes/com/sun/beans/decoder/PropertyElementHandler.java src/share/classes/com/sun/beans/decoder/ShortElementHandler.java src/share/classes/com/sun/beans/decoder/StringElementHandler.java src/share/classes/com/sun/beans/decoder/TrueElementHandler.java src/share/classes/com/sun/beans/decoder/ValueObject.java src/share/classes/com/sun/beans/decoder/ValueObjectImpl.java src/share/classes/com/sun/beans/decoder/VarElementHandler.java src/share/classes/com/sun/beans/decoder/VoidElementHandler.java src/share/classes/com/sun/beans/finder/AbstractFinder.java src/share/classes/com/sun/beans/finder/ClassFinder.java src/share/classes/com/sun/beans/finder/ConstructorFinder.java src/share/classes/com/sun/beans/finder/FieldFinder.java src/share/classes/com/sun/beans/finder/MethodFinder.java src/share/classes/com/sun/beans/finder/PrimitiveTypeMap.java src/share/classes/com/sun/beans/finder/PrimitiveWrapperMap.java src/share/classes/com/sun/beans/finder/Signature.java src/share/classes/java/beans/MetaData.java src/share/classes/java/beans/ReflectionUtils.java src/share/classes/java/beans/XMLDecoder.java src/share/classes/javax/swing/plaf/synth/SynthParser.java test/java/beans/XMLDecoder/Test4864117.java test/java/beans/XMLDecoder/Test6341798.java test/java/beans/XMLDecoder/spec/AbstractTest.java test/java/beans/XMLDecoder/spec/TestArray.java test/java/beans/XMLDecoder/spec/TestBoolean.java test/java/beans/XMLDecoder/spec/TestByte.java test/java/beans/XMLDecoder/spec/TestChar.java test/java/beans/XMLDecoder/spec/TestClass.java test/java/beans/XMLDecoder/spec/TestDouble.java test/java/beans/XMLDecoder/spec/TestFalse.java test/java/beans/XMLDecoder/spec/TestField.java test/java/beans/XMLDecoder/spec/TestFloat.java test/java/beans/XMLDecoder/spec/TestInt.java test/java/beans/XMLDecoder/spec/TestJava.java test/java/beans/XMLDecoder/spec/TestLong.java test/java/beans/XMLDecoder/spec/TestMethod.java test/java/beans/XMLDecoder/spec/TestNew.java test/java/beans/XMLDecoder/spec/TestNull.java test/java/beans/XMLDecoder/spec/TestObject.java test/java/beans/XMLDecoder/spec/TestProperty.java test/java/beans/XMLDecoder/spec/TestShort.java test/java/beans/XMLDecoder/spec/TestString.java test/java/beans/XMLDecoder/spec/TestTrue.java test/java/beans/XMLDecoder/spec/TestVar.java
diffstat 64 files changed, 5946 insertions(+), 673 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/beans/ObjectHandler.java	Thu Nov 27 17:55:36 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,479 +0,0 @@
-/*
- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package com.sun.beans;
-
-import com.sun.beans.finder.ClassFinder;
-
-import java.beans.*;
-import java.util.*;
-
-import org.xml.sax.*;
-
-import static java.util.Locale.ENGLISH;
-
-/**
- * <b>WARNING</b>: This class is an implementation detail and only meant
- * for use within the core platform. You should NOT depend upon it! This
- * API may change drastically between dot dot release, and it may even be
- * removed.
- *
- * @see java.beans.XMLEncoder
- * @see java.io.ObjectInputStream
- *
- * @since 1.4
- *
- * @author Philip Milne
- */
-public class ObjectHandler extends HandlerBase {
-
-    public static Class typeNameToClass(String typeName) {
-        typeName = typeName.intern();
-        if (typeName == "boolean") return Boolean.class;
-        if (typeName == "byte") return Byte.class;
-        if (typeName == "char") return Character.class;
-        if (typeName == "short") return Short.class;
-        if (typeName == "int") return Integer.class;
-        if (typeName == "long") return Long.class;
-        if (typeName == "float") return Float.class;
-        if (typeName == "double") return Double.class;
-        if (typeName == "void") return Void.class;
-        return null;
-    }
-
-    public static Class typeNameToPrimitiveClass(String typeName) {
-        typeName = typeName.intern();
-        if (typeName == "boolean") return boolean.class;
-        if (typeName == "byte") return byte.class;
-        if (typeName == "char") return char.class;
-        if (typeName == "short") return short.class;
-        if (typeName == "int") return int.class;
-        if (typeName == "long") return long.class;
-        if (typeName == "float") return float.class;
-        if (typeName == "double") return double.class;
-        if (typeName == "void") return void.class;
-        return null;
-    }
-
-    /**
-     * Returns the <code>Class</code> object associated with
-     * the class or interface with the given string name,
-     * using the default class loader.
-     *
-     * @param name  fully qualified name of the desired class
-     * @param cl    class loader from which the class must be loaded
-     * @return class object representing the desired class
-     *
-     * @exception ClassNotFoundException  if the class cannot be located
-     *                                    by the specified class loader
-     *
-     * @deprecated As of JDK version 7, replaced by
-     *             {@link ClassFinder#resolveClass(String)}.
-     */
-    @Deprecated
-    public static Class classForName(String name) throws ClassNotFoundException {
-        return ClassFinder.resolveClass(name);
-    }
-
-    /**
-     * Returns the <code>Class</code> object associated with
-     * the class or interface with the given string name,
-     * using the given class loader.
-     *
-     * @param name  fully qualified name of the desired class
-     * @param cl    class loader from which the class must be loaded
-     * @return class object representing the desired class
-     *
-     * @exception ClassNotFoundException  if the class cannot be located
-     *                                    by the specified class loader
-     *
-     * @deprecated As of JDK version 7, replaced by
-     *             {@link ClassFinder#resolveClass(String,ClassLoader)}.
-     */
-    @Deprecated
-    public static Class classForName(String name, ClassLoader cl)
-        throws ClassNotFoundException {
-        return ClassFinder.resolveClass(name, cl);
-    }
-
-    private Hashtable environment;
-    private Vector expStack;
-    private StringBuffer chars;
-    private XMLDecoder is;
-    private ClassLoader ldr;
-    private int itemsRead = 0;
-    private boolean isString;
-
-    public ObjectHandler() {
-        environment = new Hashtable();
-        expStack = new Vector();
-        chars = new StringBuffer();
-    }
-
-    public ObjectHandler(XMLDecoder is) {
-        this();
-        this.is = is;
-    }
-
-    /* loader can be null */
-    public ObjectHandler(XMLDecoder is, ClassLoader loader) {
-        this(is);
-        this.ldr = loader;
-    }
-
-
-    public void reset() {
-        expStack.clear();
-        chars.setLength(0);
-        MutableExpression e = new MutableExpression();
-        e.setTarget(classForName2("java.lang.Object"));
-        e.setMethodName("null");
-        expStack.add(e);
-    }
-
-    private Object getValue(Expression exp) {
-        try {
-            return exp.getValue();
-        }
-        catch (Exception e) {
-            if (is != null) {
-                is.getExceptionListener().exceptionThrown(e);
-            }
-            return null;
-        }
-    }
-
-    private void addArg(Object arg) {
-        lastExp().addArg(arg);
-    }
-
-    private Object pop(Vector v) {
-        int last = v.size()-1;
-        Object result = v.get(last);
-        v.remove(last);
-        return result;
-    }
-
-    private Object eval() {
-        return getValue(lastExp());
-    }
-
-    private MutableExpression lastExp() {
-        return (MutableExpression)expStack.lastElement();
-    }
-
-    public Object dequeueResult() {
-        Object[] results = lastExp().getArguments();
-        return results[itemsRead++];
-    }
-
-    private boolean isPrimitive(String name) {
-        return name != "void" && typeNameToClass(name) != null;
-    }
-
-    private void simulateException(String message) {
-        Exception e = new Exception(message);
-        e.fillInStackTrace();
-        if (is != null) {
-            is.getExceptionListener().exceptionThrown(e);
-        }
-    }
-
-    private Class classForName2(String name) {
-        try {
-            return ClassFinder.resolveClass(name, this.ldr);
-        }
-        catch (ClassNotFoundException e) {
-            if (is != null) {
-                is.getExceptionListener().exceptionThrown(e);
-            }
-        }
-        return null;
-    }
-
-    private HashMap getAttributes(AttributeList attrs) {
-        HashMap attributes = new HashMap();
-        if (attrs != null && attrs.getLength() > 0) {
-            for(int i = 0; i < attrs.getLength(); i++) {
-                attributes.put(attrs.getName(i), attrs.getValue(i));
-            }
-        }
-        return attributes;
-    }
-
-    public void startElement(String name, AttributeList attrs) throws SAXException {
-        name = name.intern(); // Xerces parser does not supply unique tag names.
-        if (this.isString) {
-            parseCharCode(name, getAttributes(attrs));
-            return;
-        }
-        chars.setLength(0);
-
-        HashMap attributes = getAttributes(attrs);
-        MutableExpression e = new MutableExpression();
-
-        // Target
-        String className = (String)attributes.get("class");
-        if (className != null) {
-            e.setTarget(classForName2(className));
-        }
-
-        // Property
-        Object property = attributes.get("property");
-        String index = (String)attributes.get("index");
-        if (index != null) {
-            property = new Integer(index);
-            e.addArg(property);
-        }
-        e.setProperty(property);
-
-        // Method
-        String methodName = (String)attributes.get("method");
-        if (methodName == null && property == null) {
-            methodName = "new";
-        }
-        e.setMethodName(methodName);
-
-        // Tags
-        if (name == "string") {
-            e.setTarget(String.class);
-            e.setMethodName("new");
-            this.isString = true;
-        }
-        else if (isPrimitive(name)){
-            Class wrapper = typeNameToClass(name);
-            e.setTarget(wrapper);
-            e.setMethodName("new");
-            parseCharCode(name, attributes);
-        }
-        else if (name == "class") {
-            e.setTarget(Class.class);
-            e.setMethodName("forName");
-        }
-        else if (name == "null") {
-            // Create an arbitrary expression that has a value of null - for
-            // consistency.
-            e.setTarget(Object.class);
-            e.setMethodName("getSuperclass");
-            e.setValue(null);
-        }
-        else if (name == "void") {
-            if (e.getTarget() == null) { // this check is for "void class="foo" method= ..."
-                e.setTarget(eval());
-            }
-        }
-        else if (name == "array") {
-            // The class attribute means sub-type for arrays.
-            String subtypeName = (String)attributes.get("class");
-            Class subtype = (subtypeName == null) ? Object.class : classForName2(subtypeName);
-            String length = (String)attributes.get("length");
-            if (length != null) {
-                e.setTarget(java.lang.reflect.Array.class);
-                e.addArg(subtype);
-                e.addArg(new Integer(length));
-            }
-            else {
-                Class arrayClass = java.lang.reflect.Array.newInstance(subtype, 0).getClass();
-                e.setTarget(arrayClass);
-            }
-        }
-        else if (name == "java") {
-            e.setValue(is); // The outermost scope is the stream itself.
-        }
-        else if (name == "object") {
-        }
-        else {
-            simulateException("Unrecognized opening tag: " + name + " " + attrsToString(attrs));
-            return;
-        }
-
-        // ids
-        String idName = (String)attributes.get("id");
-        if (idName != null) {
-            environment.put(idName, e);
-        }
-
-        // idrefs
-        String idrefName = (String)attributes.get("idref");
-        if (idrefName != null) {
-            e.setValue(lookup(idrefName));
-        }
-
-        // fields
-        String fieldName = (String)attributes.get("field");
-        if (fieldName != null) {
-            e.setValue(getFieldValue(e.getTarget(), fieldName));
-        }
-        expStack.add(e);
-    }
-
-    private Object getFieldValue(Object target, String fieldName) {
-        try {
-            Class type = target.getClass();
-            if (type == Class.class) {
-                type = (Class)target;
-            }
-            java.lang.reflect.Field f = sun.reflect.misc.FieldUtil.getField(type, fieldName);
-            return f.get(target);
-        }
-        catch (Exception e) {
-            if (is != null) {
-                is.getExceptionListener().exceptionThrown(e);
-            }
-            return null;
-        }
-    }
-
-    private String attrsToString(AttributeList attrs) {
-        StringBuffer b = new StringBuffer();
-        for (int i = 0; i < attrs.getLength (); i++) {
-            b.append(attrs.getName(i)+"=\""+attrs.getValue(i)+"\" ");
-        }
-        return b.toString();
-    }
-
-    public void characters(char buf [], int offset, int len) throws SAXException {
-        chars.append(new String(buf, offset, len));
-    }
-
-    private void parseCharCode(String name, Map map) {
-        if (name == "char") {
-            String value = (String) map.get("code");
-            if (value != null) {
-                int code = Integer.decode(value);
-                for (char ch : Character.toChars(code)) {
-                    this.chars.append(ch);
-                }
-            }
-        }
-    }
-
-    public Object lookup(String s) {
-        Expression e = (Expression)environment.get(s);
-        if (e == null) {
-            simulateException("Unbound variable: " + s);
-        }
-        return getValue(e);
-    }
-
-    public void register(String id, Object value) {
-        Expression e = new MutableExpression();
-        e.setValue(value);
-        environment.put(id, e);
-    }
-
-    public void endElement(String name) throws SAXException {
-        name = name.intern(); // Xerces parser does not supply unique tag names.
-        if (name == "string") {
-            this.isString = false;
-        } else if (this.isString) {
-            return;
-        }
-        if (name == "java") {
-            return;
-        }
-        if (isPrimitive(name) || name == "string" || name == "class") {
-            addArg(chars.toString());
-        }
-        if (name == "object" || name == "array" || name == "void" ||
-                isPrimitive(name) || name == "string" || name == "class" ||
-                name == "null") {
-            Expression e = (Expression)pop(expStack);
-            Object value = getValue(e);
-            if (name != "void") {
-                addArg(value);
-            }
-        }
-        else {
-            simulateException("Unrecognized closing tag: " + name);
-        }
-    }
-}
-
-
-class MutableExpression extends Expression {
-    private Object target;
-    private String methodName;
-
-    private Object property;
-    private Vector argV = new Vector();
-
-    private String capitalize(String propertyName) {
-        if (propertyName.length() == 0) {
-            return propertyName;
-        }
-        return propertyName.substring(0, 1).toUpperCase(ENGLISH) + propertyName.substring(1);
-    }
-
-    public MutableExpression() {
-        super(null, null, null);
-    }
-
-    public Object[] getArguments() {
-        return argV.toArray();
-    }
-
-    public String getMethodName() {
-        if (property == null) {
-            return methodName;
-        }
-        int setterArgs = (property instanceof String) ? 1 : 2;
-        String methodName = (argV.size() == setterArgs) ? "set" : "get";
-        if (property instanceof String) {
-            return methodName + capitalize((String)property);
-        }
-        else {
-            return methodName;
-        }
-    }
-
-    public void addArg(Object arg) {
-        argV.add(arg);
-    }
-
-    public void setTarget(Object target) {
-        this.target = target;
-    }
-
-    public Object getTarget() {
-        return target;
-    }
-
-    public void setMethodName(String methodName) {
-        this.methodName = methodName;
-    }
-
-    public void setProperty(Object property) {
-        this.property = property;
-    }
-
-    public void setValue(Object value) {
-        super.setValue(value);
-    }
-
-    public Object getValue() throws Exception {
-        return super.getValue();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/AccessorElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This is base class that simplifies access to entities (fields or properties).
+ * The {@code name} attribute specifies the name of the accessible entity.
+ * The element defines getter if it contains no argument
+ * or setter if it contains one argument.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+abstract class AccessorElementHandler extends ElementHandler {
+    private String name;
+    private ValueObject value;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>name
+     * <dd>the name of the accessible entity
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("name")) { // NON-NLS: the attribute name
+            this.name = value;
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Adds the argument that is used to set the value of this element.
+     *
+     * @param argument  the value of the element that contained in this one
+     */
+    @Override
+    protected final void addArgument(Object argument) {
+        if (this.value != null) {
+            throw new IllegalStateException("Could not add argument to evaluated element");
+        }
+        setValue(this.name, argument);
+        this.value = ValueObjectImpl.VOID;
+    }
+
+    /**
+     * Returns the value of this element.
+     *
+     * @return the value of this element
+     */
+    @Override
+    protected final ValueObject getValueObject() {
+        if (this.value == null) {
+            this.value = ValueObjectImpl.create(getValue(this.name));
+        }
+        return this.value;
+    }
+
+    /**
+     * Returns the value of the entity with specified {@code name}.
+     *
+     * @param name  the name of the accessible entity
+     * @return the value of the specified entity
+     */
+    protected abstract Object getValue(String name);
+
+    /**
+     * Sets the new value for the entity with specified {@code name}.
+     *
+     * @param name   the name of the accessible entity
+     * @param value  the new value for the specified entity
+     */
+    protected abstract void setValue(String name, Object value);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/ArrayElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import java.lang.reflect.Array;
+
+/**
+ * This class is intended to handle &lt;array&gt; element,
+ * that is used to array creation.
+ * The {@code length} attribute specifies the length of the array.
+ * The {@code class} attribute specifies the elements type.
+ * The {@link Object} type is used by default.
+ * For example:<pre>
+ * &lt;array length="10"/&gt;</pre>
+ * is equivalent to {@code new Component[10]} in Java code.
+ * The {@code set} and {@code get} methods,
+ * as defined in the {@link java.util.List} interface,
+ * can be used as if they could be applied to array instances.
+ * The {@code index} attribute can thus be used with arrays.
+ * For example:<pre>
+ * &lt;array length="3" class="java.lang.String"&gt;
+ *     &lt;void index="1"&gt;
+ *         &lt;string&gt;Hello, world&lt;/string&gt;
+ *     &lt;/void&gt;
+ * &lt;/array&gt;</pre>
+ * is equivalent to the following Java code:<pre>
+ * String[] s = new String[3];
+ * s[1] = "Hello, world";</pre>
+ * It is possible to omit the {@code length} attribute and
+ * specify the values directly, without using {@code void} tags.
+ * The length of the array is equal to the number of values specified.
+ * For example:<pre>
+ * &lt;array id="array" class="int"&gt;
+ *     &lt;int&gt;123&lt;/int&gt;
+ *     &lt;int&gt;456&lt;/int&gt;
+ * &lt;/array&gt;</pre>
+ * is equivalent to {@code int[] array = {123, 456}} in Java code.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>length
+ * <dd>the array length
+ * <dt>class
+ * <dd>the type of object for instantiation
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class ArrayElementHandler extends NewElementHandler {
+    private Integer length;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>length
+     * <dd>the array length
+     * <dt>class
+     * <dd>the type of object for instantiation
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("length")) { // NON-NLS: the attribute name
+            this.length = Integer.valueOf(value);
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Calculates the value of this element
+     * if the lentgh attribute is set.
+     */
+    @Override
+    public void startElement() {
+        if (this.length != null) {
+            getValueObject();
+        }
+    }
+
+    /**
+     * Creates an instance of the array.
+     *
+     * @param type  the base class
+     * @param args  the array of arguments
+     * @return the value of this element
+     */
+    @Override
+    protected ValueObject getValueObject(Class<?> type, Object[] args) {
+        if (type == null) {
+            type = Object.class;
+        }
+        if (this.length != null) {
+            return ValueObjectImpl.create(Array.newInstance(type, this.length));
+        }
+        Object array = Array.newInstance(type, args.length);
+        for (int i = 0; i < args.length; i++) {
+            Array.set(array, i, args[i]);
+        }
+        return ValueObjectImpl.create(array);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/BooleanElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;boolean&gt; element.
+ * This element specifies {@code boolean} values.
+ * The class {@link Boolean} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;boolean&gt;true&lt;/boolean&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="valueOf" class="java.lang.Boolean"&gt;
+ *     &lt;string&gt;true&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Boolean.valueOf("true")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class BooleanElementHandler extends StringElementHandler {
+
+    /**
+     * Creates {@code boolean} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code boolean} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        if (Boolean.TRUE.toString().equalsIgnoreCase(argument)) {
+            return Boolean.TRUE;
+        }
+        if (Boolean.FALSE.toString().equalsIgnoreCase(argument)) {
+            return Boolean.FALSE;
+        }
+        throw new IllegalArgumentException("Unsupported boolean argument: " + argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/ByteElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;byte&gt; element.
+ * This element specifies {@code byte} values.
+ * The class {@link Byte} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;byte&gt;127&lt;/byte&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="decode" class="java.lang.Byte"&gt;
+ *     &lt;string&gt;127&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Byte.decode("127")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class ByteElementHandler extends StringElementHandler {
+
+    /**
+     * Creates {@code byte} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code byte} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        return Byte.decode(argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/CharElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;char&gt; element.
+ * This element specifies {@code char} values.
+ * The class {@link Character} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;char&gt;X&lt;/char&gt;</pre>
+ * which is equivalent to {@code Character.valueOf('X')} in Java code.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>code
+ * <dd>this attribute specifies character code
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ * The {@code code} attribute can be used for characters
+ * that are illegal in XML document, for example:<pre>
+ * &lt;char code="0"/&gt;</pre>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class CharElementHandler extends StringElementHandler {
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>code
+     * <dd>this attribute specifies character code
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("code")) { // NON-NLS: the attribute name
+            int code = Integer.decode(value);
+            for (char ch : Character.toChars(code)) {
+                addCharacter(ch);
+            }
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Creates {@code char} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code char} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        if (argument.length() != 1) {
+            throw new IllegalArgumentException("Wrong characters count");
+        }
+        return Character.valueOf(argument.charAt(0));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/ClassElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;class&gt; element.
+ * This element specifies {@link Class} values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;class&gt;java.lang.Class&lt;/class&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="forName" class="java.lang.Class"&gt;
+ *     &lt;string&gt;java.lang.Class&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Class.forName("java.lang.Class")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class ClassElementHandler extends StringElementHandler {
+
+    /**
+     * Creates class by the name from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code Class} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        return getOwner().findClass(argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/DocumentHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,389 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import com.sun.beans.finder.ClassFinder;
+
+import java.beans.ExceptionListener;
+
+import java.io.IOException;
+
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * The main class to parse JavaBeans XML archive.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ *
+ * @see ElementHandler
+ */
+public final class DocumentHandler extends DefaultHandler {
+    private final Map<String, Class<? extends ElementHandler>> handlers = new HashMap<String, Class<? extends ElementHandler>>();
+
+    private final Map<String, Object> environment = new HashMap<String, Object>();
+
+    private final List<Object> objects = new ArrayList<Object>();
+
+    private Reference<ClassLoader> loader;
+    private ExceptionListener listener;
+    private Object owner;
+
+    private ElementHandler handler;
+
+    /**
+     * Creates new instance of document handler.
+     */
+    public DocumentHandler() {
+        setElementHandler("java", JavaElementHandler.class); // NON-NLS: the element name
+        setElementHandler("null", NullElementHandler.class); // NON-NLS: the element name
+        setElementHandler("array", ArrayElementHandler.class); // NON-NLS: the element name
+        setElementHandler("class", ClassElementHandler.class); // NON-NLS: the element name
+        setElementHandler("string", StringElementHandler.class); // NON-NLS: the element name
+        setElementHandler("object", ObjectElementHandler.class); // NON-NLS: the element name
+
+        setElementHandler("void", VoidElementHandler.class); // NON-NLS: the element name
+        setElementHandler("char", CharElementHandler.class); // NON-NLS: the element name
+        setElementHandler("byte", ByteElementHandler.class); // NON-NLS: the element name
+        setElementHandler("short", ShortElementHandler.class); // NON-NLS: the element name
+        setElementHandler("int", IntElementHandler.class); // NON-NLS: the element name
+        setElementHandler("long", LongElementHandler.class); // NON-NLS: the element name
+        setElementHandler("float", FloatElementHandler.class); // NON-NLS: the element name
+        setElementHandler("double", DoubleElementHandler.class); // NON-NLS: the element name
+        setElementHandler("boolean", BooleanElementHandler.class); // NON-NLS: the element name
+
+        // some handlers for new elements
+        setElementHandler("new", NewElementHandler.class); // NON-NLS: the element name
+        setElementHandler("var", VarElementHandler.class); // NON-NLS: the element name
+        setElementHandler("true", TrueElementHandler.class); // NON-NLS: the element name
+        setElementHandler("false", FalseElementHandler.class); // NON-NLS: the element name
+        setElementHandler("field", FieldElementHandler.class); // NON-NLS: the element name
+        setElementHandler("method", MethodElementHandler.class); // NON-NLS: the element name
+        setElementHandler("property", PropertyElementHandler.class); // NON-NLS: the element name
+    }
+
+    /**
+     * Returns the class loader used to instantiate objects.
+     * If the class loader has not been explicitly set
+     * then {@code null} is returned.
+     *
+     * @return the class loader used to instantiate objects
+     */
+    public ClassLoader getClassLoader() {
+        return (this.loader != null)
+                ? this.loader.get()
+                : null;
+    }
+
+    /**
+     * Sets the class loader used to instantiate objects.
+     * If the class loader is not set
+     * then default class loader will be used.
+     *
+     * @param loader  a classloader to use
+     */
+    public void setClassLoader(ClassLoader loader) {
+        this.loader = new WeakReference<ClassLoader>(loader);
+    }
+
+    /**
+     * Returns the exception listener for parsing.
+     * The exception listener is notified
+     * when handler catches recoverable exceptions.
+     * If the exception listener has not been explicitly set
+     * then default exception listener is returned.
+     *
+     * @return the exception listener for parsing
+     */
+    public ExceptionListener getExceptionListener() {
+        return this.listener;
+    }
+
+    /**
+     * Sets the exception listener for parsing.
+     * The exception listener is notified
+     * when handler catches recoverable exceptions.
+     *
+     * @param listener  the exception listener for parsing
+     */
+    public void setExceptionListener(ExceptionListener listener) {
+        this.listener = listener;
+    }
+
+    /**
+     * Returns the owner of this document handler.
+     *
+     * @return the owner of this document handler
+     */
+    public Object getOwner() {
+        return this.owner;
+    }
+
+    /**
+     * Sets the owner of this document handler.
+     *
+     * @param owner  the owner of this document handler
+     */
+    public void setOwner(Object owner) {
+        this.owner = owner;
+    }
+
+    /**
+     * Returns the handler for the element with specified name.
+     *
+     * @param name  the name of the element
+     * @return the corresponding element handler
+     */
+    public Class<? extends ElementHandler> getElementHandler(String name) {
+        Class<? extends ElementHandler> type = this.handlers.get(name);
+        if (type == null) {
+            throw new IllegalArgumentException("Unsupported element: " + name);
+        }
+        return type;
+    }
+
+    /**
+     * Sets the handler for the element with specified name.
+     *
+     * @param name     the name of the element
+     * @param handler  the corresponding element handler
+     */
+    public void setElementHandler(String name, Class<? extends ElementHandler> handler) {
+        this.handlers.put(name, handler);
+    }
+
+    /**
+     * Indicates whether the variable with specified identifier is defined.
+     *
+     * @param id  the identifier
+     * @return @{code true} if the variable is defined;
+     *         @{code false} otherwise
+     */
+    public boolean hasVariable(String id) {
+        return this.environment.containsKey(id);
+    }
+
+    /**
+     * Returns the value of the variable with specified identifier.
+     *
+     * @param id  the identifier
+     * @return the value of the variable
+     */
+    public Object getVariable(String id) {
+        if (!this.environment.containsKey(id)) {
+            throw new IllegalArgumentException("Unbound variable: " + id);
+        }
+        return this.environment.get(id);
+    }
+
+    /**
+     * Sets new value of the variable with specified identifier.
+     *
+     * @param id     the identifier
+     * @param value  new value of the variable
+     */
+    public void setVariable(String id, Object value) {
+        this.environment.put(id, value);
+    }
+
+    /**
+     * Returns the array of readed objects.
+     *
+     * @return the array of readed objects
+     */
+    public Object[] getObjects() {
+        return this.objects.toArray();
+    }
+
+    /**
+     * Adds the object to the list of readed objects.
+     *
+     * @param object  the object that is readed from XML document
+     */
+    void addObject(Object object) {
+        this.objects.add(object);
+    }
+
+    /**
+     * Prepares this handler to read objects from XML document.
+     */
+    @Override
+    public void startDocument() {
+        this.objects.clear();
+        this.handler = null;
+    }
+
+    /**
+     * Parses opening tag of XML element
+     * using corresponding element handler.
+     *
+     * @param uri         the namespace URI, or the empty string
+     *                    if the element has no namespace URI or
+     *                    if namespace processing is not being performed
+     * @param localName   the local name (without prefix), or the empty string
+     *                    if namespace processing is not being performed
+     * @param qName       the qualified name (with prefix), or the empty string
+     *                    if qualified names are not available
+     * @param attributes  the attributes attached to the element
+     */
+    @Override
+    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+        ElementHandler parent = this.handler;
+        try {
+            this.handler = getElementHandler(qName).newInstance();
+            this.handler.setOwner(this);
+            this.handler.setParent(parent);
+        }
+        catch (Exception exception) {
+            throw new SAXException(exception);
+        }
+        for (int i = 0; i < attributes.getLength(); i++)
+            try {
+                String name = attributes.getQName(i);
+                String value = attributes.getValue(i);
+                this.handler.addAttribute(name, value);
+            }
+            catch (RuntimeException exception) {
+                handleException(exception);
+            }
+
+        this.handler.startElement();
+    }
+
+    /**
+     * Parses closing tag of XML element
+     * using corresponding element handler.
+     *
+     * @param uri        the namespace URI, or the empty string
+     *                   if the element has no namespace URI or
+     *                   if namespace processing is not being performed
+     * @param localName  the local name (without prefix), or the empty string
+     *                   if namespace processing is not being performed
+     * @param qName      the qualified name (with prefix), or the empty string
+     *                   if qualified names are not available
+     */
+    @Override
+    public void endElement(String uri, String localName, String qName) {
+        try {
+            this.handler.endElement();
+        }
+        catch (RuntimeException exception) {
+            handleException(exception);
+        }
+        finally {
+            this.handler = this.handler.getParent();
+        }
+    }
+
+    /**
+     * Parses character data inside XML element.
+     *
+     * @param chars   the array of characters
+     * @param start   the start position in the character array
+     * @param length  the number of characters to use
+     */
+    @Override
+    public void characters(char[] chars, int start, int length) {
+        if (this.handler != null) {
+            try {
+                while (0 < length--) {
+                    this.handler.addCharacter(chars[start++]);
+                }
+            }
+            catch (RuntimeException exception) {
+                handleException(exception);
+            }
+        }
+    }
+
+    /**
+     * Handles an exception using current exception listener.
+     *
+     * @param exception  an exception to handle
+     * @see #setExceptionListener
+     */
+    public void handleException(Exception exception) {
+        if (this.listener == null) {
+            throw new IllegalStateException(exception);
+        }
+        this.listener.exceptionThrown(exception);
+    }
+
+    /**
+     * Starts parsing of the specified input source.
+     *
+     * @param input  the input source to parse
+     */
+    public void parse(InputSource input) {
+        try {
+            SAXParserFactory.newInstance().newSAXParser().parse(input, this);
+        }
+        catch (ParserConfigurationException exception) {
+            handleException(exception);
+        }
+        catch (SAXException wrapper) {
+            Exception exception = wrapper.getException();
+            if (exception == null) {
+                exception = wrapper;
+            }
+            handleException(exception);
+        }
+        catch (IOException exception) {
+            handleException(exception);
+        }
+    }
+
+    /**
+     * Resolves class by name using current class loader.
+     * This method handles exception using current exception listener.
+     *
+     * @param name  the name of the class
+     * @return the object that represents the class
+     */
+    public Class<?> findClass(String name) {
+        try {
+            return ClassFinder.resolveClass(name, getClassLoader());
+        }
+        catch (ClassNotFoundException exception) {
+            handleException(exception);
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/DoubleElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;double&gt; element.
+ * This element specifies {@code double} values.
+ * The class {@link Double} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;double&gt;1.23e45&lt;/double&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="valueOf" class="java.lang.Double"&gt;
+ *     &lt;string&gt;1.23e45&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Double.valueOf("1.23e45")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class DoubleElementHandler extends StringElementHandler {
+
+    /**
+     * Creates {@code double} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code double} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        return Double.valueOf(argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/ElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * The base class for element handlers.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ *
+ * @see DocumentHandler
+ */
+public abstract class ElementHandler {
+    private DocumentHandler owner;
+    private ElementHandler parent;
+
+    private String id;
+
+    /**
+     * Returns the document handler that creates this element handler.
+     *
+     * @return the owner document handler
+     */
+    public final DocumentHandler getOwner() {
+        return this.owner;
+    }
+
+    /**
+     * Sets the document handler that creates this element handler.
+     * The owner document handler should be set after instantiation.
+     * Such approach is used to simplify the extensibility.
+     *
+     * @param owner  the owner document handler
+     * @see DocumentHandler#startElement
+     */
+    final void setOwner(DocumentHandler owner) {
+        if (owner == null) {
+            throw new IllegalArgumentException("Every element should have owner");
+        }
+        this.owner = owner;
+    }
+
+    /**
+     * Returns the element handler that contains this one.
+     *
+     * @return the parent element handler
+     */
+    public final ElementHandler getParent() {
+        return this.parent;
+    }
+
+    /**
+     * Sets the element handler that contains this one.
+     * The parent element handler should be set after instantiation.
+     * Such approach is used to simplify the extensibility.
+     *
+     * @param parent  the parent element handler
+     * @see DocumentHandler#startElement
+     */
+    final void setParent(ElementHandler parent) {
+        this.parent = parent;
+    }
+
+    /**
+     * Returns the value of the variable with specified identifier.
+     *
+     * @param id  the identifier
+     * @return the value of the variable
+     */
+    protected final Object getVariable(String id) {
+        if (id.equals(this.id)) {
+            ValueObject value = getValueObject();
+            if (value.isVoid()) {
+                throw new IllegalStateException("The element does not return value");
+            }
+            return value.getValue();
+        }
+        return (this.parent != null)
+                ? this.parent.getVariable(id)
+                : this.owner.getVariable(id);
+    }
+
+    /**
+     * Returns the value of the parent element.
+     *
+     * @return the value of the parent element
+     */
+    protected Object getContextBean() {
+        if (this.parent != null) {
+            ValueObject value = this.parent.getValueObject();
+            if (!value.isVoid()) {
+                return value.getValue();
+            }
+            throw new IllegalStateException("The outer element does not return value");
+        } else {
+            Object value = this.owner.getOwner();
+            if (value != null) {
+                return value;
+            }
+            throw new IllegalStateException("The topmost element does not have context");
+        }
+    }
+
+    /**
+     * Parses attributes of the element.
+     * By default, the following atribute is supported:
+     * <dl>
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    public void addAttribute(String name, String value) {
+        if (name.equals("id")) { // NON-NLS: the attribute name
+            this.id = value;
+        } else {
+            throw new IllegalArgumentException("Unsupported attribute: " + name);
+        }
+    }
+
+    /**
+     * This method is called before parsing of the element's body.
+     * All attributes are parsed at this point.
+     * By default, do nothing.
+     */
+    public void startElement() {
+    }
+
+    /**
+     * This method is called after parsing of the element's body.
+     * By default, it calculates the value of this element.
+     * The following tasks are executing for any non-void value:
+     * <ol>
+     * <li>If the {@code id} attribute is set
+     * the value of the variable with the specified identifier
+     * is set to the value of this element.</li>
+     * <li>This element is used as an argument of parent element if it is possible.</li>
+     * </ol>
+     *
+     * @see #isArgument
+     */
+    public void endElement() {
+        // do nothing if no value returned
+        ValueObject value = getValueObject();
+        if (!value.isVoid()) {
+            if (this.id != null) {
+                this.owner.setVariable(this.id, value.getValue());
+            }
+            if (isArgument()) {
+                if (this.parent != null) {
+                    this.parent.addArgument(value.getValue());
+                } else {
+                    this.owner.addObject(value.getValue());
+                }
+            }
+        }
+    }
+
+    /**
+     * Adds the character that contained in this element.
+     * By default, only whitespaces are acceptable.
+     *
+     * @param ch  the character
+     */
+    public void addCharacter(char ch) {
+        if ((ch != ' ') && (ch != '\n') && (ch != '\t') && (ch != '\r')) {
+            throw new IllegalStateException("Illegal character with code " + (int) ch);
+        }
+    }
+
+    /**
+     * Adds the argument that is used to calculate the value of this element.
+     * By default, no arguments are acceptable.
+     *
+     * @param argument  the value of the element that contained in this one
+     */
+    protected void addArgument(Object argument) {
+        throw new IllegalStateException("Could not add argument to simple element");
+    }
+
+    /**
+     * Tests whether the value of this element can be used
+     * as an argument of the element that contained in this one.
+     *
+     * @return {@code true} if the value of this element can be used
+     *         as an argument of the element that contained in this one,
+     *         {@code false} otherwise
+     */
+    protected boolean isArgument() {
+        return this.id == null;
+    }
+
+    /**
+     * Returns the value of this element.
+     *
+     * @return the value of this element
+     */
+    protected abstract ValueObject getValueObject();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/FalseElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;false&gt; element.
+ * This element specifies {@code false} value.
+ * It should not contain body or inner elements.
+ * For example:<pre>
+ * &lt;false/&gt;</pre>
+ * is equivalent to {@code false} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class FalseElementHandler extends NullElementHandler {
+
+    /**
+     * Returns {@code Boolean.FALSE}
+     * as a value of &lt;false&gt; element.
+     *
+     * @return {@code Boolean.FALSE} by default
+     */
+    @Override
+    public Object getValue() {
+        return Boolean.FALSE;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/FieldElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import com.sun.beans.finder.FieldFinder;
+
+import java.lang.reflect.Field;
+
+/**
+ * This class is intended to handle &lt;field&gt; element.
+ * This element simplifies access to the fields.
+ * If the {@code class} attribute is specified
+ * this element accesses static field of specified class.
+ * This element defines getter if it contains no argument.
+ * It returns the value of the field in this case.
+ * For example:<pre>
+ * &lt;field name="TYPE" class="java.lang.Long"/&gt;</pre>
+ * is equivalent to {@code Long.TYPE} in Java code.
+ * This element defines setter if it contains one argument.
+ * It does not return the value of the field in this case.
+ * For example:<pre>
+ * &lt;field name="id"&gt;&lt;int&gt;0&lt;/int&gt;&lt;/field&gt;</pre>
+ * is equivalent to {@code id = 0} in Java code.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>name
+ * <dd>the field name
+ * <dt>class
+ * <dd>the type is used for static fields only
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class FieldElementHandler extends AccessorElementHandler {
+    private Class<?> type;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>name
+     * <dd>the field name
+     * <dt>class
+     * <dd>the type is used for static fields only
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("class")) { // NON-NLS: the attribute name
+            this.type = getOwner().findClass(value);
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Tests whether the value of this element can be used
+     * as an argument of the element that contained in this one.
+     *
+     * @return {@code true} if the value of this element should be used
+     *         as an argument of the element that contained in this one,
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isArgument() {
+        return super.isArgument() && (this.type != null); // only static accessor can be used an argument
+    }
+
+    /**
+     * Returns the context of the field.
+     * The context of the static field is the class object.
+     * The context of the non-static field is the value of the parent element.
+     *
+     * @return the context of the field
+     */
+    @Override
+    protected Object getContextBean() {
+        return (this.type != null)
+                ? this.type
+                : super.getContextBean();
+    }
+
+    /**
+     * Returns the value of the field with specified {@code name}.
+     *
+     * @param name  the name of the field
+     * @return the value of the specified field
+     */
+    @Override
+    protected Object getValue(String name) {
+        try {
+            return getFieldValue(getContextBean(), name);
+        }
+        catch (Exception exception) {
+            getOwner().handleException(exception);
+        }
+        return null;
+    }
+
+    /**
+     * Sets the new value for the field with specified {@code name}.
+     *
+     * @param name   the name of the field
+     * @param value  the new value for the specified field
+     */
+    @Override
+    protected void setValue(String name, Object value) {
+        try {
+            setFieldValue(getContextBean(), name, value);
+        }
+        catch (Exception exception) {
+            getOwner().handleException(exception);
+        }
+    }
+
+    /**
+     * Performs the search of the field with specified {@code name}
+     * in specified context and returns its value.
+     *
+     * @param bean  the context bean that contains field
+     * @param name  the name of the field
+     * @return the value of the field
+     * @throws IllegalAccessException if the field is not accesible
+     * @throws NoSuchFieldException   if the field is not found
+     */
+    static Object getFieldValue(Object bean, String name) throws IllegalAccessException, NoSuchFieldException {
+        return findField(bean, name).get(bean);
+    }
+
+    /**
+     * Performs the search of the field with specified {@code name}
+     * in specified context and updates its value.
+     *
+     * @param bean   the context bean that contains field
+     * @param name   the name of the field
+     * @param value  the new value for the field
+     * @throws IllegalAccessException if the field is not accesible
+     * @throws NoSuchFieldException   if the field is not found
+     */
+    private static void setFieldValue(Object bean, String name, Object value) throws IllegalAccessException, NoSuchFieldException {
+        findField(bean, name).set(bean, value);
+    }
+
+    /**
+     * Performs the search of the field
+     * with specified {@code name} in specified context.
+     *
+     * @param bean  the context bean that contains field
+     * @param name  the name of the field
+     * @return field object that represents found field
+     * @throws NoSuchFieldException if the field is not found
+     */
+    private static Field findField(Object bean, String name) throws NoSuchFieldException {
+        return (bean instanceof Class<?>)
+                ? FieldFinder.findStaticField((Class<?>) bean, name)
+                : FieldFinder.findField(bean.getClass(), name);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/FloatElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;float&gt; element.
+ * This element specifies {@code float} values.
+ * The class {@link Float} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;float&gt;-1.23&lt;/float&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="valueOf" class="java.lang.Float"&gt;
+ *     &lt;string&gt;-1.23&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Float.valueOf("-1.23")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class FloatElementHandler extends StringElementHandler {
+
+    /**
+     * Creates {@code float} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code float} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        return Float.valueOf(argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/IntElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;int&gt; element.
+ * This element specifies {@code int} values.
+ * The class {@link Integer} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;int&gt;-1&lt;/int&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="decode" class="java.lang.Integer"&gt;
+ *     &lt;string&gt;-1&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Integer.decode("-1")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class IntElementHandler extends StringElementHandler {
+
+    /**
+     * Creates {@code int} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code int} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        return Integer.decode(argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/JavaElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import java.beans.XMLDecoder;
+
+/**
+ * This class is intended to handle &lt;java&gt; element.
+ * Each element that appears in the body of this element
+ * is evaluated in the context of the decoder itself.
+ * Typically this outer context is used to retrieve the owner of the decoder,
+ * which can be set before reading the archive.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>version
+ * <dd>the Java version (not supported)
+ * <dt>class
+ * <dd>the type of preferable parser (not supported)
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @see DocumentHandler#getOwner
+ * @see DocumentHandler#setOwner
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class JavaElementHandler extends ElementHandler {
+    private Class<?> type;
+    private ValueObject value;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>version
+     * <dd>the Java version (not supported)
+     * <dt>class
+     * <dd>the type of preferable parser (not supported)
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("version")) { // NON-NLS: the attribute name
+            // unsupported attribute
+        } else if (name.equals("class")) { // NON-NLS: the attribute name
+            // check class for owner
+            this.type = getOwner().findClass(value);
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Adds the argument to the list of readed objects.
+     *
+     * @param argument  the value of the element that contained in this one
+     */
+    @Override
+    protected void addArgument(Object argument) {
+        getOwner().addObject(argument);
+    }
+
+    /**
+     * Tests whether the value of this element can be used
+     * as an argument of the element that contained in this one.
+     *
+     * @return {@code true} if the value of this element should be used
+     *         as an argument of the element that contained in this one,
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isArgument() {
+        return false; // do not use owner as object
+    }
+
+    /**
+     * Returns the value of this element.
+     *
+     * @return the value of this element
+     */
+    @Override
+    protected ValueObject getValueObject() {
+        if (this.value == null) {
+            this.value = ValueObjectImpl.create(getValue());
+        }
+        return this.value;
+    }
+
+    /**
+     * Returns the owner of the owner document handler
+     * as a value of &lt;java&gt; element.
+     *
+     * @return the owner of the owner document handler
+     */
+    private Object getValue() {
+        Object owner = getOwner().getOwner();
+        if ((this.type == null) || isValid(owner)) {
+            return owner;
+        }
+        if (owner instanceof XMLDecoder) {
+            XMLDecoder decoder = (XMLDecoder) owner;
+            owner = decoder.getOwner();
+            if (isValid(owner)) {
+                return owner;
+            }
+        }
+        throw new IllegalStateException("Unexpected owner class: " + owner.getClass().getName());
+    }
+
+    /**
+     * Validates the owner of the &lt;java&gt; element.
+     * The owner is valid if it is {@code null} or an instance
+     * of the class specified by the {@code class} attribute.
+     *
+     * @param owner  the owner of the &lt;java&gt; element
+     * @return {@code true} if the {@code owner} is valid;
+     *         {@code false} otherwise
+     */
+    private boolean isValid(Object owner) {
+        return (owner == null) || this.type.isInstance(owner);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/LongElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;long&gt; element.
+ * This element specifies {@code long} values.
+ * The class {@link Long} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;long&gt;0xFFFF&lt;/long&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="decode" class="java.lang.Long"&gt;
+ *     &lt;string&gt;0xFFFF&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Long.decode("0xFFFF")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class LongElementHandler extends StringElementHandler {
+
+    /**
+     * Creates {@code long} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code long} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        return Long.decode(argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/MethodElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import com.sun.beans.finder.MethodFinder;
+
+import java.lang.reflect.Method;
+
+/**
+ * This class is intended to handle &lt;method&gt; element.
+ * It describes invocation of the method.
+ * The {@code name} attribute denotes
+ * the name of the method to invoke.
+ * If the {@code class} attribute is specified
+ * this element invokes static method of specified class.
+ * The inner elements specifies the arguments of the method.
+ * For example:<pre>
+ * &lt;method name="valueOf" class="java.lang.Long"&gt;
+ *     &lt;string&gt;10&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * is equivalent to {@code Long.valueOf("10")} in Java code.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>name
+ * <dd>the method name
+ * <dt>class
+ * <dd>the type of object for instantiation
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class MethodElementHandler extends NewElementHandler {
+    private String name;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>name
+     * <dd>the method name
+     * <dt>class
+     * <dd>the type of object for instantiation
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("name")) { // NON-NLS: the attribute name
+            this.name = value;
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Returns the result of method execution.
+     *
+     * @param type  the base class
+     * @param args  the array of arguments
+     * @return the value of this element
+     * @throws Exception if calculation is failed
+     */
+    @Override
+    protected ValueObject getValueObject(Class<?> type, Object[] args) throws Exception {
+        Object bean = getContextBean();
+        Class<?>[] types = getArgumentTypes(args);
+        Method method = (type != null)
+                ? MethodFinder.findStaticMethod(type, this.name, types)
+                : MethodFinder.findMethod(bean.getClass(), this.name, types);
+
+        if (method.isVarArgs()) {
+            args = getArguments(args, method.getParameterTypes());
+        }
+        Object value = method.invoke(bean, args);
+        return method.getReturnType().equals(void.class)
+                ? ValueObjectImpl.VOID
+                : ValueObjectImpl.create(value);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/NewElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import com.sun.beans.finder.ConstructorFinder;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class is intended to handle &lt;new&gt; element.
+ * It describes instantiation of the object.
+ * The {@code class} attribute denotes
+ * the name of the class to instantiate.
+ * The inner elements specifies the arguments of the constructor.
+ * For example:<pre>
+ * &lt;new class="java.lang.Long"&gt;
+ *     &lt;string&gt;10&lt;/string&gt;
+ * &lt;/new&gt;</pre>
+ * is equivalent to {@code new Long("10")} in Java code.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>class
+ * <dd>the type of object for instantiation
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+class NewElementHandler extends ElementHandler {
+    private List<Object> arguments = new ArrayList<Object>();
+    private ValueObject value = ValueObjectImpl.VOID;
+
+    private Class<?> type;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>class
+     * <dd>the type of object for instantiation
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("class")) { // NON-NLS: the attribute name
+            this.type = getOwner().findClass(value);
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Adds the argument to the list of arguments
+     * that is used to calculate the value of this element.
+     *
+     * @param argument  the value of the element that contained in this one
+     */
+    @Override
+    protected final void addArgument(Object argument) {
+        if (this.arguments == null) {
+            throw new IllegalStateException("Could not add argument to evaluated element");
+        }
+        this.arguments.add(argument);
+    }
+
+    /**
+     * Returns the context of the method.
+     * The context of the static method is the class object.
+     * The context of the non-static method is the value of the parent element.
+     *
+     * @return the context of the method
+     */
+    @Override
+    protected final Object getContextBean() {
+        return (this.type != null)
+                ? this.type
+                : super.getContextBean();
+    }
+
+    /**
+     * Returns the value of this element.
+     *
+     * @return the value of this element
+     */
+    @Override
+    protected final ValueObject getValueObject() {
+        if (this.arguments != null) {
+            try {
+                this.value = getValueObject(this.type, this.arguments.toArray());
+            }
+            catch (Exception exception) {
+                getOwner().handleException(exception);
+            }
+            finally {
+                this.arguments = null;
+            }
+        }
+        return this.value;
+    }
+
+    /**
+     * Calculates the value of this element
+     * using the base class and the array of arguments.
+     * By default, it creates an instance of the base class.
+     * This method should be overridden in those handlers
+     * that extend behavior of this element.
+     *
+     * @param type  the base class
+     * @param args  the array of arguments
+     * @return the value of this element
+     * @throws Exception if calculation is failed
+     */
+    ValueObject getValueObject(Class<?> type, Object[] args) throws Exception {
+        if (type == null) {
+            throw new IllegalArgumentException("Class name is not set");
+        }
+        Class<?>[] types = getArgumentTypes(args);
+        Constructor<?> constructor = ConstructorFinder.findConstructor(type, types);
+        if (constructor.isVarArgs()) {
+            args = getArguments(args, constructor.getParameterTypes());
+        }
+        return ValueObjectImpl.create(constructor.newInstance(args));
+    }
+
+    /**
+     * Converts the array of arguments to the array of corresponding classes.
+     * If argument is {@code null} the class is {@code null} too.
+     *
+     * @param arguments  the array of arguments
+     * @return the array of corresponding classes
+     */
+    static Class<?>[] getArgumentTypes(Object[] arguments) {
+        Class<?>[] types = new Class<?>[arguments.length];
+        for (int i = 0; i < arguments.length; i++) {
+            if (arguments[i] != null) {
+                types[i] = arguments[i].getClass();
+            }
+        }
+        return types;
+    }
+
+    /**
+     * Resolves variable arguments.
+     *
+     * @param arguments  the array of arguments
+     * @param types      the array of parameter types
+     * @return the resolved array of arguments
+     */
+    static Object[] getArguments(Object[] arguments, Class<?>[] types) {
+        int index = types.length - 1;
+        if (types.length == arguments.length) {
+            Object argument = arguments[index];
+            if (argument == null) {
+                return arguments;
+            }
+            Class<?> type = types[index];
+            if (type.isAssignableFrom(argument.getClass())) {
+                return arguments;
+            }
+        }
+        int length = arguments.length - index;
+        Class<?> type = types[index].getComponentType();
+        Object array = Array.newInstance(type, length);
+        System.arraycopy(arguments, index, array, 0, length);
+
+        Object[] args = new Object[types.length];
+        System.arraycopy(arguments, 0, args, 0, index);
+        args[index] = array;
+        return args;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/NullElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;null&gt; element.
+ * This element specifies {@code null} value.
+ * It should not contain body or inner elements.
+ * For example:<pre>
+ * &lt;null/&gt;</pre>
+ * is equivalent to {@code null} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+class NullElementHandler extends ElementHandler implements ValueObject {
+
+    /**
+     * Returns the value of this element.
+     *
+     * @return the value of this element
+     */
+    @Override
+    protected final ValueObject getValueObject() {
+        return this;
+    }
+
+    /**
+     * Returns {@code null}
+     * as a value of &lt;null&gt; element.
+     * This method should be overridden in those handlers
+     * that extend behavior of this element.
+     *
+     * @return {@code null} by default
+     */
+    public Object getValue() {
+        return null;
+    }
+
+    /**
+     * Returns {@code void} state of this value object.
+     *
+     * @return {@code false} always
+     */
+    public final boolean isVoid() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/ObjectElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import java.beans.Expression;
+
+import static java.util.Locale.ENGLISH;
+
+/**
+ * This class is intended to handle &lt;object&gt; element.
+ * This element looks like &lt;void&gt; element,
+ * but its value is always used as an argument for element
+ * that contains this one.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>class
+ * <dd>the type is used for static methods and fields
+ * <dt>method
+ * <dd>the method name
+ * <dt>property
+ * <dd>the property name
+ * <dt>index
+ * <dd>the property index
+ * <dt>field
+ * <dd>the field name
+ * <dt>idref
+ * <dd>the identifier to refer to the variable
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+class ObjectElementHandler extends NewElementHandler {
+    private String idref;
+    private String field;
+    private Integer index;
+    private String property;
+    private String method;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>class
+     * <dd>the type is used for static methods and fields
+     * <dt>method
+     * <dd>the method name
+     * <dt>property
+     * <dd>the property name
+     * <dt>index
+     * <dd>the property index
+     * <dt>field
+     * <dd>the field name
+     * <dt>idref
+     * <dd>the identifier to refer to the variable
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public final void addAttribute(String name, String value) {
+        if (name.equals("idref")) { // NON-NLS: the attribute name
+            this.idref = value;
+        } else if (name.equals("field")) { // NON-NLS: the attribute name
+            this.field = value;
+        } else if (name.equals("index")) { // NON-NLS: the attribute name
+            this.index = Integer.valueOf(value);
+            addArgument(this.index); // hack for compatibility
+        } else if (name.equals("property")) { // NON-NLS: the attribute name
+            this.property = value;
+        } else if (name.equals("method")) { // NON-NLS: the attribute name
+            this.method = value;
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Calculates the value of this element
+     * if the field attribute or the idref attribute is set.
+     */
+    @Override
+    public final void startElement() {
+        if ((this.field != null) || (this.idref != null)) {
+            getValueObject();
+        }
+    }
+
+    /**
+     * Tests whether the value of this element can be used
+     * as an argument of the element that contained in this one.
+     *
+     * @return {@code true} if the value of this element can be used
+     *         as an argument of the element that contained in this one,
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isArgument() {
+        return true; // hack for compatibility
+    }
+
+    /**
+     * Creates the value of this element.
+     *
+     * @param type  the base class
+     * @param args  the array of arguments
+     * @return the value of this element
+     * @throws Exception if calculation is failed
+     */
+    @Override
+    protected final ValueObject getValueObject(Class<?> type, Object[] args) throws Exception {
+        if (this.field != null) {
+            return ValueObjectImpl.create(FieldElementHandler.getFieldValue(getContextBean(), this.field));
+        }
+        if (this.idref != null) {
+            return ValueObjectImpl.create(getVariable(this.idref));
+        }
+        Object bean = getContextBean();
+        String name;
+        if (this.index != null) {
+            name = (args.length == 2)
+                    ? PropertyElementHandler.SETTER
+                    : PropertyElementHandler.GETTER;
+        } else if (this.property != null) {
+            name = (args.length == 1)
+                    ? PropertyElementHandler.SETTER
+                    : PropertyElementHandler.GETTER;
+
+            if (0 < this.property.length()) {
+                name += this.property.substring(0, 1).toUpperCase(ENGLISH) + this.property.substring(1);
+            }
+        } else {
+            name = (this.method != null) && (0 < this.method.length())
+                    ? this.method
+                    : "new"; // NON-NLS: the constructor marker
+        }
+        Expression expression = new Expression(bean, name, args);
+        return ValueObjectImpl.create(expression.getValue());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/PropertyElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+import com.sun.beans.finder.MethodFinder;
+
+import java.beans.IndexedPropertyDescriptor;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * This class is intended to handle &lt;property&gt; element.
+ * This element simplifies access to the properties.
+ * If the {@code index} attribute is specified
+ * this element uses additional {@code int} parameter.
+ * If the {@code name} attribute is not specified
+ * this element uses method "get" as getter
+ * and method "set" as setter.
+ * This element defines getter if it contains no argument.
+ * It returns the value of the property in this case.
+ * For example:<pre>
+ * &lt;property name="object" index="10"/&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="getObject"&gt;
+ *     &lt;int&gt;10&lt;/int&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code getObject(10)} in Java code.
+ * This element defines setter if it contains one argument.
+ * It does not return the value of the property in this case.
+ * For example:<pre>
+ * &lt;property&gt;&lt;int&gt;0&lt;/int&gt;&lt;/property&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="set"&gt;
+ *     &lt;int&gt;0&lt;/int&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code set(0)} in Java code.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>name
+ * <dd>the property name
+ * <dt>index
+ * <dd>the property index
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class PropertyElementHandler extends AccessorElementHandler {
+    static final String GETTER = "get"; // NON-NLS: the getter prefix
+    static final String SETTER = "set"; // NON-NLS: the setter prefix
+
+    private Integer index;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>name
+     * <dd>the property name
+     * <dt>index
+     * <dd>the property index
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("index")) { // NON-NLS: the attribute name
+            this.index = Integer.valueOf(value);
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Tests whether the value of this element can be used
+     * as an argument of the element that contained in this one.
+     *
+     * @return {@code true} if the value of this element should be used
+     *         as an argument of the element that contained in this one,
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isArgument() {
+        return false; // non-static accessor cannot be used an argument
+    }
+
+    /**
+     * Returns the value of the property with specified {@code name}.
+     *
+     * @param name  the name of the property
+     * @return the value of the specified property
+     */
+    @Override
+    protected Object getValue(String name) {
+        try {
+            return getPropertyValue(getContextBean(), name, this.index);
+        }
+        catch (Exception exception) {
+            getOwner().handleException(exception);
+        }
+        return null;
+    }
+
+    /**
+     * Sets the new value for the property with specified {@code name}.
+     *
+     * @param name   the name of the property
+     * @param value  the new value for the specified property
+     */
+    @Override
+    protected void setValue(String name, Object value) {
+        try {
+            setPropertyValue(getContextBean(), name, this.index, value);
+        }
+        catch (Exception exception) {
+            getOwner().handleException(exception);
+        }
+    }
+
+    /**
+     * Performs the search of the getter for the property
+     * with specified {@code name} in specified class
+     * and returns value of the property.
+     *
+     * @param bean   the context bean that contains property
+     * @param name   the name of the property
+     * @param index  the index of the indexed property
+     * @return the value of the property
+     * @throws IllegalAccessException    if the property is not accesible
+     * @throws IntrospectionException    if the bean introspection is failed
+     * @throws InvocationTargetException if the getter cannot be invoked
+     * @throws NoSuchMethodException     if the getter is not found
+     */
+    private static Object getPropertyValue(Object bean, String name, Integer index) throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException {
+        Class<?> type = bean.getClass();
+        if (index == null) {
+            return findGetter(type, name).invoke(bean);
+        } else if (type.isArray() && (name == null)) {
+            return Array.get(bean, index);
+        } else {
+            return findGetter(type, name, int.class).invoke(bean, index);
+        }
+    }
+
+    /**
+     * Performs the search of the setter for the property
+     * with specified {@code name} in specified class
+     * and updates value of the property.
+     *
+     * @param bean   the context bean that contains property
+     * @param name   the name of the property
+     * @param index  the index of the indexed property
+     * @param value  the new value for the property
+     * @throws IllegalAccessException    if the property is not accesible
+     * @throws IntrospectionException    if the bean introspection is failed
+     * @throws InvocationTargetException if the setter cannot be invoked
+     * @throws NoSuchMethodException     if the setter is not found
+     */
+    private static void setPropertyValue(Object bean, String name, Integer index, Object value) throws IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException {
+        Class<?> type = bean.getClass();
+        Class<?> param = (value != null)
+                ? value.getClass()
+                : null;
+
+        if (index == null) {
+            findSetter(type, name, param).invoke(bean, value);
+        } else if (type.isArray() && (name == null)) {
+            Array.set(bean, index, value);
+        } else {
+            findSetter(type, name, int.class, param).invoke(bean, index, value);
+        }
+    }
+
+    /**
+     * Performs the search of the getter for the property
+     * with specified {@code name} in specified class.
+     *
+     * @param type  the class that contains method
+     * @param name  the name of the property
+     * @param args  the method arguments
+     * @return method object that represents found getter
+     * @throws IntrospectionException if the bean introspection is failed
+     * @throws NoSuchMethodException  if method is not found
+     */
+    private static Method findGetter(Class<?> type, String name, Class<?>...args) throws IntrospectionException, NoSuchMethodException {
+        if (name == null) {
+            return MethodFinder.findInstanceMethod(type, GETTER, args);
+        }
+        PropertyDescriptor pd = getProperty(type, name);
+        if (args.length == 0) {
+            Method method = pd.getReadMethod();
+            if (method != null) {
+                return method;
+            }
+        } else if (pd instanceof IndexedPropertyDescriptor) {
+            IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
+            Method method = ipd.getIndexedReadMethod();
+            if (method != null) {
+                return method;
+            }
+        }
+        throw new IntrospectionException("Could not find getter for the " + name + " property");
+    }
+
+    /**
+     * Performs the search of the setter for the property
+     * with specified {@code name} in specified class.
+     *
+     * @param type  the class that contains method
+     * @param name  the name of the property
+     * @param args  the method arguments
+     * @return method object that represents found setter
+     * @throws IntrospectionException if the bean introspection is failed
+     * @throws NoSuchMethodException  if method is not found
+     */
+    private static Method findSetter(Class<?> type, String name, Class<?>...args) throws IntrospectionException, NoSuchMethodException {
+        if (name == null) {
+            return MethodFinder.findInstanceMethod(type, SETTER, args);
+        }
+        PropertyDescriptor pd = getProperty(type, name);
+        if (args.length == 1) {
+            Method method = pd.getWriteMethod();
+            if (method != null) {
+                return method;
+            }
+        } else if (pd instanceof IndexedPropertyDescriptor) {
+            IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
+            Method method = ipd.getIndexedWriteMethod();
+            if (method != null) {
+                return method;
+            }
+        }
+        throw new IntrospectionException("Could not find setter for the " + name + " property");
+    }
+
+    /**
+     * Performs the search of the descriptor for the property
+     * with specified {@code name} in specified class.
+     *
+     * @param type  the class to introspect
+     * @param name  the property name
+     * @return descriptor for the named property
+     * @throws IntrospectionException if property descriptor is not found
+     */
+    private static PropertyDescriptor getProperty(Class<?> type, String name) throws IntrospectionException {
+        for (PropertyDescriptor pd : Introspector.getBeanInfo(type).getPropertyDescriptors()) {
+            if (name.equals(pd.getName())) {
+                return pd;
+            }
+        }
+        throw new IntrospectionException("Could not find the " + name + " property descriptor");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/ShortElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;short&gt; element.
+ * This element specifies {@code short} values.
+ * The class {@link Short} is used as wrapper for these values.
+ * The result value is created from text of the body of this element.
+ * The body parsing is described in the class {@link StringElementHandler}.
+ * For example:<pre>
+ * &lt;short&gt;200&lt;/short&gt;</pre>
+ * is shortcut to<pre>
+ * &lt;method name="decode" class="java.lang.Short"&gt;
+ *     &lt;string&gt;200&lt;/string&gt;
+ * &lt;/method&gt;</pre>
+ * which is equivalent to {@code Short.decode("200")} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class ShortElementHandler extends StringElementHandler {
+
+    /**
+     * Creates {@code short} value from
+     * the text of the body of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated {@code short} value
+     */
+    @Override
+    public Object getValue(String argument) {
+        return Short.decode(argument);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/StringElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;string&gt; element.
+ * This element specifies {@link String} values.
+ * The result value is created from text of the body of this element.
+ * For example:<pre>
+ * &lt;string&gt;description&lt;/string&gt;</pre>
+ * is equivalent to {@code "description"} in Java code.
+ * The value of inner element is calculated
+ * before adding to the string using {@link String#valueOf(Object)}.
+ * Note that all characters are used including whitespaces (' ', '\t', '\n', '\r').
+ * So the value of the element<pre>
+ * &lt;string&gt&lt;true&gt&lt;/string&gt;</pre>
+ * is not equal to the value of the element<pre>
+ * &lt;string&gt;
+ *     &lt;true&gt;
+ * &lt;/string&gt;</pre>
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+public class StringElementHandler extends ElementHandler {
+    private StringBuilder sb = new StringBuilder();
+    private ValueObject value = ValueObjectImpl.NULL;
+
+    /**
+     * Adds the character that contained in this element.
+     *
+     * @param ch  the character
+     */
+    @Override
+    public final void addCharacter(char ch) {
+        if (this.sb == null) {
+            throw new IllegalStateException("Could not add chararcter to evaluated string element");
+        }
+        this.sb.append(ch);
+    }
+
+    /**
+     * Adds the string value of the argument to the string value of this element.
+     *
+     * @param argument  the value of the element that contained in this one
+     */
+    @Override
+    protected final void addArgument(Object argument) {
+        if (this.sb == null) {
+            throw new IllegalStateException("Could not add argument to evaluated string element");
+        }
+        this.sb.append(argument);
+    }
+
+    /**
+     * Returns the value of this element.
+     *
+     * @return the value of this element
+     */
+    @Override
+    protected final ValueObject getValueObject() {
+        if (this.sb != null) {
+            try {
+                this.value = ValueObjectImpl.create(getValue(this.sb.toString()));
+            }
+            catch (RuntimeException exception) {
+                getOwner().handleException(exception);
+            }
+            finally {
+                this.sb = null;
+            }
+        }
+        return this.value;
+    }
+
+    /**
+     * Returns the text of the body of this element.
+     * This method evaluates value from text of the body,
+     * and should be overridden in those handlers
+     * that extend behavior of this element.
+     *
+     * @param argument  the text of the body
+     * @return evaluated value
+     */
+    protected Object getValue(String argument) {
+        return argument;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/TrueElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;true&gt; element.
+ * This element specifies {@code true} value.
+ * It should not contain body or inner elements.
+ * For example:<pre>
+ * &lt;true/&gt;</pre>
+ * is equivalent to {@code true} in Java code.
+ * <p>The following atribute is supported:
+ * <dl>
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class TrueElementHandler extends NullElementHandler {
+
+    /**
+     * Returns {@code Boolean.TRUE}
+     * as a value of &lt;true&gt; element.
+     *
+     * @return {@code Boolean.TRUE} by default
+     */
+    @Override
+    public Object getValue() {
+        return Boolean.TRUE;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/ValueObject.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This interface represents the result of method execution.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+public interface ValueObject {
+
+    /**
+     * Returns the result of method execution.
+     *
+     * @return the result of method execution
+     */
+    Object getValue();
+
+    /**
+     * Returns {@code void} state of this value object.
+     *
+     * @return {@code true} if value can be ignored,
+     *         {@code false} otherwise
+     */
+    boolean isVoid();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/ValueObjectImpl.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This utility class provides {@code static} method
+ * to create the object that contains the result of method execution.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class ValueObjectImpl implements ValueObject {
+    static final ValueObject NULL = new ValueObjectImpl(null);
+    static final ValueObject VOID = new ValueObjectImpl();
+
+    /**
+     * Returns the object that describes returning value.
+     *
+     * @param value  the result of method execution
+     * @return the object that describes value
+     */
+    static ValueObject create(Object value) {
+        return (value != null)
+                ? new ValueObjectImpl(value)
+                : NULL;
+    }
+
+    private Object value;
+    private boolean isVoid;
+
+    /**
+     * Creates the object that describes returning void value.
+     */
+    private ValueObjectImpl() {
+        this.isVoid = true;
+    }
+
+    /**
+     * Creates the object that describes returning non-void value.
+     *
+     * @param value  the result of method execution
+     */
+    private ValueObjectImpl(Object value) {
+        this.value = value;
+    }
+
+    /**
+     * Returns the result of method execution.
+     *
+     * @return the result of method execution
+     */
+    public Object getValue() {
+        return this.value;
+    }
+
+    /**
+     * Returns {@code void} state of this value object.
+     *
+     * @return {@code true} if value should be ignored,
+     *         {@code false} otherwise
+     */
+    public boolean isVoid() {
+        return this.isVoid;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/VarElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;var&gt; element.
+ * This element retrieves the value of specified variable.
+ * For example:<pre>
+ * &lt;var id="id1" idref="id2"/&gt;</pre>
+ * is equivalent to {@code id1 = id2} in Java code.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>idref
+ * <dd>the identifier to refer to the variable
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class VarElementHandler extends ElementHandler {
+    private ValueObject value;
+
+    /**
+     * Parses attributes of the element.
+     * The following atributes are supported:
+     * <dl>
+     * <dt>idref
+     * <dd>the identifier to refer to the variable
+     * <dt>id
+     * <dd>the identifier of the variable that is intended to store the result
+     * </dl>
+     *
+     * @param name   the attribute name
+     * @param value  the attribute value
+     */
+    @Override
+    public void addAttribute(String name, String value) {
+        if (name.equals("idref")) { // NON-NLS: the attribute name
+            this.value = ValueObjectImpl.create(getVariable(value));
+        } else {
+            super.addAttribute(name, value);
+        }
+    }
+
+    /**
+     * Returns the value of this element.
+     *
+     * @return the value of this element
+     */
+    @Override
+    protected ValueObject getValueObject() {
+        if (this.value == null) {
+            throw new IllegalArgumentException("Variable name is not set");
+        }
+        return this.value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/decoder/VoidElementHandler.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.decoder;
+
+/**
+ * This class is intended to handle &lt;void&gt; element.
+ * This element looks like &lt;object&gt; element,
+ * but its value is not used as an argument for element
+ * that contains this one.
+ * <p>The following atributes are supported:
+ * <dl>
+ * <dt>class
+ * <dd>the type is used for static methods and fields
+ * <dt>method
+ * <dd>the method name
+ * <dt>property
+ * <dd>the property name
+ * <dt>index
+ * <dd>the property index
+ * <dt>field
+ * <dd>the field name
+ * <dt>idref
+ * <dd>the identifier to refer to the variable
+ * <dt>id
+ * <dd>the identifier of the variable that is intended to store the result
+ * </dl>
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class VoidElementHandler extends ObjectElementHandler {
+
+    /**
+     * Tests whether the value of this element can be used
+     * as an argument of the element that contained in this one.
+     *
+     * @return {@code true} if the value of this element should be used
+     *         as an argument of the element that contained in this one,
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isArgument() {
+        return false; // hack for compatibility
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/finder/AbstractFinder.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.finder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This abstract class provides functionality
+ * to find a public method or constructor
+ * with specified parameter types.
+ * It supports a variable number of parameters.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+abstract class AbstractFinder<T> {
+    private final Class<?>[] args;
+
+    /**
+     * Creates finder for array of classes of arguments.
+     * If a particular element of array equals {@code null},
+     * than the appropriate pair of classes
+     * does not take into consideration.
+     *
+     * @param args  array of classes of arguments
+     */
+    protected AbstractFinder(Class<?>[] args) {
+        this.args = args;
+    }
+
+    /**
+     * Returns an array of {@code Class} objects
+     * that represent the formal parameter types of the method
+     * Returns an empty array if the method takes no parameters.
+     *
+     * @param method  the object that represents method
+     * @return the parameter types of the method
+     */
+    protected abstract Class<?>[] getParameters(T method);
+
+    /**
+     * Returns {@code true} if and only if the method
+     * was declared to take a variable number of arguments.
+     *
+     * @param method  the object that represents method
+     * @return {@code true} if the method was declared
+     *         to take a variable number of arguments;
+     *         {@code false} otherwise
+     */
+    protected abstract boolean isVarArgs(T method);
+
+    /**
+     * Checks validness of the method.
+     * At least the valid method should be public.
+     *
+     * @param method  the object that represents method
+     * @return {@code true} if the method is valid,
+     *         {@code false} otherwise
+     */
+    protected abstract boolean isValid(T method);
+
+    /**
+     * Performs a search in the {@code methods} array.
+     * The one method is selected from the array of the valid methods.
+     * The list of parameters of the selected method shows
+     * the best correlation with the list of arguments
+     * specified at class initialization.
+     * If more than one method is both accessible and applicable
+     * to a method invocation, it is necessary to choose one
+     * to provide the descriptor for the run-time method dispatch.
+     * The most specific method should be chosen.
+     *
+     * @param methods  the array of methods to search within
+     * @return the object that represents found method
+     * @throws NoSuchMethodException if no method was found or several
+     *                               methods meet the search criteria
+     * @see #isAssignable
+     */
+    final T find(T[] methods) throws NoSuchMethodException {
+        Map<T, Class<?>[]> map = new HashMap<T, Class<?>[]>();
+
+        T oldMethod = null;
+        Class<?>[] oldParams = null;
+        boolean ambiguous = false;
+
+        for (T newMethod : methods) {
+            if (isValid(newMethod)) {
+                Class<?>[] newParams = getParameters(newMethod);
+                if (newParams.length == this.args.length) {
+                    PrimitiveWrapperMap.replacePrimitivesWithWrappers(newParams);
+                    if (isAssignable(newParams, this.args)) {
+                        if (oldMethod == null) {
+                            oldMethod = newMethod;
+                            oldParams = newParams;
+                        } else {
+                            boolean useNew = isAssignable(oldParams, newParams);
+                            boolean useOld = isAssignable(newParams, oldParams);
+
+                            if (useOld == useNew) {
+                                ambiguous = true;
+                            } else if (useNew) {
+                                oldMethod = newMethod;
+                                oldParams = newParams;
+                                ambiguous = false;
+                            }
+                        }
+                    }
+                }
+                if (isVarArgs(newMethod)) {
+                    int length = newParams.length - 1;
+                    if (length <= this.args.length) {
+                        Class<?>[] array = new Class<?>[this.args.length];
+                        System.arraycopy(newParams, 0, array, 0, length);
+                        if (length < this.args.length) {
+                            Class<?> type = newParams[length].getComponentType();
+                            if (type.isPrimitive()) {
+                                type = PrimitiveWrapperMap.getType(type.getName());
+                            }
+                            for (int i = length; i < this.args.length; i++) {
+                                array[i] = type;
+                            }
+                        }
+                        map.put(newMethod, array);
+                    }
+                }
+            }
+        }
+        for (T newMethod : methods) {
+            Class<?>[] newParams = map.get(newMethod);
+            if (newParams != null) {
+                if (isAssignable(newParams, this.args)) {
+                    if (oldMethod == null) {
+                        oldMethod = newMethod;
+                        oldParams = newParams;
+                    } else {
+                        boolean useNew = isAssignable(oldParams, newParams);
+                        boolean useOld = isAssignable(newParams, oldParams);
+
+                        if (useOld == useNew) {
+                            if (oldParams == map.get(oldMethod)) {
+                                ambiguous = true;
+                            }
+                        } else if (useNew) {
+                            oldMethod = newMethod;
+                            oldParams = newParams;
+                            ambiguous = false;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (ambiguous) {
+            throw new NoSuchMethodException("Ambiguous methods are found");
+        }
+        if (oldMethod == null) {
+            throw new NoSuchMethodException("Method is not found");
+        }
+        return oldMethod;
+    }
+
+    /**
+     * Determines if every class in {@code min} array is either the same as,
+     * or is a superclass of, the corresponding class in {@code max} array.
+     * The length of every array must equal the number of arguments.
+     * This comparison is performed in the {@link #find} method
+     * before the first call of the isAssignable method.
+     * If an argument equals {@code null}
+     * the appropriate pair of classes does not take into consideration.
+     *
+     * @param min  the array of classes to be checked
+     * @param max  the array of classes that is used to check
+     * @return {@code true} if all classes in {@code min} array
+     *         are assignable from corresponding classes in {@code max} array,
+     *         {@code false} otherwise
+     *
+     * @see Class#isAssignableFrom
+     */
+    private boolean isAssignable(Class<?>[] min, Class<?>[] max) {
+        for (int i = 0; i < this.args.length; i++) {
+            if (null != this.args[i]) {
+                if (!min[i].isAssignableFrom(max[i])) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+}
--- a/src/share/classes/com/sun/beans/finder/ClassFinder.java	Thu Nov 27 17:55:36 2008 +0300
+++ b/src/share/classes/com/sun/beans/finder/ClassFinder.java	Mon Dec 22 17:42:49 2008 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2006-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
 package com.sun.beans.finder;
 
 /**
- * This is utility class that provides <code>static</code> methods
+ * This is utility class that provides {@code static} methods
  * to find a class with the specified name using the specified class loader.
  *
  * @since 1.7
@@ -33,137 +33,138 @@
  * @author Sergey A. Malenkov
  */
 public final class ClassFinder {
+
     /**
-     * Returns the <code>Class</code> object associated
+     * Returns the {@code Class} object associated
      * with the class or interface with the given string name,
      * using the default class loader.
      * <p>
-     * The <code>name</code> can denote an array class
+     * The {@code name} can denote an array class
      * (see {@link Class#getName} for details).
      *
      * @param name  fully qualified name of the desired class
      * @return class object representing the desired class
      *
-     * @exception ClassNotFoundException  if the class cannot be located
-     *                                    by the specified class loader
+     * @throws ClassNotFoundException  if the class cannot be located
+     *                                 by the specified class loader
      *
      * @see Class#forName(String)
      * @see Class#forName(String,boolean,ClassLoader)
      * @see ClassLoader#getSystemClassLoader()
      * @see Thread#getContextClassLoader()
      */
-    public static Class findClass( String name ) throws ClassNotFoundException {
+    public static Class<?> findClass(String name) throws ClassNotFoundException {
         try {
             ClassLoader loader = Thread.currentThread().getContextClassLoader();
-            if ( loader == null ) {
+            if (loader == null) {
                 // can be null in IE (see 6204697)
                 loader = ClassLoader.getSystemClassLoader();
             }
-            if ( loader != null ) {
-                return Class.forName( name, false, loader );
+            if (loader != null) {
+                return Class.forName(name, false, loader);
             }
 
-        } catch ( ClassNotFoundException exception ) {
+        } catch (ClassNotFoundException exception) {
             // use current class loader instead
-        } catch ( SecurityException exception ) {
+        } catch (SecurityException exception) {
             // use current class loader instead
         }
-        return Class.forName( name );
+        return Class.forName(name);
     }
 
     /**
-     * Returns the <code>Class</code> object associated with
+     * Returns the {@code Class} object associated with
      * the class or interface with the given string name,
      * using the given class loader.
      * <p>
-     * The <code>name</code> can denote an array class
+     * The {@code name} can denote an array class
      * (see {@link Class#getName} for details).
      * <p>
-     * If the parameter <code>loader</code> is null,
+     * If the parameter {@code loader} is null,
      * the class is loaded through the default class loader.
      *
      * @param name    fully qualified name of the desired class
      * @param loader  class loader from which the class must be loaded
      * @return class object representing the desired class
      *
-     * @exception ClassNotFoundException  if the class cannot be located
-     *                                    by the specified class loader
+     * @throws ClassNotFoundException  if the class cannot be located
+     *                                 by the specified class loader
      *
      * @see #findClass(String,ClassLoader)
      * @see Class#forName(String,boolean,ClassLoader)
      */
-    public static Class findClass( String name, ClassLoader loader ) throws ClassNotFoundException {
-        if ( loader != null ) {
+    public static Class<?> findClass(String name, ClassLoader loader) throws ClassNotFoundException {
+        if (loader != null) {
             try {
-                return Class.forName( name, false, loader );
-            } catch ( ClassNotFoundException exception ) {
+                return Class.forName(name, false, loader);
+            } catch (ClassNotFoundException exception) {
                 // use default class loader instead
-            } catch ( SecurityException exception ) {
+            } catch (SecurityException exception) {
                 // use default class loader instead
             }
         }
-        return findClass( name );
+        return findClass(name);
     }
 
     /**
-     * Returns the <code>Class</code> object associated
+     * Returns the {@code Class} object associated
      * with the class or interface with the given string name,
      * using the default class loader.
      * <p>
-     * The <code>name</code> can denote an array class
+     * The {@code name} can denote an array class
      * (see {@link Class#getName} for details).
      * <p>
      * This method can be used to obtain
-     * any of the <code>Class</code> objects
-     * representing <code>void</code> or primitive Java types:
-     * <code>char</code>, <code>byte</code>, <code>short</code>,
-     * <code>int</code>, <code>long</code>, <code>float</code>,
-     * <code>double</code> and <code>boolean</code>.
+     * any of the {@code Class} objects
+     * representing {@code void} or primitive Java types:
+     * {@code char}, {@code byte}, {@code short},
+     * {@code int}, {@code long}, {@code float},
+     * {@code double} and {@code boolean}.
      *
      * @param name  fully qualified name of the desired class
      * @return class object representing the desired class
      *
-     * @exception ClassNotFoundException  if the class cannot be located
-     *                                    by the specified class loader
+     * @throws ClassNotFoundException  if the class cannot be located
+     *                                 by the specified class loader
      *
      * @see #resolveClass(String,ClassLoader)
      */
-    public static Class resolveClass( String name ) throws ClassNotFoundException {
-        return resolveClass( name, null );
+    public static Class<?> resolveClass(String name) throws ClassNotFoundException {
+        return resolveClass(name, null);
     }
 
     /**
-     * Returns the <code>Class</code> object associated with
+     * Returns the {@code Class} object associated with
      * the class or interface with the given string name,
      * using the given class loader.
      * <p>
-     * The <code>name</code> can denote an array class
+     * The {@code name} can denote an array class
      * (see {@link Class#getName} for details).
      * <p>
-     * If the parameter <code>loader</code> is null,
+     * If the parameter {@code loader} is null,
      * the class is loaded through the default class loader.
      * <p>
      * This method can be used to obtain
-     * any of the <code>Class</code> objects
-     * representing <code>void</code> or primitive Java types:
-     * <code>char</code>, <code>byte</code>, <code>short</code>,
-     * <code>int</code>, <code>long</code>, <code>float</code>,
-     * <code>double</code> and <code>boolean</code>.
+     * any of the {@code Class} objects
+     * representing {@code void} or primitive Java types:
+     * {@code char}, {@code byte}, {@code short},
+     * {@code int}, {@code long}, {@code float},
+     * {@code double} and {@code boolean}.
      *
      * @param name    fully qualified name of the desired class
      * @param loader  class loader from which the class must be loaded
      * @return class object representing the desired class
      *
-     * @exception ClassNotFoundException  if the class cannot be located
-     *                                    by the specified class loader
+     * @throws ClassNotFoundException  if the class cannot be located
+     *                                 by the specified class loader
      *
      * @see #findClass(String,ClassLoader)
      * @see PrimitiveTypeMap#getType(String)
      */
-    public static Class resolveClass( String name, ClassLoader loader ) throws ClassNotFoundException {
-        Class type = PrimitiveTypeMap.getType( name );
-        return ( type == null )
-                ? findClass( name, loader )
+    public static Class<?> resolveClass(String name, ClassLoader loader) throws ClassNotFoundException {
+        Class<?> type = PrimitiveTypeMap.getType(name);
+        return (type == null)
+                ? findClass(name, loader)
                 : type;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/finder/ConstructorFinder.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.finder;
+
+import com.sun.beans.WeakCache;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+
+/**
+ * This utility class provides {@code static} methods
+ * to find a public constructor with specified parameter types
+ * in specified class.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+public final class ConstructorFinder extends AbstractFinder<Constructor<?>> {
+    private static final WeakCache<Signature, Constructor<?>> CACHE = new WeakCache<Signature, Constructor<?>>();
+
+    /**
+     * Finds public constructor
+     * that is declared in public class.
+     *
+     * @param type  the class that can have constructor
+     * @param args  parameter types that is used to find constructor
+     * @return object that represents found constructor
+     * @throws NoSuchMethodException if constructor could not be found
+     *                               or some constructors are found
+     */
+    public static Constructor<?> findConstructor(Class<?> type, Class<?>...args) throws NoSuchMethodException {
+        if (type.isPrimitive()) {
+            throw new NoSuchMethodException("Primitive wrapper does not contain constructors");
+        }
+        if (type.isInterface()) {
+            throw new NoSuchMethodException("Interface does not contain constructors");
+        }
+        if (Modifier.isAbstract(type.getModifiers())) {
+            throw new NoSuchMethodException("Abstract class cannot be instantiated");
+        }
+        if (!Modifier.isPublic(type.getModifiers())) {
+            throw new NoSuchMethodException("Class is not accessible");
+        }
+        PrimitiveWrapperMap.replacePrimitivesWithWrappers(args);
+        Signature signature = new Signature(type, args);
+
+        Constructor<?> constructor = CACHE.get(signature);
+        if (constructor != null) {
+            return constructor;
+        }
+        constructor = new ConstructorFinder(args).find(type.getConstructors());
+        CACHE.put(signature, constructor);
+        return constructor;
+    }
+
+    /**
+     * Creates constructor finder with specified array of parameter types.
+     *
+     * @param args  the array of parameter types
+     */
+    private ConstructorFinder(Class<?>[] args) {
+        super(args);
+    }
+
+    /**
+     * Returns an array of {@code Class} objects
+     * that represent the formal parameter types of the constructor
+     * Returns an empty array if the constructor takes no parameters.
+     *
+     * @param constructor  the object that represents constructor
+     * @return the parameter types of the constructor
+     */
+    @Override
+    protected Class<?>[] getParameters(Constructor<?> constructor) {
+        return constructor.getParameterTypes();
+    }
+
+    /**
+     * Returns {@code true} if and only if the constructor
+     * was declared to take a variable number of arguments.
+     *
+     * @param constructor  the object that represents constructor
+     * @return {@code true} if the constructor was declared
+     *         to take a variable number of arguments;
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isVarArgs(Constructor<?> constructor) {
+        return constructor.isVarArgs();
+    }
+
+    /**
+     * Checks validness of the constructor.
+     * The valid constructor should be public.
+     *
+     * @param constructor  the object that represents constructor
+     * @return {@code true} if the constructor is valid,
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isValid(Constructor<?> constructor) {
+        return Modifier.isPublic(constructor.getModifiers());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/finder/FieldFinder.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.finder;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+/**
+ * This utility class provides {@code static} methods
+ * to find a public field with specified name
+ * in specified class.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+public final class FieldFinder {
+
+    /**
+     * Finds public field (static or non-static)
+     * that is declared in public class.
+     *
+     * @param type  the class that can have field
+     * @param name  the name of field to find
+     * @return object that represents found field
+     * @throws NoSuchFieldException if field is not found
+     * @see Class#getField
+     */
+    public static Field findField(Class<?> type, String name) throws NoSuchFieldException {
+        if (name == null) {
+            throw new IllegalArgumentException("Field name is not set");
+        }
+        Field field = type.getField(name);
+        if (!Modifier.isPublic(field.getModifiers())) {
+            throw new NoSuchFieldException("Field '" + name + "' is not public");
+        }
+        if (!Modifier.isPublic(field.getDeclaringClass().getModifiers())) {
+            throw new NoSuchFieldException("Field '" + name + "' is not accessible");
+        }
+        return field;
+    }
+
+    /**
+     * Finds public non-static field
+     * that is declared in public class.
+     *
+     * @param type  the class that can have field
+     * @param name  the name of field to find
+     * @return object that represents found field
+     * @throws NoSuchFieldException if field is not found
+     * @see Class#getField
+     */
+    public static Field findInstanceField(Class<?> type, String name) throws NoSuchFieldException {
+        Field field = findField(type, name);
+        if (Modifier.isStatic(field.getModifiers())) {
+            throw new NoSuchFieldException("Field '" + name + "' is static");
+        }
+        return field;
+    }
+
+    /**
+     * Finds public static field
+     * that is declared in public class.
+     *
+     * @param type  the class that can have field
+     * @param name  the name of field to find
+     * @return object that represents found field
+     * @throws NoSuchFieldException if field is not found
+     * @see Class#getField
+     */
+    public static Field findStaticField(Class<?> type, String name) throws NoSuchFieldException {
+        Field field = findField(type, name);
+        if (!Modifier.isStatic(field.getModifiers())) {
+            throw new NoSuchFieldException("Field '" + name + "' is not static");
+        }
+        return field;
+    }
+
+    /**
+     * Disable instantiation.
+     */
+    private FieldFinder() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/finder/MethodFinder.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.finder;
+
+import com.sun.beans.WeakCache;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * This utility class provides {@code static} methods
+ * to find a public method with specified name and parameter types
+ * in specified class.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+public final class MethodFinder extends AbstractFinder<Method> {
+    private static final WeakCache<Signature, Method> CACHE = new WeakCache<Signature, Method>();
+
+    /**
+     * Finds public method (static or non-static)
+     * that is accessible from public class.
+     *
+     * @param type  the class that can have method
+     * @param name  the name of method to find
+     * @param args  parameter types that is used to find method
+     * @return object that represents found method
+     * @throws NoSuchMethodException if method could not be found
+     *                               or some methods are found
+     */
+    public static Method findMethod(Class<?> type, String name, Class<?>...args) throws NoSuchMethodException {
+        if (name == null) {
+            throw new IllegalArgumentException("Method name is not set");
+        }
+        PrimitiveWrapperMap.replacePrimitivesWithWrappers(args);
+        Signature signature = new Signature(type, name, args);
+
+        Method method = CACHE.get(signature);
+        if (method != null) {
+            return method;
+        }
+        method = findAccessibleMethod(new MethodFinder(name, args).find(type.getMethods()));
+        CACHE.put(signature, method);
+        return method;
+    }
+
+    /**
+     * Finds public non-static method
+     * that is accessible from public class.
+     *
+     * @param type  the class that can have method
+     * @param name  the name of method to find
+     * @param args  parameter types that is used to find method
+     * @return object that represents found method
+     * @throws NoSuchMethodException if method could not be found
+     *                               or some methods are found
+     */
+    public static Method findInstanceMethod(Class<?> type, String name, Class<?>... args) throws NoSuchMethodException {
+        Method method = findMethod(type, name, args);
+        if (Modifier.isStatic(method.getModifiers())) {
+            throw new NoSuchMethodException("Method '" + name + "' is static");
+        }
+        return method;
+    }
+
+    /**
+     * Finds public static method
+     * that is accessible from public class.
+     *
+     * @param type  the class that can have method
+     * @param name  the name of method to find
+     * @param args  parameter types that is used to find method
+     * @return object that represents found method
+     * @throws NoSuchMethodException if method could not be found
+     *                               or some methods are found
+     */
+    public static Method findStaticMethod(Class<?> type, String name, Class<?>...args) throws NoSuchMethodException {
+        Method method = findMethod(type, name, args);
+        if (!Modifier.isStatic(method.getModifiers())) {
+            throw new NoSuchMethodException("Method '" + name + "' is not static");
+        }
+        return method;
+    }
+
+    /**
+     * Finds method that is accessible from public class or interface through class hierarchy.
+     *
+     * @param method  object that represents found method
+     * @return object that represents accessible method
+     * @throws NoSuchMethodException if method is not accessible or is not found
+     *                               in specified superclass or interface
+     */
+    private static Method findAccessibleMethod(Method method) throws NoSuchMethodException {
+        Class<?> type = method.getDeclaringClass();
+        if (Modifier.isPublic(type.getModifiers())) {
+            return method;
+        }
+        if (Modifier.isStatic(method.getModifiers())) {
+            throw new NoSuchMethodException("Method '" + method.getName() + "' is not accessible");
+        }
+        for (Class<?> face : type.getInterfaces()) {
+            try {
+                return findAccessibleMethod(method, face);
+            }
+            catch (NoSuchMethodException exception) {
+                // try to find in superclass or another interface
+            }
+        }
+        return findAccessibleMethod(method, type.getSuperclass());
+    }
+
+    /**
+     * Finds method that accessible from specified class.
+     *
+     * @param method  object that represents found method
+     * @param type    class that is used to find accessible method
+     * @return object that represents accessible method
+     * @throws NoSuchMethodException if method is not accessible or is not found
+     *                               in specified superclass or interface
+     */
+    private static Method findAccessibleMethod(Method method, Class<?> type) throws NoSuchMethodException {
+        String name = method.getName();
+        Class<?>[] params = method.getParameterTypes();
+        return findAccessibleMethod(type.getMethod(name, params));
+    }
+
+
+    private final String name;
+
+    /**
+     * Creates method finder with specified array of parameter types.
+     *
+     * @param name  the name of method to find
+     * @param args  the array of parameter types
+     */
+    private MethodFinder(String name, Class<?>[] args) {
+        super(args);
+        this.name = name;
+    }
+
+    /**
+     * Returns an array of {@code Class} objects
+     * that represent the formal parameter types of the method
+     * Returns an empty array if the method takes no parameters.
+     *
+     * @param method  the object that represents method
+     * @return the parameter types of the method
+     */
+    @Override
+    protected Class<?>[] getParameters(Method method) {
+        return method.getParameterTypes();
+    }
+
+    /**
+     * Returns {@code true} if and only if the method
+     * was declared to take a variable number of arguments.
+     *
+     * @param method  the object that represents method
+     * @return {@code true} if the method was declared
+     *         to take a variable number of arguments;
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isVarArgs(Method method) {
+        return method.isVarArgs();
+    }
+
+    /**
+     * Checks validness of the method.
+     * The valid method should be public and
+     * should have the specified name.
+     *
+     * @param method  the object that represents method
+     * @return {@code true} if the method is valid,
+     *         {@code false} otherwise
+     */
+    @Override
+    protected boolean isValid(Method method) {
+        return Modifier.isPublic(method.getModifiers()) && method.getName().equals(this.name);
+    }
+}
--- a/src/share/classes/com/sun/beans/finder/PrimitiveTypeMap.java	Thu Nov 27 17:55:36 2008 +0300
+++ b/src/share/classes/com/sun/beans/finder/PrimitiveTypeMap.java	Mon Dec 22 17:42:49 2008 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2006-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,29 +36,30 @@
  * @author Sergey A. Malenkov
  */
 final class PrimitiveTypeMap {
+
     /**
      * Returns primitive type class by its name.
      *
      * @param name  the name of primitive type
      * @return found primitive type class,
-     *         or <code>null</code> if not found
+     *         or {@code null} if not found
      */
-    static Class getType( String name ) {
-        return map.get( name );
+    static Class<?> getType(String name) {
+        return map.get(name);
     }
 
-    private static final Map<String, Class> map = new HashMap<String, Class>( 9 );
+    private static final Map<String, Class<?>> map = new HashMap<String, Class<?>>(9);
 
     static {
-        map.put( boolean.class.getName(), boolean.class );
-        map.put( char.class.getName(), char.class );
-        map.put( byte.class.getName(), byte.class );
-        map.put( short.class.getName(), short.class );
-        map.put( int.class.getName(), int.class );
-        map.put( long.class.getName(), long.class );
-        map.put( float.class.getName(), float.class );
-        map.put( double.class.getName(), double.class );
-        map.put( void.class.getName(), void.class );
+        map.put(boolean.class.getName(), boolean.class);
+        map.put(char.class.getName(), char.class);
+        map.put(byte.class.getName(), byte.class);
+        map.put(short.class.getName(), short.class);
+        map.put(int.class.getName(), int.class);
+        map.put(long.class.getName(), long.class);
+        map.put(float.class.getName(), float.class);
+        map.put(double.class.getName(), double.class);
+        map.put(void.class.getName(), void.class);
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/finder/PrimitiveWrapperMap.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.finder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This utility class associates
+ * name of primitive type with appropriate wrapper.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+public final class PrimitiveWrapperMap {
+
+    /**
+     * Replaces all primitive types in specified array with wrappers.
+     *
+     * @param types  array of classes where all primitive types
+     *               will be replaced by appropriate wrappers
+     */
+    static void replacePrimitivesWithWrappers(Class<?>[] types) {
+        for (int i = 0; i < types.length; i++) {
+            if (types[i] != null) {
+                if (types[i].isPrimitive()) {
+                    types[i] = getType(types[i].getName());
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns wrapper for primitive type by its name.
+     *
+     * @param name  the name of primitive type
+     * @return found wrapper for primitive type,
+     *         or {@code null} if not found
+     */
+    public static Class<?> getType(String name) {
+        return map.get(name);
+    }
+
+    private static final Map<String, Class<?>> map = new HashMap<String, Class<?>>(9);
+
+    static {
+        map.put(Boolean.TYPE.getName(), Boolean.class);
+        map.put(Character.TYPE.getName(), Character.class);
+        map.put(Byte.TYPE.getName(), Byte.class);
+        map.put(Short.TYPE.getName(), Short.class);
+        map.put(Integer.TYPE.getName(), Integer.class);
+        map.put(Long.TYPE.getName(), Long.class);
+        map.put(Float.TYPE.getName(), Float.class);
+        map.put(Double.TYPE.getName(), Double.class);
+        map.put(Void.TYPE.getName(), Void.class);
+    }
+
+    /**
+     * Disable instantiation.
+     */
+    private PrimitiveWrapperMap() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/beans/finder/Signature.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.beans.finder;
+
+/**
+ * This class is designed to be a key of a cache
+ * of constructors or methods.
+ *
+ * @since 1.7
+ *
+ * @author Sergey A. Malenkov
+ */
+final class Signature {
+    private final Class<?> type;
+    private final String name;
+    private final Class<?>[] args;
+
+    private volatile int code;
+
+    /**
+     * Constructs signature for constructor.
+     *
+     * @param type  the class that contains constructor
+     * @param args  the types of constructor's parameters
+     */
+    Signature(Class<?> type, Class<?>[] args) {
+        this(type, null, args);
+    }
+
+    /**
+     * Constructs signature for method.
+     *
+     * @param type  the class that contains method
+     * @param name  the name of the method
+     * @param args  the types of method's parameters
+     */
+    Signature(Class<?> type, String name, Class<?>[] args) {
+        this.type = type;
+        this.name = name;
+        this.args = args;
+    }
+
+    /**
+     * Indicates whether some other object is "equal to" this one.
+     *
+     * @param object  the reference object with which to compare
+     * @return {@code true} if this object is the same as the
+     *         {@code object} argument, {@code false} otherwise
+     * @see #hashCode()
+     */
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (object instanceof Signature) {
+            Signature signature = (Signature) object;
+            return isEqual(signature.type, this.type)
+                && isEqual(signature.name, this.name)
+                && isEqual(signature.args, this.args);
+        }
+        return false;
+    }
+
+    /**
+     * Indicates whether some object is "equal to" another one.
+     * This method supports {@code null} values.
+     *
+     * @param obj1  the first reference object that will compared
+     * @param obj2  the second reference object that will compared
+     * @return {@code true} if first object is the same as the second object,
+     *         {@code false} otherwise
+     */
+    private static boolean isEqual(Object obj1, Object obj2) {
+        return (obj1 == null)
+                ? obj2 == null
+                : obj1.equals(obj2);
+    }
+
+    /**
+     * Indicates whether some array is "equal to" another one.
+     * This method supports {@code null} values.
+     *
+     * @param args1 the first reference array that will compared
+     * @param args2 the second reference array that will compared
+     * @return {@code true} if first array is the same as the second array,
+     *         {@code false} otherwise
+     */
+    private static boolean isEqual(Class<?>[] args1, Class<?>[] args2) {
+        if ((args1 == null) || (args2 == null)) {
+            return args1 == args2;
+        }
+        if (args1.length != args2.length) {
+            return false;
+        }
+        for (int i = 0; i < args1.length; i++) {
+            if (!isEqual(args1[i], args2[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns a hash code value for the object.
+     * This method is supported for the benefit of hashtables
+     * such as {@link java.util.HashMap} or {@link java.util.HashSet}.
+     * Hash code computed using algorithm
+     * suggested in Effective Java, Item 8.
+     *
+     * @return a hash code value for this object
+     * @see #equals(Object)
+     */
+    @Override
+    public int hashCode() {
+        if (this.code == 0) {
+            int code = 17;
+            code = addHashCode(code, this.type);
+            code = addHashCode(code, this.name);
+
+            if (this.args != null) {
+                for (Class<?> arg : this.args) {
+                    code = addHashCode(code, arg);
+                }
+            }
+            this.code = code;
+        }
+        return this.code;
+    }
+
+    /**
+     * Adds hash code value if specified object.
+     * This is a part of the algorithm
+     * suggested in Effective Java, Item 8.
+     *
+     * @param code    current hash code value
+     * @param object  object that updates hash code value
+     * @return updated hash code value
+     * @see #hashCode()
+     */
+    private static int addHashCode(int code, Object object) {
+        code *= 37;
+        return (object != null)
+                ? code + object.hashCode()
+                : code;
+    }
+}
--- a/src/share/classes/java/beans/MetaData.java	Thu Nov 27 17:55:36 2008 +0300
+++ b/src/share/classes/java/beans/MetaData.java	Mon Dec 22 17:42:49 2008 +0300
@@ -24,6 +24,8 @@
  */
 package java.beans;
 
+import com.sun.beans.finder.PrimitiveWrapperMap;
+
 import java.awt.AWTKeyStroke;
 import java.awt.BorderLayout;
 import java.awt.Dimension;
@@ -204,7 +206,7 @@
         if (c.isPrimitive()) {
             Field field = null;
             try {
-                field = ReflectionUtils.typeToClass(c).getDeclaredField("TYPE");
+                field = PrimitiveWrapperMap.getType(c.getName()).getDeclaredField("TYPE");
             } catch (NoSuchFieldException ex) {
                 System.err.println("Unknown primitive type: " + c);
             }
--- a/src/share/classes/java/beans/ReflectionUtils.java	Thu Nov 27 17:55:36 2008 +0300
+++ b/src/share/classes/java/beans/ReflectionUtils.java	Mon Dec 22 17:42:49 2008 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,8 @@
  */
 package java.beans;
 
+import com.sun.beans.finder.PrimitiveWrapperMap;
+
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
@@ -34,7 +36,6 @@
 
 import java.util.*;
 
-import com.sun.beans.ObjectHandler;
 import sun.reflect.misc.MethodUtil;
 import sun.reflect.misc.ConstructorUtil;
 import sun.reflect.misc.ReflectUtil;
@@ -47,10 +48,6 @@
 
     private static Reference methodCacheRef;
 
-    public static Class typeToClass(Class type) {
-        return type.isPrimitive() ? ObjectHandler.typeNameToClass(type.getName()) : type;
-    }
-
     public static boolean isPrimitive(Class type) {
         return primitiveTypeFor(type) != null;
     }
@@ -99,7 +96,7 @@
         for(int j = 0; j < argClasses.length && match; j++) {
             Class argType = argTypes[j];
             if (argType.isPrimitive()) {
-                argType = typeToClass(argType);
+                argType = PrimitiveWrapperMap.getType(argType.getName());
             }
             if (explicit) {
                 // Test each element for equality
@@ -210,7 +207,7 @@
             for (int i = 0; i < args.length; i++) {
                 Class mArg = mArgs[i];
                 if (mArg.isPrimitive()) {
-                    mArg = typeToClass(mArg);
+                    mArg = PrimitiveWrapperMap.getType(mArg.getName());
                 }
                 if (args[i] == mArg) {
                     matches++;
--- a/src/share/classes/java/beans/XMLDecoder.java	Thu Nov 27 17:55:36 2008 +0300
+++ b/src/share/classes/java/beans/XMLDecoder.java	Mon Dec 22 17:42:49 2008 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,19 +24,14 @@
  */
 package java.beans;
 
-import com.sun.beans.ObjectHandler;
+import com.sun.beans.decoder.DocumentHandler;
 
+import java.io.Closeable;
 import java.io.InputStream;
 import java.io.IOException;
 
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-
-import org.xml.sax.SAXException;
-
-import javax.xml.parsers.SAXParserFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
 
 /**
  * The <code>XMLDecoder</code> class is used to read XML documents
@@ -66,11 +61,11 @@
  * @author Philip Milne
  */
 public class XMLDecoder {
-    private InputStream in;
+    private final DocumentHandler handler = new DocumentHandler();
+    private final InputSource input;
     private Object owner;
-    private ExceptionListener exceptionListener;
-    private ObjectHandler handler;
-    private Reference clref;
+    private Object[] array;
+    private int index;
 
     /**
      * Creates a new input stream for reading archives
@@ -126,36 +121,45 @@
      */
     public XMLDecoder(InputStream in, Object owner,
                       ExceptionListener exceptionListener, ClassLoader cl) {
-        this.in = in;
-        setOwner(owner);
-        setExceptionListener(exceptionListener);
-        setClassLoader(cl);
+        this(new InputSource(in), owner, exceptionListener, cl);
     }
 
 
     /**
-     * Set the class loader used to instantiate objects for this stream.
+     * Creates a new decoder to parse XML archives
+     * created by the {@code XMLEncoder} class.
+     * If the input source {@code is} is {@code null},
+     * no exception is thrown and no parsing is performed.
+     * This behavior is similar to behavior of other constructors
+     * that use {@code InputStream} as a parameter.
      *
-     * @param cl a classloader to use; if null then the default class loader
-     *           will be used
+     * @param is  the input source to parse
+     *
+     * @since 1.7
      */
-    private void setClassLoader(ClassLoader cl) {
-        if (cl != null) {
-            this.clref = new WeakReference(cl);
-        }
+    public XMLDecoder(InputSource is) {
+        this(is, null, null, null);
     }
 
     /**
-     * Return the class loader used to instantiate objects. If the class loader
-     * has not been explicitly set then null is returned.
+     * Creates a new decoder to parse XML archives
+     * created by the {@code XMLEncoder} class.
      *
-     * @return the class loader used to instantiate objects
+     * @param is     the input source to parse
+     * @param owner  the owner of this decoder
+     * @param el     the exception handler for the parser,
+     *               or {@code null} to use the default exception handler
+     * @param cl     the class loader used for instantiating objects,
+     *               or {@code null} to use the default class loader
+     *
+     * @since 1.7
      */
-    private ClassLoader getClassLoader() {
-        if (clref != null) {
-            return (ClassLoader)clref.get();
-        }
-        return null;
+    private XMLDecoder(InputSource is, Object owner, ExceptionListener el, ClassLoader cl) {
+        this.input = is;
+        this.owner = owner;
+        setExceptionListener(el);
+        this.handler.setClassLoader(cl);
+        this.handler.setOwner(this);
     }
 
     /**
@@ -163,8 +167,14 @@
      * with this stream.
      */
     public void close() {
+        if (parsingComplete()) {
+            close(this.input.getCharacterStream());
+            close(this.input.getByteStream());
+        }
+    }
+
+    private void close(Closeable in) {
         if (in != null) {
-            getHandler();
             try {
                 in.close();
             }
@@ -174,6 +184,17 @@
         }
     }
 
+    private boolean parsingComplete() {
+        if (this.input == null) {
+            return false;
+        }
+        if (this.array == null) {
+            this.handler.parse(this.input);
+            this.array = this.handler.getObjects();
+        }
+        return true;
+    }
+
     /**
      * Sets the exception handler for this stream to <code>exceptionListener</code>.
      * The exception handler is notified when this stream catches recoverable
@@ -185,7 +206,10 @@
      * @see #getExceptionListener
      */
     public void setExceptionListener(ExceptionListener exceptionListener) {
-        this.exceptionListener = exceptionListener;
+        if (exceptionListener == null) {
+            exceptionListener = Statement.defaultExceptionListener;
+        }
+        this.handler.setExceptionListener(exceptionListener);
     }
 
     /**
@@ -197,8 +221,7 @@
      * @see #setExceptionListener
      */
     public ExceptionListener getExceptionListener() {
-        return (exceptionListener != null) ? exceptionListener :
-            Statement.defaultExceptionListener;
+        return this.handler.getExceptionListener();
     }
 
     /**
@@ -212,10 +235,9 @@
      * @see XMLEncoder#writeObject
      */
     public Object readObject() {
-        if (in == null) {
-            return null;
-        }
-        return getHandler().dequeueResult();
+        return (parsingComplete())
+                ? this.array[this.index++]
+                : null;
     }
 
     /**
@@ -241,33 +263,32 @@
     }
 
     /**
-     * Returns the object handler for input stream.
-     * The object handler is created if necessary.
+     * Creates a new handler for SAX parser
+     * that can be used to parse embedded XML archives
+     * created by the {@code XMLEncoder} class.
      *
-     * @return  the object handler
+     * The {@code owner} should be used if parsed XML document contains
+     * the method call within context of the &lt;java&gt; element.
+     * The {@code null} value may cause illegal parsing in such case.
+     * The same problem may occur, if the {@code owner} class
+     * does not contain expected method to call. See details <a
+     * href="http://java.sun.com/products/jfc/tsc/articles/persistence3/">here</a>.
+     *
+     * @param owner  the owner of the default handler
+     *               that can be used as a value of &lt;java&gt; element
+     * @param el     the exception handler for the parser,
+     *               or {@code null} to use the default exception handler
+     * @param cl     the class loader used for instantiating objects,
+     *               or {@code null} to use the default class loader
+     * @return an instance of {@code DefaultHandler} for SAX parser
+     *
+     * @since 1.7
      */
-    private ObjectHandler getHandler() {
-        if ( handler == null ) {
-            SAXParserFactory factory = SAXParserFactory.newInstance();
-            try {
-                SAXParser parser = factory.newSAXParser();
-                handler = new ObjectHandler( this, getClassLoader() );
-                parser.parse( in, handler );
-            }
-            catch ( ParserConfigurationException e ) {
-                getExceptionListener().exceptionThrown( e );
-            }
-            catch ( SAXException se ) {
-                Exception e = se.getException();
-                if ( e == null ) {
-                    e = se;
-                }
-                getExceptionListener().exceptionThrown( e );
-            }
-            catch ( IOException ioe ) {
-                getExceptionListener().exceptionThrown( ioe );
-            }
-        }
+    public static DefaultHandler createHandler(Object owner, ExceptionListener el, ClassLoader cl) {
+        DocumentHandler handler = new DocumentHandler();
+        handler.setOwner(owner);
+        handler.setExceptionListener(el);
+        handler.setClassLoader(cl);
         return handler;
     }
 }
--- a/src/share/classes/javax/swing/plaf/synth/SynthParser.java	Thu Nov 27 17:55:36 2008 +0300
+++ b/src/share/classes/javax/swing/plaf/synth/SynthParser.java	Mon Dec 22 17:42:49 2008 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -59,16 +59,16 @@
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 
-import org.xml.sax.AttributeList;
-import org.xml.sax.HandlerBase;
+import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
 import org.xml.sax.Locator;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
 
-import com.sun.beans.ObjectHandler;
+import com.sun.beans.decoder.DocumentHandler;
 
-class SynthParser extends HandlerBase {
+class SynthParser extends DefaultHandler {
     //
     // Known element names
     //
@@ -119,7 +119,7 @@
     /**
      * Lazily created, used for anything we don't understand.
      */
-    private ObjectHandler _handler;
+    private DocumentHandler _handler;
 
     /**
      * Indicates the depth of how many elements we've encountered but don't
@@ -292,8 +292,9 @@
     /**
      * Handles beans persistance.
      */
-    private ObjectHandler getHandler() {
+    private DocumentHandler getHandler() {
         if (_handler == null) {
+            _handler = new DocumentHandler();
             if (_urlResourceBase != null) {
                 // getHandler() is never called before parse() so it is safe
                 // to create a URLClassLoader with _resourceBase.
@@ -304,14 +305,13 @@
                 URL[] urls = new URL[] { getResource(".") };
                 ClassLoader parent = Thread.currentThread().getContextClassLoader();
                 ClassLoader urlLoader = new URLClassLoader(urls, parent);
-                _handler = new ObjectHandler(null, urlLoader);
+                _handler.setClassLoader(urlLoader);
             } else {
-                _handler = new ObjectHandler(null,
-                    _classResourceBase.getClassLoader());
+                _handler.setClassLoader(_classResourceBase.getClassLoader());
             }
 
             for (String key : _mapping.keySet()) {
-                _handler.register(key, _mapping.get(key));
+                _handler.setVariable(key, _mapping.get(key));
             }
         }
         return _handler;
@@ -336,8 +336,8 @@
     private Object lookup(String key, Class type) throws SAXException {
         Object value;
         if (_handler != null) {
-            if ((value = _handler.lookup(key)) != null) {
-                return checkCast(value, type);
+            if (_handler.hasVariable(key)) {
+                return checkCast(_handler.getVariable(key), type);
             }
         }
         value = _mapping.get(key);
@@ -354,11 +354,11 @@
     private void register(String key, Object value) throws SAXException {
         if (key != null) {
             if (_mapping.get(key) != null ||
-                     (_handler != null && _handler.lookup(key) != null)) {
+                     (_handler != null && _handler.hasVariable(key))) {
                 throw new SAXException("ID " + key + " is already defined");
             }
             if (_handler != null) {
-                _handler.register(key, value);
+                _handler.setVariable(key, value);
             }
             else {
                 _mapping.put(key, value);
@@ -400,12 +400,12 @@
     // The following methods are invoked from startElement/stopElement
     //
 
-    private void startStyle(AttributeList attributes) throws SAXException {
+    private void startStyle(Attributes attributes) throws SAXException {
         String id = null;
 
         _style = null;
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
             if (key.equals(ATTRIBUTE_CLONE)) {
                 _style = (ParsedSynthStyle)((ParsedSynthStyle)lookup(
                          attributes.getValue(i), ParsedSynthStyle.class)).
@@ -421,7 +421,7 @@
         register(id, _style);
     }
 
-    private void endStyle() throws SAXException {
+    private void endStyle() {
         int size = _stylePainters.size();
         if (size > 0) {
             _style.setPainters(_stylePainters.toArray(new ParsedSynthStyle.PainterInfo[size]));
@@ -435,14 +435,14 @@
         _style = null;
     }
 
-    private void startState(AttributeList attributes) throws SAXException {
+    private void startState(Attributes attributes) throws SAXException {
         ParsedSynthStyle.StateInfo stateInfo = null;
         int state = 0;
         String id = null;
 
         _stateInfo = null;
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
             if (key.equals(ATTRIBUTE_ID)) {
                 id = attributes.getValue(i);
             }
@@ -496,7 +496,7 @@
         _stateInfos.add(_stateInfo);
     }
 
-    private void endState() throws SAXException {
+    private void endState() {
         int size = _statePainters.size();
         if (size > 0) {
             _stateInfo.setPainters(_statePainters.toArray(new ParsedSynthStyle.PainterInfo[size]));
@@ -505,7 +505,7 @@
         _stateInfo = null;
     }
 
-    private void startFont(AttributeList attributes) throws SAXException {
+    private void startFont(Attributes attributes) throws SAXException {
         Font font = null;
         int style = Font.PLAIN;
         int size = 0;
@@ -513,7 +513,7 @@
         String name = null;
 
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
             if (key.equals(ATTRIBUTE_ID)) {
                 id = attributes.getValue(i);
             }
@@ -568,13 +568,13 @@
         }
     }
 
-    private void startColor(AttributeList attributes) throws SAXException {
+    private void startColor(Attributes attributes) throws SAXException {
         Color color = null;
         String id = null;
 
         _colorTypes.clear();
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
             if (key.equals(ATTRIBUTE_ID)) {
                 id = attributes.getValue(i);
             }
@@ -697,7 +697,7 @@
         }
     }
 
-    private void startProperty(AttributeList attributes,
+    private void startProperty(Attributes attributes,
                                Object property) throws SAXException {
         Object value = null;
         String key = null;
@@ -707,7 +707,7 @@
         String aValue = null;
 
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String aName = attributes.getName(i);
+            String aName = attributes.getQName(i);
             if (aName.equals(ATTRIBUTE_TYPE)) {
                 String type = attributes.getValue(i).toUpperCase();
                 if (type.equals("IDREF")) {
@@ -795,11 +795,11 @@
         }
     }
 
-    private void startGraphics(AttributeList attributes) throws SAXException {
+    private void startGraphics(Attributes attributes) throws SAXException {
         SynthGraphicsUtils graphics = null;
 
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
             if (key.equals(ATTRIBUTE_IDREF)) {
                 graphics = (SynthGraphicsUtils)lookup(attributes.getValue(i),
                                                  SynthGraphicsUtils.class);
@@ -813,7 +813,7 @@
         }
     }
 
-    private void startInsets(AttributeList attributes) throws SAXException {
+    private void startInsets(Attributes attributes) throws SAXException {
         int top = 0;
         int bottom = 0;
         int left = 0;
@@ -822,7 +822,7 @@
         String id = null;
 
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
 
             try {
                 if (key.equals(ATTRIBUTE_IDREF)) {
@@ -858,13 +858,13 @@
         }
     }
 
-    private void startBind(AttributeList attributes) throws SAXException {
+    private void startBind(Attributes attributes) throws SAXException {
         ParsedSynthStyle style = null;
         String path = null;
         int type = -1;
 
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
 
             if (key.equals(ATTRIBUTE_STYLE)) {
                 style = (ParsedSynthStyle)lookup(attributes.getValue(i),
@@ -899,7 +899,7 @@
         }
     }
 
-    private void startPainter(AttributeList attributes, String type) throws SAXException {
+    private void startPainter(Attributes attributes, String type) throws SAXException {
         Insets sourceInsets = null;
         Insets destInsets = null;
         String path = null;
@@ -915,7 +915,7 @@
         boolean paintCenterSpecified = false;
 
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
             String value = attributes.getValue(i);
 
             if (key.equals(ATTRIBUTE_ID)) {
@@ -1042,12 +1042,12 @@
         painters.add(painterInfo);
     }
 
-    private void startImageIcon(AttributeList attributes) throws SAXException {
+    private void startImageIcon(Attributes attributes) throws SAXException {
         String path = null;
         String id = null;
 
         for(int i = attributes.getLength() - 1; i >= 0; i--) {
-            String key = attributes.getName(i);
+            String key = attributes.getQName(i);
 
             if (key.equals(ATTRIBUTE_ID)) {
                 id = attributes.getValue(i);
@@ -1062,12 +1062,11 @@
         register(id, new LazyImageIcon(getResource(path)));
        }
 
-    private void startOpaque(AttributeList attributes) throws
-                      SAXException {
+    private void startOpaque(Attributes attributes) {
         if (_style != null) {
             _style.setOpaque(true);
             for(int i = attributes.getLength() - 1; i >= 0; i--) {
-                String key = attributes.getName(i);
+                String key = attributes.getQName(i);
 
                 if (key.equals(ATTRIBUTE_VALUE)) {
                     _style.setOpaque("true".equals(attributes.getValue(i).
@@ -1077,12 +1076,12 @@
         }
     }
 
-    private void startInputMap(AttributeList attributes) throws SAXException {
+    private void startInputMap(Attributes attributes) throws SAXException {
         _inputMapBindings.clear();
         _inputMapID = null;
         if (_style != null) {
             for(int i = attributes.getLength() - 1; i >= 0; i--) {
-                String key = attributes.getName(i);
+                String key = attributes.getQName(i);
 
                 if (key.equals(ATTRIBUTE_ID)) {
                     _inputMapID = attributes.getValue(i);
@@ -1101,7 +1100,7 @@
         _inputMapID = null;
     }
 
-    private void startBindKey(AttributeList attributes) throws SAXException {
+    private void startBindKey(Attributes attributes) throws SAXException {
         if (_inputMapID == null) {
             // Not in an inputmap, bail.
             return;
@@ -1110,7 +1109,7 @@
             String key = null;
             String value = null;
             for(int i = attributes.getLength() - 1; i >= 0; i--) {
-                String aKey = attributes.getName(i);
+                String aKey = attributes.getQName(i);
 
                 if (aKey.equals(ATTRIBUTE_KEY)) {
                     key = attributes.getValue(i);
@@ -1129,26 +1128,26 @@
     }
 
     //
-    // SAX methods, these forward to the ObjectHandler if we don't know
+    // SAX methods, these forward to the DocumentHandler if we don't know
     // the element name.
     //
 
     public InputSource resolveEntity(String publicId, String systemId)
-                              throws SAXException {
+                              throws IOException, SAXException {
         if (isForwarding()) {
             return getHandler().resolveEntity(publicId, systemId);
         }
         return null;
     }
 
-    public void notationDecl(String name, String publicId, String systemId) {
+    public void notationDecl(String name, String publicId, String systemId) throws SAXException {
         if (isForwarding()) {
             getHandler().notationDecl(name, publicId, systemId);
         }
     }
 
     public void unparsedEntityDecl(String name, String publicId,
-                                   String systemId, String notationName) {
+                                   String systemId, String notationName) throws SAXException {
         if (isForwarding()) {
             getHandler().unparsedEntityDecl(name, publicId, systemId,
                                             notationName);
@@ -1173,7 +1172,7 @@
         }
     }
 
-    public void startElement(String name, AttributeList attributes)
+    public void startElement(String uri, String local, String name, Attributes attributes)
                      throws SAXException {
         name = name.intern();
         if (name == ELEMENT_STYLE) {
@@ -1223,18 +1222,18 @@
         }
         else if (name != ELEMENT_SYNTH) {
             if (_depth++ == 0) {
-                getHandler().reset();
+                getHandler().startDocument();
             }
-            getHandler().startElement(name, attributes);
+            getHandler().startElement(uri, local, name, attributes);
         }
     }
 
-    public void endElement(String name) throws SAXException {
+    public void endElement(String uri, String local, String name) throws SAXException {
         if (isForwarding()) {
-            getHandler().endElement(name);
+            getHandler().endElement(uri, local, name);
             _depth--;
             if (!isForwarding()) {
-                getHandler().reset();
+                getHandler().startDocument();
             }
         }
         else {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/Test4864117.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4864117
+ * @summary Tests XMLDecoder within another DefaultHandler for SAX parser
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+import java.beans.ExceptionListener;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public final class Test4864117 extends DefaultHandler implements ExceptionListener {
+    private static final String TEST = "test";
+    private static final String DATA
+            = "<test>\n"
+            + " <void property=\"message\">\n"
+            + "  <string>Hello, world!</string>\n"
+            + " </void>\n"
+            + "</test>";
+
+    public static void main(String[] args) {
+        Test4864117 test = new Test4864117();
+        InputStream input = new ByteArrayInputStream(DATA.getBytes());
+        Exception error = null;
+        try {
+            SAXParserFactory.newInstance().newSAXParser().parse(input, test);
+        }
+        catch (ParserConfigurationException exception) {
+            error = exception;
+        }
+        catch (SAXException exception) {
+            error = exception.getException();
+            if (error == null) {
+                error = exception;
+            }
+        }
+        catch (IOException exception) {
+            error = exception;
+        }
+        if (error != null) {
+            throw new Error("unexpected error", error);
+        }
+        test.print('?', test.getMessage());
+    }
+
+    private String message;
+
+    public String getMessage() {
+        if (this.message == null) {
+            throw new Error("owner's method is not called");
+        }
+        return this.message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+        print(':', this.message);
+    }
+
+    // DefaultHandler implementation
+
+    private DefaultHandler handler;
+    private int depth;
+
+    @Override
+    public void startDocument() throws SAXException {
+        this.handler = XMLDecoder.createHandler(this, this, null);
+        this.handler.startDocument();
+    }
+
+    @Override
+    public void endDocument() {
+        this.handler = null;
+    }
+
+    @Override
+    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+        print('>', qName);
+        if (this.depth > 0) {
+            this.handler.startElement(uri, localName, qName, attributes);
+        } else if (!TEST.equals(qName)) {
+            throw new SAXException("unexpected element name: " + qName);
+        }
+        this.depth++;
+    }
+
+    @Override
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+        this.depth--;
+        print('<', qName);
+        if (this.depth > 0) {
+            this.handler.endElement(uri, localName, qName);
+        } else if (!TEST.equals(qName)) {
+            throw new SAXException("unexpected element name: " + qName);
+        }
+    }
+
+    @Override
+    public void characters(char[] ch, int start, int length) throws SAXException {
+        this.handler.characters(ch, start, length);
+    }
+
+    public void exceptionThrown(Exception exception) {
+        throw new Error("unexpected exception", exception);
+    }
+
+    private void print(char ch, String name) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < this.depth; i++) sb.append(' ');
+        sb.append(ch).append(' ').append(name);
+        System.out.println(sb.toString());
+    }
+}
--- a/test/java/beans/XMLDecoder/Test6341798.java	Thu Nov 27 17:55:36 2008 +0300
+++ b/test/java/beans/XMLDecoder/Test6341798.java	Mon Dec 22 17:42:49 2008 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,7 @@
 
     private static final String DATA
             = "<java>\n"
-            + " <object class=\"TestTurkishLocale$DataBean\">\n"
+            + " <object class=\"Test6341798$DataBean\">\n"
             + "  <void property=\"illegal\">\n"
             + "   <boolean>true</boolean>\n"
             + "  </void>\n"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/AbstractTest.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.beans.ExceptionListener;
+import java.beans.XMLDecoder;
+
+import java.io.ByteArrayInputStream;
+
+abstract class AbstractTest implements ExceptionListener {
+    public void exceptionThrown(Exception exception) {
+        throw new Error("unexpected exception", exception);
+    }
+
+    /**
+     * Validates the XML decoder for XML archive
+     * that defined in the public field of the subclass.
+     *
+     * @param decoder  the initialized XML decoder
+     * @throws Error if validation failed
+     */
+    protected abstract void validate(XMLDecoder decoder);
+
+    /**
+     * This is entry point to start testing.
+     *
+     * @param security  use {@code true} to start
+     *                  second pass in secure context
+     */
+    final void test(boolean security) {
+        byte[] array = getFieldValue("XML").getBytes(); // NON-NLS: the field name
+        ByteArrayInputStream input = new ByteArrayInputStream(array);
+        XMLDecoder decoder = new XMLDecoder(input);
+        decoder.setExceptionListener(this);
+        validate(decoder);
+        try {
+            throw new Error("unexpected object" + decoder.readObject());
+        } catch (ArrayIndexOutOfBoundsException exception) {
+            // expected exception
+        }
+        decoder.close();
+        if (security) {
+            System.setSecurityManager(new SecurityManager());
+            test(false);
+        }
+    }
+
+    private String getFieldValue(String field) {
+        try {
+            return getClass().getField(field).get(this).toString();
+        } catch (NoSuchFieldException exception) {
+            throw new Error("unexpected exception", exception);
+        } catch (IllegalAccessException exception) {
+            throw new Error("unexpected exception", exception);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestArray.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <array> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+import java.lang.reflect.Array;
+
+public final class TestArray extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <array class=\"java.lang.Number\">\n"
+            + "  <byte>-111</byte>\n"
+            + "  <long>1111</long>\n"
+            + " </array>\n"
+            + " <array length=\"3\">\n"
+            + "  <void index=\"1\">\n"
+            + "   <string>Hello, world!</string>\n"
+            + "  </void>\n"
+            + " </array>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestArray().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        Number[] numbers = getArray(Number.class, 2, decoder.readObject());
+        if (!numbers[0].equals(Byte.valueOf("-111"))) { // NON-NLS: hardcoded in XML
+            throw new Error("unexpected byte value");
+        }
+        if (!numbers[1].equals(Long.valueOf("1111"))) { // NON-NLS: hardcoded in XML
+            throw new Error("unexpected long value");
+        }
+
+        Object[] objects = getArray(Object.class, 3, decoder.readObject());
+        if (objects[0] != null) {
+            throw new Error("unexpected first value");
+        }
+        if (!objects[1].equals("Hello, world!")) { // NON-NLS: hardcoded in XML
+            throw new Error("unexpected string value");
+        }
+        if (objects[2] != null) {
+            throw new Error("unexpected last value");
+        }
+    }
+
+    private static <T> T[] getArray(Class<T> component, int length, Object object) {
+        Class type = object.getClass();
+        if (!type.isArray()) {
+            throw new Error("array expected");
+        }
+        if (!type.getComponentType().equals(component)) {
+            throw new Error("unexpected component type");
+        }
+        if (length != Array.getLength(object)) {
+            throw new Error("unexpected array length");
+        }
+        return (T[]) object;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestBoolean.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <boolean> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestBoolean extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <boolean>true</boolean>\n"
+            + " <boolean>false</boolean>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestBoolean().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        if (!Boolean.TRUE.equals(decoder.readObject())) {
+            throw new Error("true expected");
+        }
+        if (!Boolean.FALSE.equals(decoder.readObject())) {
+            throw new Error("false expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestByte.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <byte> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestByte extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <byte>0</byte>\n"
+            + " <byte>127</byte>\n"
+            + " <byte>-128</byte>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestByte().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate((byte) 0, decoder.readObject());
+        validate(Byte.MAX_VALUE, decoder.readObject());
+        validate(Byte.MIN_VALUE, decoder.readObject());
+    }
+
+    private static void validate(byte value, Object object) {
+        if (!object.equals(Byte.valueOf(value))) {
+            throw new Error("byte " + value + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestChar.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <char> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestChar extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <char>X</char>\n"
+            + " <char code=\"#20\"/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestChar().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        if (!decoder.readObject().equals(Character.valueOf('X'))) {
+            throw new Error("unexpected character");
+        }
+        if (!decoder.readObject().equals(Character.valueOf((char) 0x20))) {
+            throw new Error("unexpected character code");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestClass.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <class> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestClass extends AbstractTest {
+    public static final String PREFIX = "javax.swing.colorchooser.";
+    public static final String INTERFACE = "ColorSelectionModel";
+    public static final String PUBLIC_CLASS = "DefaultColorSelectionModel";
+    public static final String PRIVATE_CLASS = "DiagramComponent";
+    public static final String XML
+            = "<java>\n"
+            + " <class>" + PREFIX + INTERFACE + "</class>\n"
+            + " <class>" + PREFIX + PUBLIC_CLASS + "</class>\n"
+            + " <class>" + PREFIX + PRIVATE_CLASS + "</class>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestClass().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate(PREFIX + INTERFACE, decoder.readObject());
+        validate(PREFIX + PUBLIC_CLASS, decoder.readObject());
+        validate(PREFIX + PRIVATE_CLASS, decoder.readObject());
+    }
+
+    private static void validate(String name, Object object) {
+        Class type = (Class) object;
+        if (!type.getName().equals(name)) {
+            throw new Error(name + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestDouble.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <double> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestDouble extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <double>0</double>\n"
+            + " <double>1000</double>\n"
+            + " <double>-1.1e15</double>\n"
+            + " <double>10.11e-123</double>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestDouble().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate(0.0, decoder.readObject());
+        validate(1000.0, decoder.readObject());
+        validate(-1.1e15, decoder.readObject());
+        validate(10.11e-123, decoder.readObject());
+    }
+
+    private static void validate(double value, Object object) {
+        if (!object.equals(Double.valueOf(value))) {
+            throw new Error("double " + value + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestFalse.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <false> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestFalse extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <false/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestFalse().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        if (!Boolean.FALSE.equals(decoder.readObject())) {
+            throw new Error("false expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestField.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <field> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestField extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <field name=\"FIELD\" class=\"TestField\"/>\n"
+            + " <field name=\"FIELD\" class=\"TestField\">\n"
+            + "  <string>static postfix</string>\n"
+            + " </field>\n"
+            + " <field name=\"FIELD\" class=\"TestField\"/>\n"
+            + " <property name=\"owner\">\n"
+            + "  <field id=\"prefix\" name=\"field\"/>\n"
+            + "  <field name=\"field\">\n"
+            + "   <string>postfix</string>\n"
+            + "  </field>\n"
+            + "  <field id=\"postfix\" name=\"field\"/>\n"
+            + " </property>\n"
+            + " <var idref=\"prefix\"/>\n"
+            + " <var idref=\"postfix\"/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestField().test(true);
+    }
+
+    public static String FIELD;
+    public String field;
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        FIELD = "static prefix";
+        field = "prefix";
+        decoder.setOwner(this);
+        validate(decoder, "static prefix");
+        validate(decoder, "static postfix");
+        validate(decoder, "prefix");
+        validate(decoder, "postfix");
+    }
+
+    private static void validate(XMLDecoder decoder, String name) {
+        if (!decoder.readObject().equals(name)) {
+            throw new Error(name + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestFloat.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <float> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestFloat extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <float>0</float>\n"
+            + " <float>100</float>\n"
+            + " <float>-1e15</float>\n"
+            + " <float>100e-20</float>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestFloat().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate(0.0f, decoder.readObject());
+        validate(100.0f, decoder.readObject());
+        validate(-1e15f, decoder.readObject());
+        validate(100e-20f, decoder.readObject());
+    }
+
+    private static void validate(float value, Object object) {
+        if (!object.equals(Float.valueOf(value))) {
+            throw new Error("float " + value + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestInt.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <int> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestInt extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <int>0</int>\n"
+            + " <int>127</int>\n"
+            + " <int>-128</int>\n"
+            + " <int>32767</int>\n"
+            + " <int>-32768</int>\n"
+            + " <int>2147483647</int>\n"
+            + " <int>-2147483648</int>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestInt().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate(0, decoder.readObject());
+        validate((int) Byte.MAX_VALUE, decoder.readObject());
+        validate((int) Byte.MIN_VALUE, decoder.readObject());
+        validate((int) Short.MAX_VALUE, decoder.readObject());
+        validate((int) Short.MIN_VALUE, decoder.readObject());
+        validate(Integer.MAX_VALUE, decoder.readObject());
+        validate(Integer.MIN_VALUE, decoder.readObject());
+    }
+
+    private static void validate(int value, Object object) {
+        if (!object.equals(Integer.valueOf(value))) {
+            throw new Error("int " + value + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestJava.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <java> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestJava extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <void id=\"owner\" method=\"getOwner\">\n"
+            + "  <void method=\"init\">\n"
+            + "   <string>Hello, world!</string>\n"
+            + "  </void>\n"
+            + " </void>\n"
+            + " <object idref=\"owner\"/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestJava().test(true);
+    }
+
+    private String message;
+
+    public void init(String message) {
+        this.message = message;
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        decoder.setOwner(this);
+        if (this != decoder.readObject()) {
+            throw new Error("owner should be the same");
+        }
+        if (this.message == null) {
+            throw new Error("owner's method is not called");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestLong.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <long> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestLong extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <long>0</long>\n"
+            + " <long>127</long>\n"
+            + " <long>-128</long>\n"
+            + " <long>32767</long>\n"
+            + " <long>-32768</long>\n"
+            + " <long>2147483647</long>\n"
+            + " <long>-2147483648</long>\n"
+            + " <long>9223372036854775807</long>\n"
+            + " <long>-9223372036854775808</long>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestLong().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate(0L, decoder.readObject());
+        validate((long) Byte.MAX_VALUE, decoder.readObject());
+        validate((long) Byte.MIN_VALUE, decoder.readObject());
+        validate((long) Short.MAX_VALUE, decoder.readObject());
+        validate((long) Short.MIN_VALUE, decoder.readObject());
+        validate((long) Integer.MAX_VALUE, decoder.readObject());
+        validate((long) Integer.MIN_VALUE, decoder.readObject());
+        validate(Long.MAX_VALUE, decoder.readObject());
+        validate(Long.MIN_VALUE, decoder.readObject());
+    }
+
+    private static void validate(long value, Object object) {
+        if (!object.equals(Long.valueOf(value))) {
+            throw new Error("long " + value + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestMethod.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <method> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestMethod extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <new class=\"TestMethod$A\">\n"
+            + "  <method name=\"m\">\n"
+            + "   <new class=\"TestMethod$Y\"/>\n"
+            + "   <new class=\"TestMethod$Y\"/>\n"
+            + "  </method>\n"
+            + " </new>\n"
+            + " <new class=\"TestMethod$B\">\n"
+            + "  <method name=\"m\">\n"
+            + "   <new class=\"TestMethod$Y\"/>\n"
+            + "   <new class=\"TestMethod$Y\"/>\n"
+            + "  </method>\n"
+            + " </new>\n"
+            + " <new class=\"TestMethod$C\">\n"
+            + "  <method name=\"m\">\n"
+            + "   <new class=\"TestMethod$Z\"/>\n"
+            + "   <new class=\"TestMethod$Z\"/>\n"
+            + "  </method>\n"
+            + " </new>\n"
+            + " <new class=\"TestMethod$D\">\n"
+            + "  <method name=\"m\">\n"
+            + "   <new class=\"TestMethod$Z\"/>\n"
+            + "   <new class=\"TestMethod$Z\"/>\n"
+            + "  </method>\n"
+            + " </new>\n"
+            + " <new class=\"TestMethod$E\">\n"
+            + "  <method name=\"m\">\n"
+            + "   <new class=\"TestMethod$Z\"/>\n"
+            + "   <new class=\"TestMethod$Z\"/>\n"
+            + "  </method>\n"
+            + " </new>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestMethod().test(true);
+    }
+
+    private NoSuchMethodException exception;
+
+    @Override
+    public void exceptionThrown(Exception exception) {
+        if (this.exception != null) {
+            // only one exception allowed
+            super.exceptionThrown(exception);
+        } else if (exception instanceof NoSuchMethodException) {
+            // expected exception: ambiguous methods are found
+            this.exception = (NoSuchMethodException) exception;
+        } else {
+            super.exceptionThrown(exception);
+        }
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        this.exception = null;
+        validate(decoder, A.class);
+        validate(decoder, B.class);
+        validate(decoder, C.class);
+        validate(decoder, D.class);
+        validate(decoder, E.class);
+        if (this.exception == null) {
+            throw new Error("NoSuchMethodException expected");
+        }
+    }
+
+    private static void validate(XMLDecoder decoder, Class type) {
+        if (!type.equals(decoder.readObject().getClass())) {
+            throw new Error("unexpected class");
+        }
+    }
+
+    /**
+     * All ambiguous method declarations should fail.
+     */
+    public static class A {
+        public void m(X x1, X x2) {
+            throw new Error("A.m(X,X) should not be called");
+        }
+
+        public void m(X x1, Y y2) {
+            throw new Error("A.m(X,Y) should not be called");
+        }
+
+        public void m(Y y1, X x2) {
+            throw new Error("A.m(Y,X) should not be called");
+        }
+    }
+
+    /**
+     * The most specific method in this case would be the second declaration.
+     */
+    public static class B {
+        public void m(X x1, X x2) {
+            throw new Error("B.m(X,X) should not be called");
+        }
+
+        public void m(X x1, Y y2) {
+            // expected: B.m(X,Y) should be called
+        }
+    }
+
+    /**
+     * The most specific method in this case would be the first declaration.
+     */
+    public static class C {
+        public void m(Y y1, Y y2) {
+            // expected: C.m(Y,Y) should be called
+        }
+
+        public void m(X x1, X x2) {
+            throw new Error("C.m(X,X) should not be called");
+        }
+    }
+
+    /**
+     * Same as the previous case but flip methods.
+     */
+    public static class D {
+        public void m(X x1, X x2) {
+            throw new Error("D.m(X,X) should not be called");
+        }
+
+        public void m(Y y1, Y y2) {
+            // expected: D.m(Y,Y) should be called
+        }
+    }
+
+    /**
+     * The method should be called with (Z,Z).
+     */
+    public static class E {
+        public void m(X x1, X x2) {
+            // expected: E.m(X,X) should be called
+        }
+    }
+
+    public static class X {
+    }
+
+    public static class Y extends X {
+    }
+
+    public static class Z extends Y {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestNew.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <new> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+import java.util.ArrayList;
+import java.util.List;
+
+public final class TestNew extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <new class=\"TestNew\"/>\n"
+            + " <new class=\"TestNew\">\n"
+            + "  <null/>\n"
+            + " </new>\n"
+            + " <new class=\"TestNew\">\n"
+            + "  <string>single</string>\n"
+            + " </new>\n"
+            + " <new class=\"TestNew\">\n"
+            + "  <string>first</string>\n"
+            + "  <string>second</string>\n"
+            + "  <string>third</string>\n"
+            + " </new>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestNew().test(true);
+    }
+
+    private List<String> list;
+
+    public TestNew(String...messages) {
+        if (messages != null) {
+            this.list = new ArrayList<String>();
+            for (String message : messages) {
+                this.list.add(message);
+            }
+        }
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (object instanceof TestNew) {
+            TestNew test = (TestNew) object;
+            return (test.list == null)
+                    ? this.list == null
+                    : test.list.equals(this.list);
+        }
+        return false;
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate(decoder.readObject());
+        validate(decoder.readObject(), null);
+        validate(decoder.readObject(), "single");
+        validate(decoder.readObject(), "first", "second", "third");
+    }
+
+    private static void validate(Object object, String...messages) {
+        if (!object.equals(new TestNew(messages))) {
+            throw new Error("expected object");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestNull.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <null> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestNull extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <null/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestNull().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        if (null != decoder.readObject()) {
+            throw new Error("null value expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestObject.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <object> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+
+public final class TestObject extends AbstractTest {
+    public static final String XML // TODO
+            = "<java>\n"
+            + " <object class=\"javax.swing.JPanel\">\n"
+            + "  <void method=\"add\">\n"
+            + "   <object id=\"button\" class=\"javax.swing.JButton\">\n"
+            + "    <string>button</string>\n"
+            + "    <void property=\"verticalAlignment\">\n"
+            + "     <object field=\"CENTER\" class=\"javax.swing.SwingConstants\"/>\n"
+            + "    </void>\n"
+            + "   </object>\n"
+            + "  </void>\n"
+            + "  <void method=\"add\">\n"
+            + "   <object class=\"javax.swing.JLabel\">\n"
+            + "    <string>label</string>\n"
+            + "    <void property=\"labelFor\">\n"
+            + "     <object idref=\"button\"/>\n"
+            + "    </void>\n"
+            + "   </object>\n"
+            + "  </void>\n"
+            + " </object>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestObject().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        JPanel panel = (JPanel) decoder.readObject();
+        if (2 != panel.getComponents().length) {
+            throw new Error("unexpected component count");
+        }
+        JButton button = (JButton) panel.getComponents()[0];
+        if (!button.getText().equals("button")) { // NON-NLS: hardcoded in XML
+            throw new Error("unexpected button text");
+        }
+        if (SwingConstants.CENTER != button.getVerticalAlignment()) {
+            throw new Error("unexpected vertical alignment");
+        }
+        JLabel label = (JLabel) panel.getComponents()[1];
+        if (!label.getText().equals("label")) { // NON-NLS: hardcoded in XML
+            throw new Error("unexpected label text");
+        }
+        if (button != label.getLabelFor()) {
+            throw new Error("unexpected component");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestProperty.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <property> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestProperty extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <property name=\"owner\">\n"
+            + "  <property name=\"message\">\n"
+            + "   <string>message</string>\n"
+            + "  </property>\n"
+            + "  <property id=\"message\" name=\"message\"/>\n"
+            + "  <property name=\"indexed\" index=\"1\">\n"
+            + "   <string>indexed</string>\n"
+            + "  </property>\n"
+            + "  <property id=\"indexed\" name=\"indexed\" index=\"1\"/>\n"
+            + " </property>\n"
+            + " <var idref=\"message\"/>\n"
+            + " <var idref=\"indexed\"/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestProperty().test(true);
+    }
+
+    private int index;
+    private String message;
+
+    public String getMessage() {
+        return this.message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String getIndexed(int index) {
+        if (this.index != index) {
+            throw new Error("unexpected index");
+        }
+        return this.message;
+    }
+
+    public void setIndexed(int index, String message) {
+        this.index = index;
+        this.message = message;
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        decoder.setOwner(this);
+        validate(decoder, "message");
+        validate(decoder, "indexed");
+    }
+
+    private static void validate(XMLDecoder decoder, String name) {
+        if (!decoder.readObject().equals(name)) {
+            throw new Error(name + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestShort.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <short> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestShort extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <short>0</short>\n"
+            + " <short>127</short>\n"
+            + " <short>-128</short>\n"
+            + " <short>32767</short>\n"
+            + " <short>-32768</short>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestShort().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate((short) 0, decoder.readObject());
+        validate((short) Byte.MAX_VALUE, decoder.readObject());
+        validate((short) Byte.MIN_VALUE, decoder.readObject());
+        validate(Short.MAX_VALUE, decoder.readObject());
+        validate(Short.MIN_VALUE, decoder.readObject());
+    }
+
+    private static void validate(short value, Object object) {
+        if (!object.equals(Short.valueOf(value))) {
+            throw new Error("short " + value + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestString.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <string> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestString extends AbstractTest {
+    public static final String PREFIX = " prefix ";
+    public static final String POSTFIX = " postfix ";
+    public static final String XML
+            = "<java>\n"
+            + " <string>" + PREFIX + "</string>\n"
+            + " <string>" + POSTFIX + "</string>\n"
+            + " <string>" + PREFIX + POSTFIX + "</string>\n"
+            + " <string>" + PREFIX + "<char code=\"0\"/>" + POSTFIX + "</string>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestString().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        validate(PREFIX, decoder.readObject());
+        validate(POSTFIX, decoder.readObject());
+        validate(PREFIX + POSTFIX, decoder.readObject());
+        validate(PREFIX + '\u0000' + POSTFIX, decoder.readObject());
+    }
+
+    private static void validate(String name, Object object) {
+        if (!object.equals(name)) {
+            throw new Error(name + " expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestTrue.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <true> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestTrue extends AbstractTest {
+    public static final String XML
+            = "<java>\n"
+            + " <true/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestTrue().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        if (!Boolean.TRUE.equals(decoder.readObject())) {
+            throw new Error("true expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/beans/XMLDecoder/spec/TestVar.java	Mon Dec 22 17:42:49 2008 +0300
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary Tests <var> element
+ * @author Sergey Malenkov
+ */
+
+import java.beans.XMLDecoder;
+
+public final class TestVar extends AbstractTest {
+    public static final String XML
+            = "<java id=\"decoder\">\n"
+            + " <var idref=\"decoder\"/>\n"
+            + " <var id=\"another\" idref=\"decoder\"/>\n"
+            + " <var idref=\"another\"/>\n"
+            + " <var id=\"decoder\" idref=\"another\"/>\n"
+            + " <var idref=\"decoder\"/>\n"
+            + "</java>";
+
+    public static void main(String[] args) {
+        new TestVar().test(true);
+    }
+
+    @Override
+    protected void validate(XMLDecoder decoder) {
+        for (int i = 0; i < 3; i++) {
+            if (decoder != decoder.readObject()) {
+                throw new Error("decoder instance expected");
+            }
+        }
+    }
+}