merge with trunk arithmetic
authorMartin Soch <Martin.Soch@oracle.com>
Tue, 05 Feb 2013 17:04:22 +0100
brancharithmetic
changeset 6771ff540c1650f
parent 676 eecf6077ec4e
parent 668 b4354a30d4dd
child 678 8a25056ef283
merge with trunk
launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Console.java
launcher/src/main/java/org/apidesign/bck2brwsr/launcher/MethodInvocation.java
vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java
     1.1 --- a/core/pom.xml	Tue Feb 05 16:40:01 2013 +0100
     1.2 +++ b/core/pom.xml	Tue Feb 05 17:04:22 2013 +0100
     1.3 @@ -38,6 +38,7 @@
     1.4      <dependency>
     1.5        <groupId>org.netbeans.api</groupId>
     1.6        <artifactId>org-openide-util-lookup</artifactId>
     1.7 +      <scope>provided</scope>
     1.8      </dependency>
     1.9    </dependencies>
    1.10      <description>Contains esential annotations for associating JavaScript code with
     2.1 --- a/emul/compact/pom.xml	Tue Feb 05 16:40:01 2013 +0100
     2.2 +++ b/emul/compact/pom.xml	Tue Feb 05 17:04:22 2013 +0100
     2.3 @@ -27,6 +27,11 @@
     2.4        <version>${project.version}</version>
     2.5        <scope>test</scope>
     2.6      </dependency>
     2.7 +    <dependency>
     2.8 +      <groupId>org.netbeans.api</groupId>
     2.9 +      <artifactId>org-openide-util-lookup</artifactId>
    2.10 +      <scope>test</scope>
    2.11 +    </dependency>
    2.12    </dependencies>
    2.13    <build>
    2.14        <plugins>
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/emul/compact/src/main/java/java/beans/ChangeListenerMap.java	Tue Feb 05 17:04:22 2013 +0100
     3.3 @@ -0,0 +1,248 @@
     3.4 +/*
     3.5 + * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.  Oracle designates this
    3.11 + * particular file as subject to the "Classpath" exception as provided
    3.12 + * by Oracle in the LICENSE file that accompanied this code.
    3.13 + *
    3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.17 + * version 2 for more details (a copy is included in the LICENSE file that
    3.18 + * accompanied this code).
    3.19 + *
    3.20 + * You should have received a copy of the GNU General Public License version
    3.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.23 + *
    3.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.25 + * or visit www.oracle.com if you need additional information or have any
    3.26 + * questions.
    3.27 + */
    3.28 +package java.beans;
    3.29 +
    3.30 +import java.util.ArrayList;
    3.31 +import java.util.Collections;
    3.32 +import java.util.EventListener;
    3.33 +import java.util.EventListenerProxy;
    3.34 +import java.util.HashMap;
    3.35 +import java.util.List;
    3.36 +import java.util.Map;
    3.37 +import java.util.Map.Entry;
    3.38 +import java.util.Set;
    3.39 +import org.apidesign.bck2brwsr.emul.lang.System;
    3.40 +
    3.41 +/**
    3.42 + * This is an abstract class that provides base functionality
    3.43 + * for the {@link PropertyChangeSupport PropertyChangeSupport} class
    3.44 + * and the {@link VetoableChangeSupport VetoableChangeSupport} class.
    3.45 + *
    3.46 + * @see PropertyChangeListenerMap
    3.47 + * @see VetoableChangeListenerMap
    3.48 + *
    3.49 + * @author Sergey A. Malenkov
    3.50 + */
    3.51 +abstract class ChangeListenerMap<L extends EventListener> {
    3.52 +    private Map<String, L[]> map;
    3.53 +
    3.54 +    /**
    3.55 +     * Creates an array of listeners.
    3.56 +     * This method can be optimized by using
    3.57 +     * the same instance of the empty array
    3.58 +     * when {@code length} is equal to {@code 0}.
    3.59 +     *
    3.60 +     * @param length  the array length
    3.61 +     * @return        an array with specified length
    3.62 +     */
    3.63 +    protected abstract L[] newArray(int length);
    3.64 +
    3.65 +    /**
    3.66 +     * Creates a proxy listener for the specified property.
    3.67 +     *
    3.68 +     * @param name      the name of the property to listen on
    3.69 +     * @param listener  the listener to process events
    3.70 +     * @return          a proxy listener
    3.71 +     */
    3.72 +    protected abstract L newProxy(String name, L listener);
    3.73 +
    3.74 +    /**
    3.75 +     * Adds a listener to the list of listeners for the specified property.
    3.76 +     * This listener is called as many times as it was added.
    3.77 +     *
    3.78 +     * @param name      the name of the property to listen on
    3.79 +     * @param listener  the listener to process events
    3.80 +     */
    3.81 +    public final synchronized void add(String name, L listener) {
    3.82 +        if (this.map == null) {
    3.83 +            this.map = new HashMap<String, L[]>();
    3.84 +        }
    3.85 +        L[] array = this.map.get(name);
    3.86 +        int size = (array != null)
    3.87 +                ? array.length
    3.88 +                : 0;
    3.89 +
    3.90 +        L[] clone = newArray(size + 1);
    3.91 +        clone[size] = listener;
    3.92 +        if (array != null) {
    3.93 +            System.arraycopy(array, 0, clone, 0, size);
    3.94 +        }
    3.95 +        this.map.put(name, clone);
    3.96 +    }
    3.97 +
    3.98 +    /**
    3.99 +     * Removes a listener from the list of listeners for the specified property.
   3.100 +     * If the listener was added more than once to the same event source,
   3.101 +     * this listener will be notified one less time after being removed.
   3.102 +     *
   3.103 +     * @param name      the name of the property to listen on
   3.104 +     * @param listener  the listener to process events
   3.105 +     */
   3.106 +    public final synchronized void remove(String name, L listener) {
   3.107 +        if (this.map != null) {
   3.108 +            L[] array = this.map.get(name);
   3.109 +            if (array != null) {
   3.110 +                for (int i = 0; i < array.length; i++) {
   3.111 +                    if (listener.equals(array[i])) {
   3.112 +                        int size = array.length - 1;
   3.113 +                        if (size > 0) {
   3.114 +                            L[] clone = newArray(size);
   3.115 +                            System.arraycopy(array, 0, clone, 0, i);
   3.116 +                            System.arraycopy(array, i + 1, clone, i, size - i);
   3.117 +                            this.map.put(name, clone);
   3.118 +                        }
   3.119 +                        else {
   3.120 +                            this.map.remove(name);
   3.121 +                            if (this.map.isEmpty()) {
   3.122 +                                this.map = null;
   3.123 +                            }
   3.124 +                        }
   3.125 +                        break;
   3.126 +                    }
   3.127 +                }
   3.128 +            }
   3.129 +        }
   3.130 +    }
   3.131 +
   3.132 +    /**
   3.133 +     * Returns the list of listeners for the specified property.
   3.134 +     *
   3.135 +     * @param name  the name of the property
   3.136 +     * @return      the corresponding list of listeners
   3.137 +     */
   3.138 +    public final synchronized L[] get(String name) {
   3.139 +        return (this.map != null)
   3.140 +                ? this.map.get(name)
   3.141 +                : null;
   3.142 +    }
   3.143 +
   3.144 +    /**
   3.145 +     * Sets new list of listeners for the specified property.
   3.146 +     *
   3.147 +     * @param name       the name of the property
   3.148 +     * @param listeners  new list of listeners
   3.149 +     */
   3.150 +    public final void set(String name, L[] listeners) {
   3.151 +        if (listeners != null) {
   3.152 +            if (this.map == null) {
   3.153 +                this.map = new HashMap<String, L[]>();
   3.154 +            }
   3.155 +            this.map.put(name, listeners);
   3.156 +        }
   3.157 +        else if (this.map != null) {
   3.158 +            this.map.remove(name);
   3.159 +            if (this.map.isEmpty()) {
   3.160 +                this.map = null;
   3.161 +            }
   3.162 +        }
   3.163 +    }
   3.164 +
   3.165 +    /**
   3.166 +     * Returns all listeners in the map.
   3.167 +     *
   3.168 +     * @return an array of all listeners
   3.169 +     */
   3.170 +    public final synchronized L[] getListeners() {
   3.171 +        if (this.map == null) {
   3.172 +            return newArray(0);
   3.173 +        }
   3.174 +        List<L> list = new ArrayList<L>();
   3.175 +
   3.176 +        L[] listeners = this.map.get(null);
   3.177 +        if (listeners != null) {
   3.178 +            for (L listener : listeners) {
   3.179 +                list.add(listener);
   3.180 +            }
   3.181 +        }
   3.182 +        for (Entry<String, L[]> entry : this.map.entrySet()) {
   3.183 +            String name = entry.getKey();
   3.184 +            if (name != null) {
   3.185 +                for (L listener : entry.getValue()) {
   3.186 +                    list.add(newProxy(name, listener));
   3.187 +                }
   3.188 +            }
   3.189 +        }
   3.190 +        return list.toArray(newArray(list.size()));
   3.191 +    }
   3.192 +
   3.193 +    /**
   3.194 +     * Returns listeners that have been associated with the named property.
   3.195 +     *
   3.196 +     * @param name  the name of the property
   3.197 +     * @return an array of listeners for the named property
   3.198 +     */
   3.199 +    public final L[] getListeners(String name) {
   3.200 +        if (name != null) {
   3.201 +            L[] listeners = get(name);
   3.202 +            if (listeners != null) {
   3.203 +                return listeners.clone();
   3.204 +            }
   3.205 +        }
   3.206 +        return newArray(0);
   3.207 +    }
   3.208 +
   3.209 +    /**
   3.210 +     * Indicates whether the map contains
   3.211 +     * at least one listener to be notified.
   3.212 +     *
   3.213 +     * @param name  the name of the property
   3.214 +     * @return      {@code true} if at least one listener exists or
   3.215 +     *              {@code false} otherwise
   3.216 +     */
   3.217 +    public final synchronized boolean hasListeners(String name) {
   3.218 +        if (this.map == null) {
   3.219 +            return false;
   3.220 +        }
   3.221 +        L[] array = this.map.get(null);
   3.222 +        return (array != null) || ((name != null) && (null != this.map.get(name)));
   3.223 +    }
   3.224 +
   3.225 +    /**
   3.226 +     * Returns a set of entries from the map.
   3.227 +     * Each entry is a pair consisted of the property name
   3.228 +     * and the corresponding list of listeners.
   3.229 +     *
   3.230 +     * @return a set of entries from the map
   3.231 +     */
   3.232 +    public final Set<Entry<String, L[]>> getEntries() {
   3.233 +        return (this.map != null)
   3.234 +                ? this.map.entrySet()
   3.235 +                : Collections.<Entry<String, L[]>>emptySet();
   3.236 +    }
   3.237 +
   3.238 +    /**
   3.239 +     * Extracts a real listener from the proxy listener.
   3.240 +     * It is necessary because default proxy class is not serializable.
   3.241 +     *
   3.242 +     * @return a real listener
   3.243 +     */
   3.244 +    public final L extract(L listener) {
   3.245 +        while (listener instanceof EventListenerProxy) {
   3.246 +            EventListenerProxy<L> proxy = (EventListenerProxy<L>) listener;
   3.247 +            listener = proxy.getListener();
   3.248 +        }
   3.249 +        return listener;
   3.250 +    }
   3.251 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/emul/compact/src/main/java/java/beans/IndexedPropertyChangeEvent.java	Tue Feb 05 17:04:22 2013 +0100
     4.3 @@ -0,0 +1,78 @@
     4.4 +/*
     4.5 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
     4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 + *
     4.8 + * This code is free software; you can redistribute it and/or modify it
     4.9 + * under the terms of the GNU General Public License version 2 only, as
    4.10 + * published by the Free Software Foundation.  Oracle designates this
    4.11 + * particular file as subject to the "Classpath" exception as provided
    4.12 + * by Oracle in the LICENSE file that accompanied this code.
    4.13 + *
    4.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    4.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.17 + * version 2 for more details (a copy is included in the LICENSE file that
    4.18 + * accompanied this code).
    4.19 + *
    4.20 + * You should have received a copy of the GNU General Public License version
    4.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    4.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.23 + *
    4.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    4.25 + * or visit www.oracle.com if you need additional information or have any
    4.26 + * questions.
    4.27 + */
    4.28 +package java.beans;
    4.29 +
    4.30 +/**
    4.31 + * An "IndexedPropertyChange" event gets delivered whenever a component that
    4.32 + * conforms to the JavaBeans&trade; specification (a "bean") changes a bound
    4.33 + * indexed property. This class is an extension of <code>PropertyChangeEvent</code>
    4.34 + * but contains the index of the property that has changed.
    4.35 + * <P>
    4.36 + * Null values may be provided for the old and the new values if their
    4.37 + * true values are not known.
    4.38 + * <P>
    4.39 + * An event source may send a null object as the name to indicate that an
    4.40 + * arbitrary set of if its properties have changed.  In this case the
    4.41 + * old and new values should also be null.
    4.42 + *
    4.43 + * @since 1.5
    4.44 + * @author Mark Davidson
    4.45 + */
    4.46 +public class IndexedPropertyChangeEvent extends PropertyChangeEvent {
    4.47 +    private static final long serialVersionUID = -320227448495806870L;
    4.48 +
    4.49 +    private int index;
    4.50 +
    4.51 +    /**
    4.52 +     * Constructs a new <code>IndexedPropertyChangeEvent</code> object.
    4.53 +     *
    4.54 +     * @param source  The bean that fired the event.
    4.55 +     * @param propertyName  The programmatic name of the property that
    4.56 +     *             was changed.
    4.57 +     * @param oldValue      The old value of the property.
    4.58 +     * @param newValue      The new value of the property.
    4.59 +     * @param index index of the property element that was changed.
    4.60 +     */
    4.61 +    public IndexedPropertyChangeEvent(Object source, String propertyName,
    4.62 +                                      Object oldValue, Object newValue,
    4.63 +                                      int index) {
    4.64 +        super (source, propertyName, oldValue, newValue);
    4.65 +        this.index = index;
    4.66 +    }
    4.67 +
    4.68 +    /**
    4.69 +     * Gets the index of the property that was changed.
    4.70 +     *
    4.71 +     * @return The index specifying the property element that was
    4.72 +     *         changed.
    4.73 +     */
    4.74 +    public int getIndex() {
    4.75 +        return index;
    4.76 +    }
    4.77 +
    4.78 +    void appendTo(StringBuilder sb) {
    4.79 +        sb.append("; index=").append(getIndex());
    4.80 +    }
    4.81 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/emul/compact/src/main/java/java/beans/PropertyChangeEvent.java	Tue Feb 05 17:04:22 2013 +0100
     5.3 @@ -0,0 +1,164 @@
     5.4 +/*
     5.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
     5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 + *
     5.8 + * This code is free software; you can redistribute it and/or modify it
     5.9 + * under the terms of the GNU General Public License version 2 only, as
    5.10 + * published by the Free Software Foundation.  Oracle designates this
    5.11 + * particular file as subject to the "Classpath" exception as provided
    5.12 + * by Oracle in the LICENSE file that accompanied this code.
    5.13 + *
    5.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    5.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.17 + * version 2 for more details (a copy is included in the LICENSE file that
    5.18 + * accompanied this code).
    5.19 + *
    5.20 + * You should have received a copy of the GNU General Public License version
    5.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    5.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.23 + *
    5.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.25 + * or visit www.oracle.com if you need additional information or have any
    5.26 + * questions.
    5.27 + */
    5.28 +
    5.29 +package java.beans;
    5.30 +
    5.31 +/**
    5.32 + * A "PropertyChange" event gets delivered whenever a bean changes a "bound"
    5.33 + * or "constrained" property.  A PropertyChangeEvent object is sent as an
    5.34 + * argument to the PropertyChangeListener and VetoableChangeListener methods.
    5.35 + * <P>
    5.36 + * Normally PropertyChangeEvents are accompanied by the name and the old
    5.37 + * and new value of the changed property.  If the new value is a primitive
    5.38 + * type (such as int or boolean) it must be wrapped as the
    5.39 + * corresponding java.lang.* Object type (such as Integer or Boolean).
    5.40 + * <P>
    5.41 + * Null values may be provided for the old and the new values if their
    5.42 + * true values are not known.
    5.43 + * <P>
    5.44 + * An event source may send a null object as the name to indicate that an
    5.45 + * arbitrary set of if its properties have changed.  In this case the
    5.46 + * old and new values should also be null.
    5.47 + */
    5.48 +
    5.49 +public class PropertyChangeEvent extends java.util.EventObject {
    5.50 +    private static final long serialVersionUID = 7042693688939648123L;
    5.51 +
    5.52 +    /**
    5.53 +     * Constructs a new <code>PropertyChangeEvent</code>.
    5.54 +     *
    5.55 +     * @param source  The bean that fired the event.
    5.56 +     * @param propertyName  The programmatic name of the property
    5.57 +     *          that was changed.
    5.58 +     * @param oldValue  The old value of the property.
    5.59 +     * @param newValue  The new value of the property.
    5.60 +     */
    5.61 +    public PropertyChangeEvent(Object source, String propertyName,
    5.62 +                                     Object oldValue, Object newValue) {
    5.63 +        super(source);
    5.64 +        this.propertyName = propertyName;
    5.65 +        this.newValue = newValue;
    5.66 +        this.oldValue = oldValue;
    5.67 +    }
    5.68 +
    5.69 +    /**
    5.70 +     * Gets the programmatic name of the property that was changed.
    5.71 +     *
    5.72 +     * @return  The programmatic name of the property that was changed.
    5.73 +     *          May be null if multiple properties have changed.
    5.74 +     */
    5.75 +    public String getPropertyName() {
    5.76 +        return propertyName;
    5.77 +    }
    5.78 +
    5.79 +    /**
    5.80 +     * Gets the new value for the property, expressed as an Object.
    5.81 +     *
    5.82 +     * @return  The new value for the property, expressed as an Object.
    5.83 +     *          May be null if multiple properties have changed.
    5.84 +     */
    5.85 +    public Object getNewValue() {
    5.86 +        return newValue;
    5.87 +    }
    5.88 +
    5.89 +    /**
    5.90 +     * Gets the old value for the property, expressed as an Object.
    5.91 +     *
    5.92 +     * @return  The old value for the property, expressed as an Object.
    5.93 +     *          May be null if multiple properties have changed.
    5.94 +     */
    5.95 +    public Object getOldValue() {
    5.96 +        return oldValue;
    5.97 +    }
    5.98 +
    5.99 +    /**
   5.100 +     * Sets the propagationId object for the event.
   5.101 +     *
   5.102 +     * @param propagationId  The propagationId object for the event.
   5.103 +     */
   5.104 +    public void setPropagationId(Object propagationId) {
   5.105 +        this.propagationId = propagationId;
   5.106 +    }
   5.107 +
   5.108 +    /**
   5.109 +     * The "propagationId" field is reserved for future use.  In Beans 1.0
   5.110 +     * the sole requirement is that if a listener catches a PropertyChangeEvent
   5.111 +     * and then fires a PropertyChangeEvent of its own, then it should
   5.112 +     * make sure that it propagates the propagationId field from its
   5.113 +     * incoming event to its outgoing event.
   5.114 +     *
   5.115 +     * @return the propagationId object associated with a bound/constrained
   5.116 +     *          property update.
   5.117 +     */
   5.118 +    public Object getPropagationId() {
   5.119 +        return propagationId;
   5.120 +    }
   5.121 +
   5.122 +    /**
   5.123 +     * name of the property that changed.  May be null, if not known.
   5.124 +     * @serial
   5.125 +     */
   5.126 +    private String propertyName;
   5.127 +
   5.128 +    /**
   5.129 +     * New value for property.  May be null if not known.
   5.130 +     * @serial
   5.131 +     */
   5.132 +    private Object newValue;
   5.133 +
   5.134 +    /**
   5.135 +     * Previous value for property.  May be null if not known.
   5.136 +     * @serial
   5.137 +     */
   5.138 +    private Object oldValue;
   5.139 +
   5.140 +    /**
   5.141 +     * Propagation ID.  May be null.
   5.142 +     * @serial
   5.143 +     * @see #getPropagationId
   5.144 +     */
   5.145 +    private Object propagationId;
   5.146 +
   5.147 +    /**
   5.148 +     * Returns a string representation of the object.
   5.149 +     *
   5.150 +     * @return a string representation of the object
   5.151 +     *
   5.152 +     * @since 1.7
   5.153 +     */
   5.154 +    public String toString() {
   5.155 +        StringBuilder sb = new StringBuilder(getClass().getName());
   5.156 +        sb.append("[propertyName=").append(getPropertyName());
   5.157 +        appendTo(sb);
   5.158 +        sb.append("; oldValue=").append(getOldValue());
   5.159 +        sb.append("; newValue=").append(getNewValue());
   5.160 +        sb.append("; propagationId=").append(getPropagationId());
   5.161 +        sb.append("; source=").append(getSource());
   5.162 +        return sb.append("]").toString();
   5.163 +    }
   5.164 +
   5.165 +    void appendTo(StringBuilder sb) {
   5.166 +    }
   5.167 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/emul/compact/src/main/java/java/beans/PropertyChangeListener.java	Tue Feb 05 17:04:22 2013 +0100
     6.3 @@ -0,0 +1,44 @@
     6.4 +/*
     6.5 + * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
     6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.7 + *
     6.8 + * This code is free software; you can redistribute it and/or modify it
     6.9 + * under the terms of the GNU General Public License version 2 only, as
    6.10 + * published by the Free Software Foundation.  Oracle designates this
    6.11 + * particular file as subject to the "Classpath" exception as provided
    6.12 + * by Oracle in the LICENSE file that accompanied this code.
    6.13 + *
    6.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    6.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    6.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    6.17 + * version 2 for more details (a copy is included in the LICENSE file that
    6.18 + * accompanied this code).
    6.19 + *
    6.20 + * You should have received a copy of the GNU General Public License version
    6.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    6.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    6.23 + *
    6.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    6.25 + * or visit www.oracle.com if you need additional information or have any
    6.26 + * questions.
    6.27 + */
    6.28 +
    6.29 +package java.beans;
    6.30 +
    6.31 +/**
    6.32 + * A "PropertyChange" event gets fired whenever a bean changes a "bound"
    6.33 + * property.  You can register a PropertyChangeListener with a source
    6.34 + * bean so as to be notified of any bound property updates.
    6.35 + */
    6.36 +
    6.37 +public interface PropertyChangeListener extends java.util.EventListener {
    6.38 +
    6.39 +    /**
    6.40 +     * This method gets called when a bound property is changed.
    6.41 +     * @param evt A PropertyChangeEvent object describing the event source
    6.42 +     *          and the property that has changed.
    6.43 +     */
    6.44 +
    6.45 +    void propertyChange(PropertyChangeEvent evt);
    6.46 +
    6.47 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/emul/compact/src/main/java/java/beans/PropertyChangeListenerProxy.java	Tue Feb 05 17:04:22 2013 +0100
     7.3 @@ -0,0 +1,81 @@
     7.4 +/*
     7.5 + * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
     7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 + *
     7.8 + * This code is free software; you can redistribute it and/or modify it
     7.9 + * under the terms of the GNU General Public License version 2 only, as
    7.10 + * published by the Free Software Foundation.  Oracle designates this
    7.11 + * particular file as subject to the "Classpath" exception as provided
    7.12 + * by Oracle in the LICENSE file that accompanied this code.
    7.13 + *
    7.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    7.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.17 + * version 2 for more details (a copy is included in the LICENSE file that
    7.18 + * accompanied this code).
    7.19 + *
    7.20 + * You should have received a copy of the GNU General Public License version
    7.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    7.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.23 + *
    7.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    7.25 + * or visit www.oracle.com if you need additional information or have any
    7.26 + * questions.
    7.27 + */
    7.28 +
    7.29 +package java.beans;
    7.30 +
    7.31 +import java.util.EventListenerProxy;
    7.32 +
    7.33 +/**
    7.34 + * A class which extends the {@code EventListenerProxy}
    7.35 + * specifically for adding a {@code PropertyChangeListener}
    7.36 + * with a "bound" property.
    7.37 + * Instances of this class can be added
    7.38 + * as {@code PropertyChangeListener}s to a bean
    7.39 + * which supports firing property change events.
    7.40 + * <p>
    7.41 + * If the object has a {@code getPropertyChangeListeners} method
    7.42 + * then the array returned could be a mixture of {@code PropertyChangeListener}
    7.43 + * and {@code PropertyChangeListenerProxy} objects.
    7.44 + *
    7.45 + * @see java.util.EventListenerProxy
    7.46 + * @see PropertyChangeSupport#getPropertyChangeListeners
    7.47 + * @since 1.4
    7.48 + */
    7.49 +public class PropertyChangeListenerProxy
    7.50 +        extends EventListenerProxy<PropertyChangeListener>
    7.51 +        implements PropertyChangeListener {
    7.52 +
    7.53 +    private final String propertyName;
    7.54 +
    7.55 +    /**
    7.56 +     * Constructor which binds the {@code PropertyChangeListener}
    7.57 +     * to a specific property.
    7.58 +     *
    7.59 +     * @param propertyName  the name of the property to listen on
    7.60 +     * @param listener      the listener object
    7.61 +     */
    7.62 +    public PropertyChangeListenerProxy(String propertyName, PropertyChangeListener listener) {
    7.63 +        super(listener);
    7.64 +        this.propertyName = propertyName;
    7.65 +    }
    7.66 +
    7.67 +    /**
    7.68 +     * Forwards the property change event to the listener delegate.
    7.69 +     *
    7.70 +     * @param event  the property change event
    7.71 +     */
    7.72 +    public void propertyChange(PropertyChangeEvent event) {
    7.73 +        getListener().propertyChange(event);
    7.74 +    }
    7.75 +
    7.76 +    /**
    7.77 +     * Returns the name of the named property associated with the listener.
    7.78 +     *
    7.79 +     * @return the name of the named property associated with the listener
    7.80 +     */
    7.81 +    public String getPropertyName() {
    7.82 +        return this.propertyName;
    7.83 +    }
    7.84 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/emul/compact/src/main/java/java/beans/PropertyChangeSupport.java	Tue Feb 05 17:04:22 2013 +0100
     8.3 @@ -0,0 +1,536 @@
     8.4 +/*
     8.5 + * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
     8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.7 + *
     8.8 + * This code is free software; you can redistribute it and/or modify it
     8.9 + * under the terms of the GNU General Public License version 2 only, as
    8.10 + * published by the Free Software Foundation.  Oracle designates this
    8.11 + * particular file as subject to the "Classpath" exception as provided
    8.12 + * by Oracle in the LICENSE file that accompanied this code.
    8.13 + *
    8.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    8.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    8.17 + * version 2 for more details (a copy is included in the LICENSE file that
    8.18 + * accompanied this code).
    8.19 + *
    8.20 + * You should have received a copy of the GNU General Public License version
    8.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    8.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    8.23 + *
    8.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    8.25 + * or visit www.oracle.com if you need additional information or have any
    8.26 + * questions.
    8.27 + */
    8.28 +package java.beans;
    8.29 +
    8.30 +import java.io.Serializable;
    8.31 +import java.io.ObjectStreamField;
    8.32 +import java.io.ObjectOutputStream;
    8.33 +import java.io.ObjectInputStream;
    8.34 +import java.io.IOException;
    8.35 +import java.util.Hashtable;
    8.36 +import java.util.Map.Entry;
    8.37 +
    8.38 +/**
    8.39 + * This is a utility class that can be used by beans that support bound
    8.40 + * properties.  It manages a list of listeners and dispatches
    8.41 + * {@link PropertyChangeEvent}s to them.  You can use an instance of this class
    8.42 + * as a member field of your bean and delegate these types of work to it.
    8.43 + * The {@link PropertyChangeListener} can be registered for all properties
    8.44 + * or for a property specified by name.
    8.45 + * <p>
    8.46 + * Here is an example of {@code PropertyChangeSupport} usage that follows
    8.47 + * the rules and recommendations laid out in the JavaBeans&trade; specification:
    8.48 + * <pre>
    8.49 + * public class MyBean {
    8.50 + *     private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
    8.51 + *
    8.52 + *     public void addPropertyChangeListener(PropertyChangeListener listener) {
    8.53 + *         this.pcs.addPropertyChangeListener(listener);
    8.54 + *     }
    8.55 + *
    8.56 + *     public void removePropertyChangeListener(PropertyChangeListener listener) {
    8.57 + *         this.pcs.removePropertyChangeListener(listener);
    8.58 + *     }
    8.59 + *
    8.60 + *     private String value;
    8.61 + *
    8.62 + *     public String getValue() {
    8.63 + *         return this.value;
    8.64 + *     }
    8.65 + *
    8.66 + *     public void setValue(String newValue) {
    8.67 + *         String oldValue = this.value;
    8.68 + *         this.value = newValue;
    8.69 + *         this.pcs.firePropertyChange("value", oldValue, newValue);
    8.70 + *     }
    8.71 + *
    8.72 + *     [...]
    8.73 + * }
    8.74 + * </pre>
    8.75 + * <p>
    8.76 + * A {@code PropertyChangeSupport} instance is thread-safe.
    8.77 + * <p>
    8.78 + * This class is serializable.  When it is serialized it will save
    8.79 + * (and restore) any listeners that are themselves serializable.  Any
    8.80 + * non-serializable listeners will be skipped during serialization.
    8.81 + *
    8.82 + * @see VetoableChangeSupport
    8.83 + */
    8.84 +public class PropertyChangeSupport implements Serializable {
    8.85 +    private PropertyChangeListenerMap map = new PropertyChangeListenerMap();
    8.86 +
    8.87 +    /**
    8.88 +     * Constructs a <code>PropertyChangeSupport</code> object.
    8.89 +     *
    8.90 +     * @param sourceBean  The bean to be given as the source for any events.
    8.91 +     */
    8.92 +    public PropertyChangeSupport(Object sourceBean) {
    8.93 +        if (sourceBean == null) {
    8.94 +            throw new NullPointerException();
    8.95 +        }
    8.96 +        source = sourceBean;
    8.97 +    }
    8.98 +
    8.99 +    /**
   8.100 +     * Add a PropertyChangeListener to the listener list.
   8.101 +     * The listener is registered for all properties.
   8.102 +     * The same listener object may be added more than once, and will be called
   8.103 +     * as many times as it is added.
   8.104 +     * If <code>listener</code> is null, no exception is thrown and no action
   8.105 +     * is taken.
   8.106 +     *
   8.107 +     * @param listener  The PropertyChangeListener to be added
   8.108 +     */
   8.109 +    public void addPropertyChangeListener(PropertyChangeListener listener) {
   8.110 +        if (listener == null) {
   8.111 +            return;
   8.112 +        }
   8.113 +        if (listener instanceof PropertyChangeListenerProxy) {
   8.114 +            PropertyChangeListenerProxy proxy =
   8.115 +                   (PropertyChangeListenerProxy)listener;
   8.116 +            // Call two argument add method.
   8.117 +            addPropertyChangeListener(proxy.getPropertyName(),
   8.118 +                                      proxy.getListener());
   8.119 +        } else {
   8.120 +            this.map.add(null, listener);
   8.121 +        }
   8.122 +    }
   8.123 +
   8.124 +    /**
   8.125 +     * Remove a PropertyChangeListener from the listener list.
   8.126 +     * This removes a PropertyChangeListener that was registered
   8.127 +     * for all properties.
   8.128 +     * If <code>listener</code> was added more than once to the same event
   8.129 +     * source, it will be notified one less time after being removed.
   8.130 +     * If <code>listener</code> is null, or was never added, no exception is
   8.131 +     * thrown and no action is taken.
   8.132 +     *
   8.133 +     * @param listener  The PropertyChangeListener to be removed
   8.134 +     */
   8.135 +    public void removePropertyChangeListener(PropertyChangeListener listener) {
   8.136 +        if (listener == null) {
   8.137 +            return;
   8.138 +        }
   8.139 +        if (listener instanceof PropertyChangeListenerProxy) {
   8.140 +            PropertyChangeListenerProxy proxy =
   8.141 +                    (PropertyChangeListenerProxy)listener;
   8.142 +            // Call two argument remove method.
   8.143 +            removePropertyChangeListener(proxy.getPropertyName(),
   8.144 +                                         proxy.getListener());
   8.145 +        } else {
   8.146 +            this.map.remove(null, listener);
   8.147 +        }
   8.148 +    }
   8.149 +
   8.150 +    /**
   8.151 +     * Returns an array of all the listeners that were added to the
   8.152 +     * PropertyChangeSupport object with addPropertyChangeListener().
   8.153 +     * <p>
   8.154 +     * If some listeners have been added with a named property, then
   8.155 +     * the returned array will be a mixture of PropertyChangeListeners
   8.156 +     * and <code>PropertyChangeListenerProxy</code>s. If the calling
   8.157 +     * method is interested in distinguishing the listeners then it must
   8.158 +     * test each element to see if it's a
   8.159 +     * <code>PropertyChangeListenerProxy</code>, perform the cast, and examine
   8.160 +     * the parameter.
   8.161 +     *
   8.162 +     * <pre>
   8.163 +     * PropertyChangeListener[] listeners = bean.getPropertyChangeListeners();
   8.164 +     * for (int i = 0; i < listeners.length; i++) {
   8.165 +     *   if (listeners[i] instanceof PropertyChangeListenerProxy) {
   8.166 +     *     PropertyChangeListenerProxy proxy =
   8.167 +     *                    (PropertyChangeListenerProxy)listeners[i];
   8.168 +     *     if (proxy.getPropertyName().equals("foo")) {
   8.169 +     *       // proxy is a PropertyChangeListener which was associated
   8.170 +     *       // with the property named "foo"
   8.171 +     *     }
   8.172 +     *   }
   8.173 +     * }
   8.174 +     *</pre>
   8.175 +     *
   8.176 +     * @see PropertyChangeListenerProxy
   8.177 +     * @return all of the <code>PropertyChangeListeners</code> added or an
   8.178 +     *         empty array if no listeners have been added
   8.179 +     * @since 1.4
   8.180 +     */
   8.181 +    public PropertyChangeListener[] getPropertyChangeListeners() {
   8.182 +        return this.map.getListeners();
   8.183 +    }
   8.184 +
   8.185 +    /**
   8.186 +     * Add a PropertyChangeListener for a specific property.  The listener
   8.187 +     * will be invoked only when a call on firePropertyChange names that
   8.188 +     * specific property.
   8.189 +     * The same listener object may be added more than once.  For each
   8.190 +     * property,  the listener will be invoked the number of times it was added
   8.191 +     * for that property.
   8.192 +     * If <code>propertyName</code> or <code>listener</code> is null, no
   8.193 +     * exception is thrown and no action is taken.
   8.194 +     *
   8.195 +     * @param propertyName  The name of the property to listen on.
   8.196 +     * @param listener  The PropertyChangeListener to be added
   8.197 +     */
   8.198 +    public void addPropertyChangeListener(
   8.199 +                String propertyName,
   8.200 +                PropertyChangeListener listener) {
   8.201 +        if (listener == null || propertyName == null) {
   8.202 +            return;
   8.203 +        }
   8.204 +        listener = this.map.extract(listener);
   8.205 +        if (listener != null) {
   8.206 +            this.map.add(propertyName, listener);
   8.207 +        }
   8.208 +    }
   8.209 +
   8.210 +    /**
   8.211 +     * Remove a PropertyChangeListener for a specific property.
   8.212 +     * If <code>listener</code> was added more than once to the same event
   8.213 +     * source for the specified property, it will be notified one less time
   8.214 +     * after being removed.
   8.215 +     * If <code>propertyName</code> is null,  no exception is thrown and no
   8.216 +     * action is taken.
   8.217 +     * If <code>listener</code> is null, or was never added for the specified
   8.218 +     * property, no exception is thrown and no action is taken.
   8.219 +     *
   8.220 +     * @param propertyName  The name of the property that was listened on.
   8.221 +     * @param listener  The PropertyChangeListener to be removed
   8.222 +     */
   8.223 +    public void removePropertyChangeListener(
   8.224 +                String propertyName,
   8.225 +                PropertyChangeListener listener) {
   8.226 +        if (listener == null || propertyName == null) {
   8.227 +            return;
   8.228 +        }
   8.229 +        listener = this.map.extract(listener);
   8.230 +        if (listener != null) {
   8.231 +            this.map.remove(propertyName, listener);
   8.232 +        }
   8.233 +    }
   8.234 +
   8.235 +    /**
   8.236 +     * Returns an array of all the listeners which have been associated
   8.237 +     * with the named property.
   8.238 +     *
   8.239 +     * @param propertyName  The name of the property being listened to
   8.240 +     * @return all of the <code>PropertyChangeListeners</code> associated with
   8.241 +     *         the named property.  If no such listeners have been added,
   8.242 +     *         or if <code>propertyName</code> is null, an empty array is
   8.243 +     *         returned.
   8.244 +     * @since 1.4
   8.245 +     */
   8.246 +    public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
   8.247 +        return this.map.getListeners(propertyName);
   8.248 +    }
   8.249 +
   8.250 +    /**
   8.251 +     * Reports a bound property update to listeners
   8.252 +     * that have been registered to track updates of
   8.253 +     * all properties or a property with the specified name.
   8.254 +     * <p>
   8.255 +     * No event is fired if old and new values are equal and non-null.
   8.256 +     * <p>
   8.257 +     * This is merely a convenience wrapper around the more general
   8.258 +     * {@link #firePropertyChange(PropertyChangeEvent)} method.
   8.259 +     *
   8.260 +     * @param propertyName  the programmatic name of the property that was changed
   8.261 +     * @param oldValue      the old value of the property
   8.262 +     * @param newValue      the new value of the property
   8.263 +     */
   8.264 +    public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
   8.265 +        if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
   8.266 +            firePropertyChange(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue));
   8.267 +        }
   8.268 +    }
   8.269 +
   8.270 +    /**
   8.271 +     * Reports an integer bound property update to listeners
   8.272 +     * that have been registered to track updates of
   8.273 +     * all properties or a property with the specified name.
   8.274 +     * <p>
   8.275 +     * No event is fired if old and new values are equal.
   8.276 +     * <p>
   8.277 +     * This is merely a convenience wrapper around the more general
   8.278 +     * {@link #firePropertyChange(String, Object, Object)}  method.
   8.279 +     *
   8.280 +     * @param propertyName  the programmatic name of the property that was changed
   8.281 +     * @param oldValue      the old value of the property
   8.282 +     * @param newValue      the new value of the property
   8.283 +     */
   8.284 +    public void firePropertyChange(String propertyName, int oldValue, int newValue) {
   8.285 +        if (oldValue != newValue) {
   8.286 +            firePropertyChange(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue));
   8.287 +        }
   8.288 +    }
   8.289 +
   8.290 +    /**
   8.291 +     * Reports a boolean bound property update to listeners
   8.292 +     * that have been registered to track updates of
   8.293 +     * all properties or a property with the specified name.
   8.294 +     * <p>
   8.295 +     * No event is fired if old and new values are equal.
   8.296 +     * <p>
   8.297 +     * This is merely a convenience wrapper around the more general
   8.298 +     * {@link #firePropertyChange(String, Object, Object)}  method.
   8.299 +     *
   8.300 +     * @param propertyName  the programmatic name of the property that was changed
   8.301 +     * @param oldValue      the old value of the property
   8.302 +     * @param newValue      the new value of the property
   8.303 +     */
   8.304 +    public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
   8.305 +        if (oldValue != newValue) {
   8.306 +            firePropertyChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
   8.307 +        }
   8.308 +    }
   8.309 +
   8.310 +    /**
   8.311 +     * Fires a property change event to listeners
   8.312 +     * that have been registered to track updates of
   8.313 +     * all properties or a property with the specified name.
   8.314 +     * <p>
   8.315 +     * No event is fired if the given event's old and new values are equal and non-null.
   8.316 +     *
   8.317 +     * @param event  the {@code PropertyChangeEvent} to be fired
   8.318 +     */
   8.319 +    public void firePropertyChange(PropertyChangeEvent event) {
   8.320 +        Object oldValue = event.getOldValue();
   8.321 +        Object newValue = event.getNewValue();
   8.322 +        if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
   8.323 +            String name = event.getPropertyName();
   8.324 +
   8.325 +            PropertyChangeListener[] common = this.map.get(null);
   8.326 +            PropertyChangeListener[] named = (name != null)
   8.327 +                        ? this.map.get(name)
   8.328 +                        : null;
   8.329 +
   8.330 +            fire(common, event);
   8.331 +            fire(named, event);
   8.332 +        }
   8.333 +    }
   8.334 +
   8.335 +    private static void fire(PropertyChangeListener[] listeners, PropertyChangeEvent event) {
   8.336 +        if (listeners != null) {
   8.337 +            for (PropertyChangeListener listener : listeners) {
   8.338 +                listener.propertyChange(event);
   8.339 +            }
   8.340 +        }
   8.341 +    }
   8.342 +
   8.343 +    /**
   8.344 +     * Reports a bound indexed property update to listeners
   8.345 +     * that have been registered to track updates of
   8.346 +     * all properties or a property with the specified name.
   8.347 +     * <p>
   8.348 +     * No event is fired if old and new values are equal and non-null.
   8.349 +     * <p>
   8.350 +     * This is merely a convenience wrapper around the more general
   8.351 +     * {@link #firePropertyChange(PropertyChangeEvent)} method.
   8.352 +     *
   8.353 +     * @param propertyName  the programmatic name of the property that was changed
   8.354 +     * @param index         the index of the property element that was changed
   8.355 +     * @param oldValue      the old value of the property
   8.356 +     * @param newValue      the new value of the property
   8.357 +     * @since 1.5
   8.358 +     */
   8.359 +    public void fireIndexedPropertyChange(String propertyName, int index, Object oldValue, Object newValue) {
   8.360 +        if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
   8.361 +            firePropertyChange(new IndexedPropertyChangeEvent(source, propertyName, oldValue, newValue, index));
   8.362 +        }
   8.363 +    }
   8.364 +
   8.365 +    /**
   8.366 +     * Reports an integer bound indexed property update to listeners
   8.367 +     * that have been registered to track updates of
   8.368 +     * all properties or a property with the specified name.
   8.369 +     * <p>
   8.370 +     * No event is fired if old and new values are equal.
   8.371 +     * <p>
   8.372 +     * This is merely a convenience wrapper around the more general
   8.373 +     * {@link #fireIndexedPropertyChange(String, int, Object, Object)} method.
   8.374 +     *
   8.375 +     * @param propertyName  the programmatic name of the property that was changed
   8.376 +     * @param index         the index of the property element that was changed
   8.377 +     * @param oldValue      the old value of the property
   8.378 +     * @param newValue      the new value of the property
   8.379 +     * @since 1.5
   8.380 +     */
   8.381 +    public void fireIndexedPropertyChange(String propertyName, int index, int oldValue, int newValue) {
   8.382 +        if (oldValue != newValue) {
   8.383 +            fireIndexedPropertyChange(propertyName, index, Integer.valueOf(oldValue), Integer.valueOf(newValue));
   8.384 +        }
   8.385 +    }
   8.386 +
   8.387 +    /**
   8.388 +     * Reports a boolean bound indexed property update to listeners
   8.389 +     * that have been registered to track updates of
   8.390 +     * all properties or a property with the specified name.
   8.391 +     * <p>
   8.392 +     * No event is fired if old and new values are equal.
   8.393 +     * <p>
   8.394 +     * This is merely a convenience wrapper around the more general
   8.395 +     * {@link #fireIndexedPropertyChange(String, int, Object, Object)} method.
   8.396 +     *
   8.397 +     * @param propertyName  the programmatic name of the property that was changed
   8.398 +     * @param index         the index of the property element that was changed
   8.399 +     * @param oldValue      the old value of the property
   8.400 +     * @param newValue      the new value of the property
   8.401 +     * @since 1.5
   8.402 +     */
   8.403 +    public void fireIndexedPropertyChange(String propertyName, int index, boolean oldValue, boolean newValue) {
   8.404 +        if (oldValue != newValue) {
   8.405 +            fireIndexedPropertyChange(propertyName, index, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
   8.406 +        }
   8.407 +    }
   8.408 +
   8.409 +    /**
   8.410 +     * Check if there are any listeners for a specific property, including
   8.411 +     * those registered on all properties.  If <code>propertyName</code>
   8.412 +     * is null, only check for listeners registered on all properties.
   8.413 +     *
   8.414 +     * @param propertyName  the property name.
   8.415 +     * @return true if there are one or more listeners for the given property
   8.416 +     */
   8.417 +    public boolean hasListeners(String propertyName) {
   8.418 +        return this.map.hasListeners(propertyName);
   8.419 +    }
   8.420 +
   8.421 +    /**
   8.422 +     * @serialData Null terminated list of <code>PropertyChangeListeners</code>.
   8.423 +     * <p>
   8.424 +     * At serialization time we skip non-serializable listeners and
   8.425 +     * only serialize the serializable listeners.
   8.426 +     */
   8.427 +    private void writeObject(ObjectOutputStream s) throws IOException {
   8.428 +        Hashtable<String, PropertyChangeSupport> children = null;
   8.429 +        PropertyChangeListener[] listeners = null;
   8.430 +        synchronized (this.map) {
   8.431 +            for (Entry<String, PropertyChangeListener[]> entry : this.map.getEntries()) {
   8.432 +                String property = entry.getKey();
   8.433 +                if (property == null) {
   8.434 +                    listeners = entry.getValue();
   8.435 +                } else {
   8.436 +                    if (children == null) {
   8.437 +                        children = new Hashtable<String, PropertyChangeSupport>();
   8.438 +                    }
   8.439 +                    PropertyChangeSupport pcs = new PropertyChangeSupport(this.source);
   8.440 +                    pcs.map.set(null, entry.getValue());
   8.441 +                    children.put(property, pcs);
   8.442 +                }
   8.443 +            }
   8.444 +        }
   8.445 +        ObjectOutputStream.PutField fields = s.putFields();
   8.446 +        fields.put("children", children);
   8.447 +        fields.put("source", this.source);
   8.448 +        fields.put("propertyChangeSupportSerializedDataVersion", 2);
   8.449 +        s.writeFields();
   8.450 +
   8.451 +        if (listeners != null) {
   8.452 +            for (PropertyChangeListener l : listeners) {
   8.453 +                if (l instanceof Serializable) {
   8.454 +                    s.writeObject(l);
   8.455 +                }
   8.456 +            }
   8.457 +        }
   8.458 +        s.writeObject(null);
   8.459 +    }
   8.460 +
   8.461 +    private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
   8.462 +        this.map = new PropertyChangeListenerMap();
   8.463 +
   8.464 +        ObjectInputStream.GetField fields = s.readFields();
   8.465 +
   8.466 +        Hashtable<String, PropertyChangeSupport> children = (Hashtable<String, PropertyChangeSupport>) fields.get("children", null);
   8.467 +        this.source = fields.get("source", null);
   8.468 +        fields.get("propertyChangeSupportSerializedDataVersion", 2);
   8.469 +
   8.470 +        Object listenerOrNull;
   8.471 +        while (null != (listenerOrNull = s.readObject())) {
   8.472 +            this.map.add(null, (PropertyChangeListener)listenerOrNull);
   8.473 +        }
   8.474 +        if (children != null) {
   8.475 +            for (Entry<String, PropertyChangeSupport> entry : children.entrySet()) {
   8.476 +                for (PropertyChangeListener listener : entry.getValue().getPropertyChangeListeners()) {
   8.477 +                    this.map.add(entry.getKey(), listener);
   8.478 +                }
   8.479 +            }
   8.480 +        }
   8.481 +    }
   8.482 +
   8.483 +    /**
   8.484 +     * The object to be provided as the "source" for any generated events.
   8.485 +     */
   8.486 +    private Object source;
   8.487 +
   8.488 +    /**
   8.489 +     * @serialField children                                   Hashtable
   8.490 +     * @serialField source                                     Object
   8.491 +     * @serialField propertyChangeSupportSerializedDataVersion int
   8.492 +     */
   8.493 +    private static final ObjectStreamField[] serialPersistentFields = {
   8.494 +            new ObjectStreamField("children", Hashtable.class),
   8.495 +            new ObjectStreamField("source", Object.class),
   8.496 +            new ObjectStreamField("propertyChangeSupportSerializedDataVersion", Integer.TYPE)
   8.497 +    };
   8.498 +
   8.499 +    /**
   8.500 +     * Serialization version ID, so we're compatible with JDK 1.1
   8.501 +     */
   8.502 +    static final long serialVersionUID = 6401253773779951803L;
   8.503 +
   8.504 +    /**
   8.505 +     * This is a {@link ChangeListenerMap ChangeListenerMap} implementation
   8.506 +     * that works with {@link PropertyChangeListener PropertyChangeListener} objects.
   8.507 +     */
   8.508 +    private static final class PropertyChangeListenerMap extends ChangeListenerMap<PropertyChangeListener> {
   8.509 +        private static final PropertyChangeListener[] EMPTY = {};
   8.510 +
   8.511 +        /**
   8.512 +         * Creates an array of {@link PropertyChangeListener PropertyChangeListener} objects.
   8.513 +         * This method uses the same instance of the empty array
   8.514 +         * when {@code length} equals {@code 0}.
   8.515 +         *
   8.516 +         * @param length  the array length
   8.517 +         * @return        an array with specified length
   8.518 +         */
   8.519 +        @Override
   8.520 +        protected PropertyChangeListener[] newArray(int length) {
   8.521 +            return (0 < length)
   8.522 +                    ? new PropertyChangeListener[length]
   8.523 +                    : EMPTY;
   8.524 +        }
   8.525 +
   8.526 +        /**
   8.527 +         * Creates a {@link PropertyChangeListenerProxy PropertyChangeListenerProxy}
   8.528 +         * object for the specified property.
   8.529 +         *
   8.530 +         * @param name      the name of the property to listen on
   8.531 +         * @param listener  the listener to process events
   8.532 +         * @return          a {@code PropertyChangeListenerProxy} object
   8.533 +         */
   8.534 +        @Override
   8.535 +        protected PropertyChangeListener newProxy(String name, PropertyChangeListener listener) {
   8.536 +            return new PropertyChangeListenerProxy(name, listener);
   8.537 +        }
   8.538 +    }
   8.539 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/emul/compact/src/main/java/java/beans/PropertyVetoException.java	Tue Feb 05 17:04:22 2013 +0100
     9.3 @@ -0,0 +1,64 @@
     9.4 +/*
     9.5 + * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
     9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.7 + *
     9.8 + * This code is free software; you can redistribute it and/or modify it
     9.9 + * under the terms of the GNU General Public License version 2 only, as
    9.10 + * published by the Free Software Foundation.  Oracle designates this
    9.11 + * particular file as subject to the "Classpath" exception as provided
    9.12 + * by Oracle in the LICENSE file that accompanied this code.
    9.13 + *
    9.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    9.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    9.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    9.17 + * version 2 for more details (a copy is included in the LICENSE file that
    9.18 + * accompanied this code).
    9.19 + *
    9.20 + * You should have received a copy of the GNU General Public License version
    9.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    9.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    9.23 + *
    9.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    9.25 + * or visit www.oracle.com if you need additional information or have any
    9.26 + * questions.
    9.27 + */
    9.28 +
    9.29 +package java.beans;
    9.30 +
    9.31 +
    9.32 +/**
    9.33 + * A PropertyVetoException is thrown when a proposed change to a
    9.34 + * property represents an unacceptable value.
    9.35 + */
    9.36 +
    9.37 +public
    9.38 +class PropertyVetoException extends Exception {
    9.39 +    private static final long serialVersionUID = 129596057694162164L;
    9.40 +
    9.41 +    /**
    9.42 +     * Constructs a <code>PropertyVetoException</code> with a
    9.43 +     * detailed message.
    9.44 +     *
    9.45 +     * @param mess Descriptive message
    9.46 +     * @param evt A PropertyChangeEvent describing the vetoed change.
    9.47 +     */
    9.48 +    public PropertyVetoException(String mess, PropertyChangeEvent evt) {
    9.49 +        super(mess);
    9.50 +        this.evt = evt;
    9.51 +    }
    9.52 +
    9.53 +     /**
    9.54 +     * Gets the vetoed <code>PropertyChangeEvent</code>.
    9.55 +     *
    9.56 +     * @return A PropertyChangeEvent describing the vetoed change.
    9.57 +     */
    9.58 +    public PropertyChangeEvent getPropertyChangeEvent() {
    9.59 +        return evt;
    9.60 +    }
    9.61 +
    9.62 +    /**
    9.63 +     * A PropertyChangeEvent describing the vetoed change.
    9.64 +     * @serial
    9.65 +     */
    9.66 +    private PropertyChangeEvent evt;
    9.67 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/emul/compact/src/main/java/java/beans/VetoableChangeListener.java	Tue Feb 05 17:04:22 2013 +0100
    10.3 @@ -0,0 +1,44 @@
    10.4 +/*
    10.5 + * Copyright (c) 1996, 1997, Oracle and/or its affiliates. All rights reserved.
    10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.7 + *
    10.8 + * This code is free software; you can redistribute it and/or modify it
    10.9 + * under the terms of the GNU General Public License version 2 only, as
   10.10 + * published by the Free Software Foundation.  Oracle designates this
   10.11 + * particular file as subject to the "Classpath" exception as provided
   10.12 + * by Oracle in the LICENSE file that accompanied this code.
   10.13 + *
   10.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   10.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   10.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   10.17 + * version 2 for more details (a copy is included in the LICENSE file that
   10.18 + * accompanied this code).
   10.19 + *
   10.20 + * You should have received a copy of the GNU General Public License version
   10.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   10.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   10.23 + *
   10.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   10.25 + * or visit www.oracle.com if you need additional information or have any
   10.26 + * questions.
   10.27 + */
   10.28 +
   10.29 +package java.beans;
   10.30 +
   10.31 +/**
   10.32 + * A VetoableChange event gets fired whenever a bean changes a "constrained"
   10.33 + * property.  You can register a VetoableChangeListener with a source bean
   10.34 + * so as to be notified of any constrained property updates.
   10.35 + */
   10.36 +public interface VetoableChangeListener extends java.util.EventListener {
   10.37 +    /**
   10.38 +     * This method gets called when a constrained property is changed.
   10.39 +     *
   10.40 +     * @param     evt a <code>PropertyChangeEvent</code> object describing the
   10.41 +     *                event source and the property that has changed.
   10.42 +     * @exception PropertyVetoException if the recipient wishes the property
   10.43 +     *              change to be rolled back.
   10.44 +     */
   10.45 +    void vetoableChange(PropertyChangeEvent evt)
   10.46 +                                throws PropertyVetoException;
   10.47 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/emul/compact/src/main/java/java/beans/VetoableChangeListenerProxy.java	Tue Feb 05 17:04:22 2013 +0100
    11.3 @@ -0,0 +1,84 @@
    11.4 +/*
    11.5 + * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
    11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.7 + *
    11.8 + * This code is free software; you can redistribute it and/or modify it
    11.9 + * under the terms of the GNU General Public License version 2 only, as
   11.10 + * published by the Free Software Foundation.  Oracle designates this
   11.11 + * particular file as subject to the "Classpath" exception as provided
   11.12 + * by Oracle in the LICENSE file that accompanied this code.
   11.13 + *
   11.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   11.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   11.17 + * version 2 for more details (a copy is included in the LICENSE file that
   11.18 + * accompanied this code).
   11.19 + *
   11.20 + * You should have received a copy of the GNU General Public License version
   11.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   11.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   11.23 + *
   11.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   11.25 + * or visit www.oracle.com if you need additional information or have any
   11.26 + * questions.
   11.27 + */
   11.28 +
   11.29 +package java.beans;
   11.30 +
   11.31 +import java.util.EventListenerProxy;
   11.32 +
   11.33 +/**
   11.34 + * A class which extends the {@code EventListenerProxy}
   11.35 + * specifically for adding a {@code VetoableChangeListener}
   11.36 + * with a "constrained" property.
   11.37 + * Instances of this class can be added
   11.38 + * as {@code VetoableChangeListener}s to a bean
   11.39 + * which supports firing vetoable change events.
   11.40 + * <p>
   11.41 + * If the object has a {@code getVetoableChangeListeners} method
   11.42 + * then the array returned could be a mixture of {@code VetoableChangeListener}
   11.43 + * and {@code VetoableChangeListenerProxy} objects.
   11.44 + *
   11.45 + * @see java.util.EventListenerProxy
   11.46 + * @see VetoableChangeSupport#getVetoableChangeListeners
   11.47 + * @since 1.4
   11.48 + */
   11.49 +public class VetoableChangeListenerProxy
   11.50 +        extends EventListenerProxy<VetoableChangeListener>
   11.51 +        implements VetoableChangeListener {
   11.52 +
   11.53 +    private final String propertyName;
   11.54 +
   11.55 +    /**
   11.56 +     * Constructor which binds the {@code VetoableChangeListener}
   11.57 +     * to a specific property.
   11.58 +     *
   11.59 +     * @param propertyName  the name of the property to listen on
   11.60 +     * @param listener      the listener object
   11.61 +     */
   11.62 +    public VetoableChangeListenerProxy(String propertyName, VetoableChangeListener listener) {
   11.63 +        super(listener);
   11.64 +        this.propertyName = propertyName;
   11.65 +    }
   11.66 +
   11.67 +    /**
   11.68 +    * Forwards the property change event to the listener delegate.
   11.69 +    *
   11.70 +    * @param event  the property change event
   11.71 +    *
   11.72 +    * @exception PropertyVetoException if the recipient wishes the property
   11.73 +    *                                  change to be rolled back
   11.74 +    */
   11.75 +    public void vetoableChange(PropertyChangeEvent event) throws PropertyVetoException{
   11.76 +        getListener().vetoableChange(event);
   11.77 +    }
   11.78 +
   11.79 +    /**
   11.80 +     * Returns the name of the named property associated with the listener.
   11.81 +     *
   11.82 +     * @return the name of the named property associated with the listener
   11.83 +     */
   11.84 +    public String getPropertyName() {
   11.85 +        return this.propertyName;
   11.86 +    }
   11.87 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/emul/compact/src/main/java/java/beans/VetoableChangeSupport.java	Tue Feb 05 17:04:22 2013 +0100
    12.3 @@ -0,0 +1,526 @@
    12.4 +/*
    12.5 + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
    12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    12.7 + *
    12.8 + * This code is free software; you can redistribute it and/or modify it
    12.9 + * under the terms of the GNU General Public License version 2 only, as
   12.10 + * published by the Free Software Foundation.  Oracle designates this
   12.11 + * particular file as subject to the "Classpath" exception as provided
   12.12 + * by Oracle in the LICENSE file that accompanied this code.
   12.13 + *
   12.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   12.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   12.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   12.17 + * version 2 for more details (a copy is included in the LICENSE file that
   12.18 + * accompanied this code).
   12.19 + *
   12.20 + * You should have received a copy of the GNU General Public License version
   12.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   12.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   12.23 + *
   12.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   12.25 + * or visit www.oracle.com if you need additional information or have any
   12.26 + * questions.
   12.27 + */
   12.28 +package java.beans;
   12.29 +
   12.30 +import java.io.Serializable;
   12.31 +import java.io.ObjectStreamField;
   12.32 +import java.io.ObjectOutputStream;
   12.33 +import java.io.ObjectInputStream;
   12.34 +import java.io.IOException;
   12.35 +import java.util.Hashtable;
   12.36 +import java.util.Map.Entry;
   12.37 +import org.apidesign.bck2brwsr.emul.lang.System;
   12.38 +
   12.39 +/**
   12.40 + * This is a utility class that can be used by beans that support constrained
   12.41 + * properties.  It manages a list of listeners and dispatches
   12.42 + * {@link PropertyChangeEvent}s to them.  You can use an instance of this class
   12.43 + * as a member field of your bean and delegate these types of work to it.
   12.44 + * The {@link VetoableChangeListener} can be registered for all properties
   12.45 + * or for a property specified by name.
   12.46 + * <p>
   12.47 + * Here is an example of {@code VetoableChangeSupport} usage that follows
   12.48 + * the rules and recommendations laid out in the JavaBeans&trade; specification:
   12.49 + * <pre>
   12.50 + * public class MyBean {
   12.51 + *     private final VetoableChangeSupport vcs = new VetoableChangeSupport(this);
   12.52 + *
   12.53 + *     public void addVetoableChangeListener(VetoableChangeListener listener) {
   12.54 + *         this.vcs.addVetoableChangeListener(listener);
   12.55 + *     }
   12.56 + *
   12.57 + *     public void removeVetoableChangeListener(VetoableChangeListener listener) {
   12.58 + *         this.vcs.removeVetoableChangeListener(listener);
   12.59 + *     }
   12.60 + *
   12.61 + *     private String value;
   12.62 + *
   12.63 + *     public String getValue() {
   12.64 + *         return this.value;
   12.65 + *     }
   12.66 + *
   12.67 + *     public void setValue(String newValue) throws PropertyVetoException {
   12.68 + *         String oldValue = this.value;
   12.69 + *         this.vcs.fireVetoableChange("value", oldValue, newValue);
   12.70 + *         this.value = newValue;
   12.71 + *     }
   12.72 + *
   12.73 + *     [...]
   12.74 + * }
   12.75 + * </pre>
   12.76 + * <p>
   12.77 + * A {@code VetoableChangeSupport} instance is thread-safe.
   12.78 + * <p>
   12.79 + * This class is serializable.  When it is serialized it will save
   12.80 + * (and restore) any listeners that are themselves serializable.  Any
   12.81 + * non-serializable listeners will be skipped during serialization.
   12.82 + *
   12.83 + * @see PropertyChangeSupport
   12.84 + */
   12.85 +public class VetoableChangeSupport implements Serializable {
   12.86 +    private VetoableChangeListenerMap map = new VetoableChangeListenerMap();
   12.87 +
   12.88 +    /**
   12.89 +     * Constructs a <code>VetoableChangeSupport</code> object.
   12.90 +     *
   12.91 +     * @param sourceBean  The bean to be given as the source for any events.
   12.92 +     */
   12.93 +    public VetoableChangeSupport(Object sourceBean) {
   12.94 +        if (sourceBean == null) {
   12.95 +            throw new NullPointerException();
   12.96 +        }
   12.97 +        source = sourceBean;
   12.98 +    }
   12.99 +
  12.100 +    /**
  12.101 +     * Add a VetoableChangeListener to the listener list.
  12.102 +     * The listener is registered for all properties.
  12.103 +     * The same listener object may be added more than once, and will be called
  12.104 +     * as many times as it is added.
  12.105 +     * If <code>listener</code> is null, no exception is thrown and no action
  12.106 +     * is taken.
  12.107 +     *
  12.108 +     * @param listener  The VetoableChangeListener to be added
  12.109 +     */
  12.110 +    public void addVetoableChangeListener(VetoableChangeListener listener) {
  12.111 +        if (listener == null) {
  12.112 +            return;
  12.113 +        }
  12.114 +        if (listener instanceof VetoableChangeListenerProxy) {
  12.115 +            VetoableChangeListenerProxy proxy =
  12.116 +                    (VetoableChangeListenerProxy)listener;
  12.117 +            // Call two argument add method.
  12.118 +            addVetoableChangeListener(proxy.getPropertyName(),
  12.119 +                                      proxy.getListener());
  12.120 +        } else {
  12.121 +            this.map.add(null, listener);
  12.122 +        }
  12.123 +    }
  12.124 +
  12.125 +    /**
  12.126 +     * Remove a VetoableChangeListener from the listener list.
  12.127 +     * This removes a VetoableChangeListener that was registered
  12.128 +     * for all properties.
  12.129 +     * If <code>listener</code> was added more than once to the same event
  12.130 +     * source, it will be notified one less time after being removed.
  12.131 +     * If <code>listener</code> is null, or was never added, no exception is
  12.132 +     * thrown and no action is taken.
  12.133 +     *
  12.134 +     * @param listener  The VetoableChangeListener to be removed
  12.135 +     */
  12.136 +    public void removeVetoableChangeListener(VetoableChangeListener listener) {
  12.137 +        if (listener == null) {
  12.138 +            return;
  12.139 +        }
  12.140 +        if (listener instanceof VetoableChangeListenerProxy) {
  12.141 +            VetoableChangeListenerProxy proxy =
  12.142 +                    (VetoableChangeListenerProxy)listener;
  12.143 +            // Call two argument remove method.
  12.144 +            removeVetoableChangeListener(proxy.getPropertyName(),
  12.145 +                                         proxy.getListener());
  12.146 +        } else {
  12.147 +            this.map.remove(null, listener);
  12.148 +        }
  12.149 +    }
  12.150 +
  12.151 +    /**
  12.152 +     * Returns an array of all the listeners that were added to the
  12.153 +     * VetoableChangeSupport object with addVetoableChangeListener().
  12.154 +     * <p>
  12.155 +     * If some listeners have been added with a named property, then
  12.156 +     * the returned array will be a mixture of VetoableChangeListeners
  12.157 +     * and <code>VetoableChangeListenerProxy</code>s. If the calling
  12.158 +     * method is interested in distinguishing the listeners then it must
  12.159 +     * test each element to see if it's a
  12.160 +     * <code>VetoableChangeListenerProxy</code>, perform the cast, and examine
  12.161 +     * the parameter.
  12.162 +     *
  12.163 +     * <pre>
  12.164 +     * VetoableChangeListener[] listeners = bean.getVetoableChangeListeners();
  12.165 +     * for (int i = 0; i < listeners.length; i++) {
  12.166 +     *        if (listeners[i] instanceof VetoableChangeListenerProxy) {
  12.167 +     *     VetoableChangeListenerProxy proxy =
  12.168 +     *                    (VetoableChangeListenerProxy)listeners[i];
  12.169 +     *     if (proxy.getPropertyName().equals("foo")) {
  12.170 +     *       // proxy is a VetoableChangeListener which was associated
  12.171 +     *       // with the property named "foo"
  12.172 +     *     }
  12.173 +     *   }
  12.174 +     * }
  12.175 +     *</pre>
  12.176 +     *
  12.177 +     * @see VetoableChangeListenerProxy
  12.178 +     * @return all of the <code>VetoableChangeListeners</code> added or an
  12.179 +     *         empty array if no listeners have been added
  12.180 +     * @since 1.4
  12.181 +     */
  12.182 +    public VetoableChangeListener[] getVetoableChangeListeners(){
  12.183 +        return this.map.getListeners();
  12.184 +    }
  12.185 +
  12.186 +    /**
  12.187 +     * Add a VetoableChangeListener for a specific property.  The listener
  12.188 +     * will be invoked only when a call on fireVetoableChange names that
  12.189 +     * specific property.
  12.190 +     * The same listener object may be added more than once.  For each
  12.191 +     * property,  the listener will be invoked the number of times it was added
  12.192 +     * for that property.
  12.193 +     * If <code>propertyName</code> or <code>listener</code> is null, no
  12.194 +     * exception is thrown and no action is taken.
  12.195 +     *
  12.196 +     * @param propertyName  The name of the property to listen on.
  12.197 +     * @param listener  The VetoableChangeListener to be added
  12.198 +     */
  12.199 +    public void addVetoableChangeListener(
  12.200 +                                String propertyName,
  12.201 +                VetoableChangeListener listener) {
  12.202 +        if (listener == null || propertyName == null) {
  12.203 +            return;
  12.204 +        }
  12.205 +        listener = this.map.extract(listener);
  12.206 +        if (listener != null) {
  12.207 +            this.map.add(propertyName, listener);
  12.208 +        }
  12.209 +    }
  12.210 +
  12.211 +    /**
  12.212 +     * Remove a VetoableChangeListener for a specific property.
  12.213 +     * If <code>listener</code> was added more than once to the same event
  12.214 +     * source for the specified property, it will be notified one less time
  12.215 +     * after being removed.
  12.216 +     * If <code>propertyName</code> is null, no exception is thrown and no
  12.217 +     * action is taken.
  12.218 +     * If <code>listener</code> is null, or was never added for the specified
  12.219 +     * property, no exception is thrown and no action is taken.
  12.220 +     *
  12.221 +     * @param propertyName  The name of the property that was listened on.
  12.222 +     * @param listener  The VetoableChangeListener to be removed
  12.223 +     */
  12.224 +    public void removeVetoableChangeListener(
  12.225 +                                String propertyName,
  12.226 +                VetoableChangeListener listener) {
  12.227 +        if (listener == null || propertyName == null) {
  12.228 +            return;
  12.229 +        }
  12.230 +        listener = this.map.extract(listener);
  12.231 +        if (listener != null) {
  12.232 +            this.map.remove(propertyName, listener);
  12.233 +        }
  12.234 +    }
  12.235 +
  12.236 +    /**
  12.237 +     * Returns an array of all the listeners which have been associated
  12.238 +     * with the named property.
  12.239 +     *
  12.240 +     * @param propertyName  The name of the property being listened to
  12.241 +     * @return all the <code>VetoableChangeListeners</code> associated with
  12.242 +     *         the named property.  If no such listeners have been added,
  12.243 +     *         or if <code>propertyName</code> is null, an empty array is
  12.244 +     *         returned.
  12.245 +     * @since 1.4
  12.246 +     */
  12.247 +    public VetoableChangeListener[] getVetoableChangeListeners(String propertyName) {
  12.248 +        return this.map.getListeners(propertyName);
  12.249 +    }
  12.250 +
  12.251 +    /**
  12.252 +     * Reports a constrained property update to listeners
  12.253 +     * that have been registered to track updates of
  12.254 +     * all properties or a property with the specified name.
  12.255 +     * <p>
  12.256 +     * Any listener can throw a {@code PropertyVetoException} to veto the update.
  12.257 +     * If one of the listeners vetoes the update, this method passes
  12.258 +     * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
  12.259 +     * to all listeners that already confirmed this update
  12.260 +     * and throws the {@code PropertyVetoException} again.
  12.261 +     * <p>
  12.262 +     * No event is fired if old and new values are equal and non-null.
  12.263 +     * <p>
  12.264 +     * This is merely a convenience wrapper around the more general
  12.265 +     * {@link #fireVetoableChange(PropertyChangeEvent)} method.
  12.266 +     *
  12.267 +     * @param propertyName  the programmatic name of the property that is about to change
  12.268 +     * @param oldValue      the old value of the property
  12.269 +     * @param newValue      the new value of the property
  12.270 +     * @throws PropertyVetoException if one of listeners vetoes the property update
  12.271 +     */
  12.272 +    public void fireVetoableChange(String propertyName, Object oldValue, Object newValue)
  12.273 +            throws PropertyVetoException {
  12.274 +        if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
  12.275 +            fireVetoableChange(new PropertyChangeEvent(this.source, propertyName, oldValue, newValue));
  12.276 +        }
  12.277 +    }
  12.278 +
  12.279 +    /**
  12.280 +     * Reports an integer constrained property update to listeners
  12.281 +     * that have been registered to track updates of
  12.282 +     * all properties or a property with the specified name.
  12.283 +     * <p>
  12.284 +     * Any listener can throw a {@code PropertyVetoException} to veto the update.
  12.285 +     * If one of the listeners vetoes the update, this method passes
  12.286 +     * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
  12.287 +     * to all listeners that already confirmed this update
  12.288 +     * and throws the {@code PropertyVetoException} again.
  12.289 +     * <p>
  12.290 +     * No event is fired if old and new values are equal.
  12.291 +     * <p>
  12.292 +     * This is merely a convenience wrapper around the more general
  12.293 +     * {@link #fireVetoableChange(String, Object, Object)} method.
  12.294 +     *
  12.295 +     * @param propertyName  the programmatic name of the property that is about to change
  12.296 +     * @param oldValue      the old value of the property
  12.297 +     * @param newValue      the new value of the property
  12.298 +     * @throws PropertyVetoException if one of listeners vetoes the property update
  12.299 +     */
  12.300 +    public void fireVetoableChange(String propertyName, int oldValue, int newValue)
  12.301 +            throws PropertyVetoException {
  12.302 +        if (oldValue != newValue) {
  12.303 +            fireVetoableChange(propertyName, Integer.valueOf(oldValue), Integer.valueOf(newValue));
  12.304 +        }
  12.305 +    }
  12.306 +
  12.307 +    /**
  12.308 +     * Reports a boolean constrained property update to listeners
  12.309 +     * that have been registered to track updates of
  12.310 +     * all properties or a property with the specified name.
  12.311 +     * <p>
  12.312 +     * Any listener can throw a {@code PropertyVetoException} to veto the update.
  12.313 +     * If one of the listeners vetoes the update, this method passes
  12.314 +     * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
  12.315 +     * to all listeners that already confirmed this update
  12.316 +     * and throws the {@code PropertyVetoException} again.
  12.317 +     * <p>
  12.318 +     * No event is fired if old and new values are equal.
  12.319 +     * <p>
  12.320 +     * This is merely a convenience wrapper around the more general
  12.321 +     * {@link #fireVetoableChange(String, Object, Object)} method.
  12.322 +     *
  12.323 +     * @param propertyName  the programmatic name of the property that is about to change
  12.324 +     * @param oldValue      the old value of the property
  12.325 +     * @param newValue      the new value of the property
  12.326 +     * @throws PropertyVetoException if one of listeners vetoes the property update
  12.327 +     */
  12.328 +    public void fireVetoableChange(String propertyName, boolean oldValue, boolean newValue)
  12.329 +            throws PropertyVetoException {
  12.330 +        if (oldValue != newValue) {
  12.331 +            fireVetoableChange(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
  12.332 +        }
  12.333 +    }
  12.334 +
  12.335 +    /**
  12.336 +     * Fires a property change event to listeners
  12.337 +     * that have been registered to track updates of
  12.338 +     * all properties or a property with the specified name.
  12.339 +     * <p>
  12.340 +     * Any listener can throw a {@code PropertyVetoException} to veto the update.
  12.341 +     * If one of the listeners vetoes the update, this method passes
  12.342 +     * a new "undo" {@code PropertyChangeEvent} that reverts to the old value
  12.343 +     * to all listeners that already confirmed this update
  12.344 +     * and throws the {@code PropertyVetoException} again.
  12.345 +     * <p>
  12.346 +     * No event is fired if the given event's old and new values are equal and non-null.
  12.347 +     *
  12.348 +     * @param event  the {@code PropertyChangeEvent} to be fired
  12.349 +     * @throws PropertyVetoException if one of listeners vetoes the property update
  12.350 +     */
  12.351 +    public void fireVetoableChange(PropertyChangeEvent event)
  12.352 +            throws PropertyVetoException {
  12.353 +        Object oldValue = event.getOldValue();
  12.354 +        Object newValue = event.getNewValue();
  12.355 +        if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
  12.356 +            String name = event.getPropertyName();
  12.357 +
  12.358 +            VetoableChangeListener[] common = this.map.get(null);
  12.359 +            VetoableChangeListener[] named = (name != null)
  12.360 +                        ? this.map.get(name)
  12.361 +                        : null;
  12.362 +
  12.363 +            VetoableChangeListener[] listeners;
  12.364 +            if (common == null) {
  12.365 +                listeners = named;
  12.366 +            }
  12.367 +            else if (named == null) {
  12.368 +                listeners = common;
  12.369 +            }
  12.370 +            else {
  12.371 +                listeners = new VetoableChangeListener[common.length + named.length];
  12.372 +                System.arraycopy(common, 0, listeners, 0, common.length);
  12.373 +                System.arraycopy(named, 0, listeners, common.length, named.length);
  12.374 +            }
  12.375 +            if (listeners != null) {
  12.376 +                int current = 0;
  12.377 +                try {
  12.378 +                    while (current < listeners.length) {
  12.379 +                        listeners[current].vetoableChange(event);
  12.380 +                        current++;
  12.381 +                    }
  12.382 +                }
  12.383 +                catch (PropertyVetoException veto) {
  12.384 +                    event = new PropertyChangeEvent(this.source, name, newValue, oldValue);
  12.385 +                    for (int i = 0; i < current; i++) {
  12.386 +                        try {
  12.387 +                            listeners[i].vetoableChange(event);
  12.388 +                        }
  12.389 +                        catch (PropertyVetoException exception) {
  12.390 +                            // ignore exceptions that occur during rolling back
  12.391 +                        }
  12.392 +                    }
  12.393 +                    throw veto; // rethrow the veto exception
  12.394 +                }
  12.395 +            }
  12.396 +        }
  12.397 +    }
  12.398 +
  12.399 +    /**
  12.400 +     * Check if there are any listeners for a specific property, including
  12.401 +     * those registered on all properties.  If <code>propertyName</code>
  12.402 +     * is null, only check for listeners registered on all properties.
  12.403 +     *
  12.404 +     * @param propertyName  the property name.
  12.405 +     * @return true if there are one or more listeners for the given property
  12.406 +     */
  12.407 +    public boolean hasListeners(String propertyName) {
  12.408 +        return this.map.hasListeners(propertyName);
  12.409 +    }
  12.410 +
  12.411 +    /**
  12.412 +     * @serialData Null terminated list of <code>VetoableChangeListeners</code>.
  12.413 +     * <p>
  12.414 +     * At serialization time we skip non-serializable listeners and
  12.415 +     * only serialize the serializable listeners.
  12.416 +     */
  12.417 +    private void writeObject(ObjectOutputStream s) throws IOException {
  12.418 +        Hashtable<String, VetoableChangeSupport> children = null;
  12.419 +        VetoableChangeListener[] listeners = null;
  12.420 +        synchronized (this.map) {
  12.421 +            for (Entry<String, VetoableChangeListener[]> entry : this.map.getEntries()) {
  12.422 +                String property = entry.getKey();
  12.423 +                if (property == null) {
  12.424 +                    listeners = entry.getValue();
  12.425 +                } else {
  12.426 +                    if (children == null) {
  12.427 +                        children = new Hashtable<String, VetoableChangeSupport>();
  12.428 +                    }
  12.429 +                    VetoableChangeSupport vcs = new VetoableChangeSupport(this.source);
  12.430 +                    vcs.map.set(null, entry.getValue());
  12.431 +                    children.put(property, vcs);
  12.432 +                }
  12.433 +            }
  12.434 +        }
  12.435 +        ObjectOutputStream.PutField fields = s.putFields();
  12.436 +        fields.put("children", children);
  12.437 +        fields.put("source", this.source);
  12.438 +        fields.put("vetoableChangeSupportSerializedDataVersion", 2);
  12.439 +        s.writeFields();
  12.440 +
  12.441 +        if (listeners != null) {
  12.442 +            for (VetoableChangeListener l : listeners) {
  12.443 +                if (l instanceof Serializable) {
  12.444 +                    s.writeObject(l);
  12.445 +                }
  12.446 +            }
  12.447 +        }
  12.448 +        s.writeObject(null);
  12.449 +    }
  12.450 +
  12.451 +    private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
  12.452 +        this.map = new VetoableChangeListenerMap();
  12.453 +
  12.454 +        ObjectInputStream.GetField fields = s.readFields();
  12.455 +
  12.456 +        Hashtable<String, VetoableChangeSupport> children = (Hashtable<String, VetoableChangeSupport>) fields.get("children", null);
  12.457 +        this.source = fields.get("source", null);
  12.458 +        fields.get("vetoableChangeSupportSerializedDataVersion", 2);
  12.459 +
  12.460 +        Object listenerOrNull;
  12.461 +        while (null != (listenerOrNull = s.readObject())) {
  12.462 +            this.map.add(null, (VetoableChangeListener)listenerOrNull);
  12.463 +        }
  12.464 +        if (children != null) {
  12.465 +            for (Entry<String, VetoableChangeSupport> entry : children.entrySet()) {
  12.466 +                for (VetoableChangeListener listener : entry.getValue().getVetoableChangeListeners()) {
  12.467 +                    this.map.add(entry.getKey(), listener);
  12.468 +                }
  12.469 +            }
  12.470 +        }
  12.471 +    }
  12.472 +
  12.473 +    /**
  12.474 +     * The object to be provided as the "source" for any generated events.
  12.475 +     */
  12.476 +    private Object source;
  12.477 +
  12.478 +    /**
  12.479 +     * @serialField children                                   Hashtable
  12.480 +     * @serialField source                                     Object
  12.481 +     * @serialField vetoableChangeSupportSerializedDataVersion int
  12.482 +     */
  12.483 +    private static final ObjectStreamField[] serialPersistentFields = {
  12.484 +            new ObjectStreamField("children", Hashtable.class),
  12.485 +            new ObjectStreamField("source", Object.class),
  12.486 +            new ObjectStreamField("vetoableChangeSupportSerializedDataVersion", Integer.TYPE)
  12.487 +    };
  12.488 +
  12.489 +    /**
  12.490 +     * Serialization version ID, so we're compatible with JDK 1.1
  12.491 +     */
  12.492 +    static final long serialVersionUID = -5090210921595982017L;
  12.493 +
  12.494 +    /**
  12.495 +     * This is a {@link ChangeListenerMap ChangeListenerMap} implementation
  12.496 +     * that works with {@link VetoableChangeListener VetoableChangeListener} objects.
  12.497 +     */
  12.498 +    private static final class VetoableChangeListenerMap extends ChangeListenerMap<VetoableChangeListener> {
  12.499 +        private static final VetoableChangeListener[] EMPTY = {};
  12.500 +
  12.501 +        /**
  12.502 +         * Creates an array of {@link VetoableChangeListener VetoableChangeListener} objects.
  12.503 +         * This method uses the same instance of the empty array
  12.504 +         * when {@code length} equals {@code 0}.
  12.505 +         *
  12.506 +         * @param length  the array length
  12.507 +         * @return        an array with specified length
  12.508 +         */
  12.509 +        @Override
  12.510 +        protected VetoableChangeListener[] newArray(int length) {
  12.511 +            return (0 < length)
  12.512 +                    ? new VetoableChangeListener[length]
  12.513 +                    : EMPTY;
  12.514 +        }
  12.515 +
  12.516 +        /**
  12.517 +         * Creates a {@link VetoableChangeListenerProxy VetoableChangeListenerProxy}
  12.518 +         * object for the specified property.
  12.519 +         *
  12.520 +         * @param name      the name of the property to listen on
  12.521 +         * @param listener  the listener to process events
  12.522 +         * @return          a {@code VetoableChangeListenerProxy} object
  12.523 +         */
  12.524 +        @Override
  12.525 +        protected VetoableChangeListener newProxy(String name, VetoableChangeListener listener) {
  12.526 +            return new VetoableChangeListenerProxy(name, listener);
  12.527 +        }
  12.528 +    }
  12.529 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/emul/compact/src/main/java/java/io/Bits.java	Tue Feb 05 17:04:22 2013 +0100
    13.3 @@ -0,0 +1,123 @@
    13.4 +/*
    13.5 + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
    13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.7 + *
    13.8 + * This code is free software; you can redistribute it and/or modify it
    13.9 + * under the terms of the GNU General Public License version 2 only, as
   13.10 + * published by the Free Software Foundation.  Oracle designates this
   13.11 + * particular file as subject to the "Classpath" exception as provided
   13.12 + * by Oracle in the LICENSE file that accompanied this code.
   13.13 + *
   13.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   13.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.17 + * version 2 for more details (a copy is included in the LICENSE file that
   13.18 + * accompanied this code).
   13.19 + *
   13.20 + * You should have received a copy of the GNU General Public License version
   13.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   13.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.23 + *
   13.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   13.25 + * or visit www.oracle.com if you need additional information or have any
   13.26 + * questions.
   13.27 + */
   13.28 +
   13.29 +package java.io;
   13.30 +
   13.31 +/**
   13.32 + * Utility methods for packing/unpacking primitive values in/out of byte arrays
   13.33 + * using big-endian byte ordering.
   13.34 + */
   13.35 +class Bits {
   13.36 +
   13.37 +    /*
   13.38 +     * Methods for unpacking primitive values from byte arrays starting at
   13.39 +     * given offsets.
   13.40 +     */
   13.41 +
   13.42 +    static boolean getBoolean(byte[] b, int off) {
   13.43 +        return b[off] != 0;
   13.44 +    }
   13.45 +
   13.46 +    static char getChar(byte[] b, int off) {
   13.47 +        return (char) ((b[off + 1] & 0xFF) +
   13.48 +                       (b[off] << 8));
   13.49 +    }
   13.50 +
   13.51 +    static short getShort(byte[] b, int off) {
   13.52 +        return (short) ((b[off + 1] & 0xFF) +
   13.53 +                        (b[off] << 8));
   13.54 +    }
   13.55 +
   13.56 +    static int getInt(byte[] b, int off) {
   13.57 +        return ((b[off + 3] & 0xFF)      ) +
   13.58 +               ((b[off + 2] & 0xFF) <<  8) +
   13.59 +               ((b[off + 1] & 0xFF) << 16) +
   13.60 +               ((b[off    ]       ) << 24);
   13.61 +    }
   13.62 +
   13.63 +    static float getFloat(byte[] b, int off) {
   13.64 +        return Float.intBitsToFloat(getInt(b, off));
   13.65 +    }
   13.66 +
   13.67 +    static long getLong(byte[] b, int off) {
   13.68 +        return ((b[off + 7] & 0xFFL)      ) +
   13.69 +               ((b[off + 6] & 0xFFL) <<  8) +
   13.70 +               ((b[off + 5] & 0xFFL) << 16) +
   13.71 +               ((b[off + 4] & 0xFFL) << 24) +
   13.72 +               ((b[off + 3] & 0xFFL) << 32) +
   13.73 +               ((b[off + 2] & 0xFFL) << 40) +
   13.74 +               ((b[off + 1] & 0xFFL) << 48) +
   13.75 +               (((long) b[off])      << 56);
   13.76 +    }
   13.77 +
   13.78 +    static double getDouble(byte[] b, int off) {
   13.79 +        return Double.longBitsToDouble(getLong(b, off));
   13.80 +    }
   13.81 +
   13.82 +    /*
   13.83 +     * Methods for packing primitive values into byte arrays starting at given
   13.84 +     * offsets.
   13.85 +     */
   13.86 +
   13.87 +    static void putBoolean(byte[] b, int off, boolean val) {
   13.88 +        b[off] = (byte) (val ? 1 : 0);
   13.89 +    }
   13.90 +
   13.91 +    static void putChar(byte[] b, int off, char val) {
   13.92 +        b[off + 1] = (byte) (val      );
   13.93 +        b[off    ] = (byte) (val >>> 8);
   13.94 +    }
   13.95 +
   13.96 +    static void putShort(byte[] b, int off, short val) {
   13.97 +        b[off + 1] = (byte) (val      );
   13.98 +        b[off    ] = (byte) (val >>> 8);
   13.99 +    }
  13.100 +
  13.101 +    static void putInt(byte[] b, int off, int val) {
  13.102 +        b[off + 3] = (byte) (val       );
  13.103 +        b[off + 2] = (byte) (val >>>  8);
  13.104 +        b[off + 1] = (byte) (val >>> 16);
  13.105 +        b[off    ] = (byte) (val >>> 24);
  13.106 +    }
  13.107 +
  13.108 +    static void putFloat(byte[] b, int off, float val) {
  13.109 +        putInt(b, off,  Float.floatToIntBits(val));
  13.110 +    }
  13.111 +
  13.112 +    static void putLong(byte[] b, int off, long val) {
  13.113 +        b[off + 7] = (byte) (val       );
  13.114 +        b[off + 6] = (byte) (val >>>  8);
  13.115 +        b[off + 5] = (byte) (val >>> 16);
  13.116 +        b[off + 4] = (byte) (val >>> 24);
  13.117 +        b[off + 3] = (byte) (val >>> 32);
  13.118 +        b[off + 2] = (byte) (val >>> 40);
  13.119 +        b[off + 1] = (byte) (val >>> 48);
  13.120 +        b[off    ] = (byte) (val >>> 56);
  13.121 +    }
  13.122 +
  13.123 +    static void putDouble(byte[] b, int off, double val) {
  13.124 +        putLong(b, off, Double.doubleToLongBits(val));
  13.125 +    }
  13.126 +}
    14.1 --- a/emul/compact/src/main/java/java/io/BufferedReader.java	Tue Feb 05 16:40:01 2013 +0100
    14.2 +++ b/emul/compact/src/main/java/java/io/BufferedReader.java	Tue Feb 05 17:04:22 2013 +0100
    14.3 @@ -25,7 +25,6 @@
    14.4  
    14.5  package java.io;
    14.6  
    14.7 -import org.apidesign.bck2brwsr.emul.lang.System;
    14.8  
    14.9  
   14.10  /**
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/emul/compact/src/main/java/java/io/DataOutput.java	Tue Feb 05 17:04:22 2013 +0100
    15.3 @@ -0,0 +1,354 @@
    15.4 +/*
    15.5 + * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
    15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.7 + *
    15.8 + * This code is free software; you can redistribute it and/or modify it
    15.9 + * under the terms of the GNU General Public License version 2 only, as
   15.10 + * published by the Free Software Foundation.  Oracle designates this
   15.11 + * particular file as subject to the "Classpath" exception as provided
   15.12 + * by Oracle in the LICENSE file that accompanied this code.
   15.13 + *
   15.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   15.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   15.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   15.17 + * version 2 for more details (a copy is included in the LICENSE file that
   15.18 + * accompanied this code).
   15.19 + *
   15.20 + * You should have received a copy of the GNU General Public License version
   15.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   15.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   15.23 + *
   15.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   15.25 + * or visit www.oracle.com if you need additional information or have any
   15.26 + * questions.
   15.27 + */
   15.28 +
   15.29 +package java.io;
   15.30 +
   15.31 +/**
   15.32 + * The <code>DataOutput</code> interface provides
   15.33 + * for converting data from any of the Java
   15.34 + * primitive types to a series of bytes and
   15.35 + * writing these bytes to a binary stream.
   15.36 + * There is  also a facility for converting
   15.37 + * a <code>String</code> into
   15.38 + * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
   15.39 + * format and writing the resulting series
   15.40 + * of bytes.
   15.41 + * <p>
   15.42 + * For all the methods in this interface that
   15.43 + * write bytes, it is generally true that if
   15.44 + * a byte cannot be written for any reason,
   15.45 + * an <code>IOException</code> is thrown.
   15.46 + *
   15.47 + * @author  Frank Yellin
   15.48 + * @see     java.io.DataInput
   15.49 + * @see     java.io.DataOutputStream
   15.50 + * @since   JDK1.0
   15.51 + */
   15.52 +public
   15.53 +interface DataOutput {
   15.54 +    /**
   15.55 +     * Writes to the output stream the eight
   15.56 +     * low-order bits of the argument <code>b</code>.
   15.57 +     * The 24 high-order  bits of <code>b</code>
   15.58 +     * are ignored.
   15.59 +     *
   15.60 +     * @param      b   the byte to be written.
   15.61 +     * @throws     IOException  if an I/O error occurs.
   15.62 +     */
   15.63 +    void write(int b) throws IOException;
   15.64 +
   15.65 +    /**
   15.66 +     * Writes to the output stream all the bytes in array <code>b</code>.
   15.67 +     * If <code>b</code> is <code>null</code>,
   15.68 +     * a <code>NullPointerException</code> is thrown.
   15.69 +     * If <code>b.length</code> is zero, then
   15.70 +     * no bytes are written. Otherwise, the byte
   15.71 +     * <code>b[0]</code> is written first, then
   15.72 +     * <code>b[1]</code>, and so on; the last byte
   15.73 +     * written is <code>b[b.length-1]</code>.
   15.74 +     *
   15.75 +     * @param      b   the data.
   15.76 +     * @throws     IOException  if an I/O error occurs.
   15.77 +     */
   15.78 +    void write(byte b[]) throws IOException;
   15.79 +
   15.80 +    /**
   15.81 +     * Writes <code>len</code> bytes from array
   15.82 +     * <code>b</code>, in order,  to
   15.83 +     * the output stream.  If <code>b</code>
   15.84 +     * is <code>null</code>, a <code>NullPointerException</code>
   15.85 +     * is thrown.  If <code>off</code> is negative,
   15.86 +     * or <code>len</code> is negative, or <code>off+len</code>
   15.87 +     * is greater than the length of the array
   15.88 +     * <code>b</code>, then an <code>IndexOutOfBoundsException</code>
   15.89 +     * is thrown.  If <code>len</code> is zero,
   15.90 +     * then no bytes are written. Otherwise, the
   15.91 +     * byte <code>b[off]</code> is written first,
   15.92 +     * then <code>b[off+1]</code>, and so on; the
   15.93 +     * last byte written is <code>b[off+len-1]</code>.
   15.94 +     *
   15.95 +     * @param      b     the data.
   15.96 +     * @param      off   the start offset in the data.
   15.97 +     * @param      len   the number of bytes to write.
   15.98 +     * @throws     IOException  if an I/O error occurs.
   15.99 +     */
  15.100 +    void write(byte b[], int off, int len) throws IOException;
  15.101 +
  15.102 +    /**
  15.103 +     * Writes a <code>boolean</code> value to this output stream.
  15.104 +     * If the argument <code>v</code>
  15.105 +     * is <code>true</code>, the value <code>(byte)1</code>
  15.106 +     * is written; if <code>v</code> is <code>false</code>,
  15.107 +     * the  value <code>(byte)0</code> is written.
  15.108 +     * The byte written by this method may
  15.109 +     * be read by the <code>readBoolean</code>
  15.110 +     * method of interface <code>DataInput</code>,
  15.111 +     * which will then return a <code>boolean</code>
  15.112 +     * equal to <code>v</code>.
  15.113 +     *
  15.114 +     * @param      v   the boolean to be written.
  15.115 +     * @throws     IOException  if an I/O error occurs.
  15.116 +     */
  15.117 +    void writeBoolean(boolean v) throws IOException;
  15.118 +
  15.119 +    /**
  15.120 +     * Writes to the output stream the eight low-
  15.121 +     * order bits of the argument <code>v</code>.
  15.122 +     * The 24 high-order bits of <code>v</code>
  15.123 +     * are ignored. (This means  that <code>writeByte</code>
  15.124 +     * does exactly the same thing as <code>write</code>
  15.125 +     * for an integer argument.) The byte written
  15.126 +     * by this method may be read by the <code>readByte</code>
  15.127 +     * method of interface <code>DataInput</code>,
  15.128 +     * which will then return a <code>byte</code>
  15.129 +     * equal to <code>(byte)v</code>.
  15.130 +     *
  15.131 +     * @param      v   the byte value to be written.
  15.132 +     * @throws     IOException  if an I/O error occurs.
  15.133 +     */
  15.134 +    void writeByte(int v) throws IOException;
  15.135 +
  15.136 +    /**
  15.137 +     * Writes two bytes to the output
  15.138 +     * stream to represent the value of the argument.
  15.139 +     * The byte values to be written, in the  order
  15.140 +     * shown, are: <p>
  15.141 +     * <pre><code>
  15.142 +     * (byte)(0xff &amp; (v &gt;&gt; 8))
  15.143 +     * (byte)(0xff &amp; v)
  15.144 +     * </code> </pre> <p>
  15.145 +     * The bytes written by this method may be
  15.146 +     * read by the <code>readShort</code> method
  15.147 +     * of interface <code>DataInput</code> , which
  15.148 +     * will then return a <code>short</code> equal
  15.149 +     * to <code>(short)v</code>.
  15.150 +     *
  15.151 +     * @param      v   the <code>short</code> value to be written.
  15.152 +     * @throws     IOException  if an I/O error occurs.
  15.153 +     */
  15.154 +    void writeShort(int v) throws IOException;
  15.155 +
  15.156 +    /**
  15.157 +     * Writes a <code>char</code> value, which
  15.158 +     * is comprised of two bytes, to the
  15.159 +     * output stream.
  15.160 +     * The byte values to be written, in the  order
  15.161 +     * shown, are:
  15.162 +     * <p><pre><code>
  15.163 +     * (byte)(0xff &amp; (v &gt;&gt; 8))
  15.164 +     * (byte)(0xff &amp; v)
  15.165 +     * </code></pre><p>
  15.166 +     * The bytes written by this method may be
  15.167 +     * read by the <code>readChar</code> method
  15.168 +     * of interface <code>DataInput</code> , which
  15.169 +     * will then return a <code>char</code> equal
  15.170 +     * to <code>(char)v</code>.
  15.171 +     *
  15.172 +     * @param      v   the <code>char</code> value to be written.
  15.173 +     * @throws     IOException  if an I/O error occurs.
  15.174 +     */
  15.175 +    void writeChar(int v) throws IOException;
  15.176 +
  15.177 +    /**
  15.178 +     * Writes an <code>int</code> value, which is
  15.179 +     * comprised of four bytes, to the output stream.
  15.180 +     * The byte values to be written, in the  order
  15.181 +     * shown, are:
  15.182 +     * <p><pre><code>
  15.183 +     * (byte)(0xff &amp; (v &gt;&gt; 24))
  15.184 +     * (byte)(0xff &amp; (v &gt;&gt; 16))
  15.185 +     * (byte)(0xff &amp; (v &gt;&gt; &#32; &#32;8))
  15.186 +     * (byte)(0xff &amp; v)
  15.187 +     * </code></pre><p>
  15.188 +     * The bytes written by this method may be read
  15.189 +     * by the <code>readInt</code> method of interface
  15.190 +     * <code>DataInput</code> , which will then
  15.191 +     * return an <code>int</code> equal to <code>v</code>.
  15.192 +     *
  15.193 +     * @param      v   the <code>int</code> value to be written.
  15.194 +     * @throws     IOException  if an I/O error occurs.
  15.195 +     */
  15.196 +    void writeInt(int v) throws IOException;
  15.197 +
  15.198 +    /**
  15.199 +     * Writes a <code>long</code> value, which is
  15.200 +     * comprised of eight bytes, to the output stream.
  15.201 +     * The byte values to be written, in the  order
  15.202 +     * shown, are:
  15.203 +     * <p><pre><code>
  15.204 +     * (byte)(0xff &amp; (v &gt;&gt; 56))
  15.205 +     * (byte)(0xff &amp; (v &gt;&gt; 48))
  15.206 +     * (byte)(0xff &amp; (v &gt;&gt; 40))
  15.207 +     * (byte)(0xff &amp; (v &gt;&gt; 32))
  15.208 +     * (byte)(0xff &amp; (v &gt;&gt; 24))
  15.209 +     * (byte)(0xff &amp; (v &gt;&gt; 16))
  15.210 +     * (byte)(0xff &amp; (v &gt;&gt;  8))
  15.211 +     * (byte)(0xff &amp; v)
  15.212 +     * </code></pre><p>
  15.213 +     * The bytes written by this method may be
  15.214 +     * read by the <code>readLong</code> method
  15.215 +     * of interface <code>DataInput</code> , which
  15.216 +     * will then return a <code>long</code> equal
  15.217 +     * to <code>v</code>.
  15.218 +     *
  15.219 +     * @param      v   the <code>long</code> value to be written.
  15.220 +     * @throws     IOException  if an I/O error occurs.
  15.221 +     */
  15.222 +    void writeLong(long v) throws IOException;
  15.223 +
  15.224 +    /**
  15.225 +     * Writes a <code>float</code> value,
  15.226 +     * which is comprised of four bytes, to the output stream.
  15.227 +     * It does this as if it first converts this
  15.228 +     * <code>float</code> value to an <code>int</code>
  15.229 +     * in exactly the manner of the <code>Float.floatToIntBits</code>
  15.230 +     * method  and then writes the <code>int</code>
  15.231 +     * value in exactly the manner of the  <code>writeInt</code>
  15.232 +     * method.  The bytes written by this method
  15.233 +     * may be read by the <code>readFloat</code>
  15.234 +     * method of interface <code>DataInput</code>,
  15.235 +     * which will then return a <code>float</code>
  15.236 +     * equal to <code>v</code>.
  15.237 +     *
  15.238 +     * @param      v   the <code>float</code> value to be written.
  15.239 +     * @throws     IOException  if an I/O error occurs.
  15.240 +     */
  15.241 +    void writeFloat(float v) throws IOException;
  15.242 +
  15.243 +    /**
  15.244 +     * Writes a <code>double</code> value,
  15.245 +     * which is comprised of eight bytes, to the output stream.
  15.246 +     * It does this as if it first converts this
  15.247 +     * <code>double</code> value to a <code>long</code>
  15.248 +     * in exactly the manner of the <code>Double.doubleToLongBits</code>
  15.249 +     * method  and then writes the <code>long</code>
  15.250 +     * value in exactly the manner of the  <code>writeLong</code>
  15.251 +     * method. The bytes written by this method
  15.252 +     * may be read by the <code>readDouble</code>
  15.253 +     * method of interface <code>DataInput</code>,
  15.254 +     * which will then return a <code>double</code>
  15.255 +     * equal to <code>v</code>.
  15.256 +     *
  15.257 +     * @param      v   the <code>double</code> value to be written.
  15.258 +     * @throws     IOException  if an I/O error occurs.
  15.259 +     */
  15.260 +    void writeDouble(double v) throws IOException;
  15.261 +
  15.262 +    /**
  15.263 +     * Writes a string to the output stream.
  15.264 +     * For every character in the string
  15.265 +     * <code>s</code>,  taken in order, one byte
  15.266 +     * is written to the output stream.  If
  15.267 +     * <code>s</code> is <code>null</code>, a <code>NullPointerException</code>
  15.268 +     * is thrown.<p>  If <code>s.length</code>
  15.269 +     * is zero, then no bytes are written. Otherwise,
  15.270 +     * the character <code>s[0]</code> is written
  15.271 +     * first, then <code>s[1]</code>, and so on;
  15.272 +     * the last character written is <code>s[s.length-1]</code>.
  15.273 +     * For each character, one byte is written,
  15.274 +     * the low-order byte, in exactly the manner
  15.275 +     * of the <code>writeByte</code> method . The
  15.276 +     * high-order eight bits of each character
  15.277 +     * in the string are ignored.
  15.278 +     *
  15.279 +     * @param      s   the string of bytes to be written.
  15.280 +     * @throws     IOException  if an I/O error occurs.
  15.281 +     */
  15.282 +    void writeBytes(String s) throws IOException;
  15.283 +
  15.284 +    /**
  15.285 +     * Writes every character in the string <code>s</code>,
  15.286 +     * to the output stream, in order,
  15.287 +     * two bytes per character. If <code>s</code>
  15.288 +     * is <code>null</code>, a <code>NullPointerException</code>
  15.289 +     * is thrown.  If <code>s.length</code>
  15.290 +     * is zero, then no characters are written.
  15.291 +     * Otherwise, the character <code>s[0]</code>
  15.292 +     * is written first, then <code>s[1]</code>,
  15.293 +     * and so on; the last character written is
  15.294 +     * <code>s[s.length-1]</code>. For each character,
  15.295 +     * two bytes are actually written, high-order
  15.296 +     * byte first, in exactly the manner of the
  15.297 +     * <code>writeChar</code> method.
  15.298 +     *
  15.299 +     * @param      s   the string value to be written.
  15.300 +     * @throws     IOException  if an I/O error occurs.
  15.301 +     */
  15.302 +    void writeChars(String s) throws IOException;
  15.303 +
  15.304 +    /**
  15.305 +     * Writes two bytes of length information
  15.306 +     * to the output stream, followed
  15.307 +     * by the
  15.308 +     * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
  15.309 +     * representation
  15.310 +     * of  every character in the string <code>s</code>.
  15.311 +     * If <code>s</code> is <code>null</code>,
  15.312 +     * a <code>NullPointerException</code> is thrown.
  15.313 +     * Each character in the string <code>s</code>
  15.314 +     * is converted to a group of one, two, or
  15.315 +     * three bytes, depending on the value of the
  15.316 +     * character.<p>
  15.317 +     * If a character <code>c</code>
  15.318 +     * is in the range <code>&#92;u0001</code> through
  15.319 +     * <code>&#92;u007f</code>, it is represented
  15.320 +     * by one byte:<p>
  15.321 +     * <pre>(byte)c </pre>  <p>
  15.322 +     * If a character <code>c</code> is <code>&#92;u0000</code>
  15.323 +     * or is in the range <code>&#92;u0080</code>
  15.324 +     * through <code>&#92;u07ff</code>, then it is
  15.325 +     * represented by two bytes, to be written
  15.326 +     * in the order shown:<p> <pre><code>
  15.327 +     * (byte)(0xc0 | (0x1f &amp; (c &gt;&gt; 6)))
  15.328 +     * (byte)(0x80 | (0x3f &amp; c))
  15.329 +     *  </code></pre>  <p> If a character
  15.330 +     * <code>c</code> is in the range <code>&#92;u0800</code>
  15.331 +     * through <code>uffff</code>, then it is
  15.332 +     * represented by three bytes, to be written
  15.333 +     * in the order shown:<p> <pre><code>
  15.334 +     * (byte)(0xe0 | (0x0f &amp; (c &gt;&gt; 12)))
  15.335 +     * (byte)(0x80 | (0x3f &amp; (c &gt;&gt;  6)))
  15.336 +     * (byte)(0x80 | (0x3f &amp; c))
  15.337 +     *  </code></pre>  <p> First,
  15.338 +     * the total number of bytes needed to represent
  15.339 +     * all the characters of <code>s</code> is
  15.340 +     * calculated. If this number is larger than
  15.341 +     * <code>65535</code>, then a <code>UTFDataFormatException</code>
  15.342 +     * is thrown. Otherwise, this length is written
  15.343 +     * to the output stream in exactly the manner
  15.344 +     * of the <code>writeShort</code> method;
  15.345 +     * after this, the one-, two-, or three-byte
  15.346 +     * representation of each character in the
  15.347 +     * string <code>s</code> is written.<p>  The
  15.348 +     * bytes written by this method may be read
  15.349 +     * by the <code>readUTF</code> method of interface
  15.350 +     * <code>DataInput</code> , which will then
  15.351 +     * return a <code>String</code> equal to <code>s</code>.
  15.352 +     *
  15.353 +     * @param      s   the string value to be written.
  15.354 +     * @throws     IOException  if an I/O error occurs.
  15.355 +     */
  15.356 +    void writeUTF(String s) throws IOException;
  15.357 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/emul/compact/src/main/java/java/io/DataOutputStream.java	Tue Feb 05 17:04:22 2013 +0100
    16.3 @@ -0,0 +1,416 @@
    16.4 +/*
    16.5 + * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
    16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    16.7 + *
    16.8 + * This code is free software; you can redistribute it and/or modify it
    16.9 + * under the terms of the GNU General Public License version 2 only, as
   16.10 + * published by the Free Software Foundation.  Oracle designates this
   16.11 + * particular file as subject to the "Classpath" exception as provided
   16.12 + * by Oracle in the LICENSE file that accompanied this code.
   16.13 + *
   16.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   16.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   16.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   16.17 + * version 2 for more details (a copy is included in the LICENSE file that
   16.18 + * accompanied this code).
   16.19 + *
   16.20 + * You should have received a copy of the GNU General Public License version
   16.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   16.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   16.23 + *
   16.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   16.25 + * or visit www.oracle.com if you need additional information or have any
   16.26 + * questions.
   16.27 + */
   16.28 +
   16.29 +package java.io;
   16.30 +
   16.31 +/**
   16.32 + * A data output stream lets an application write primitive Java data
   16.33 + * types to an output stream in a portable way. An application can
   16.34 + * then use a data input stream to read the data back in.
   16.35 + *
   16.36 + * @author  unascribed
   16.37 + * @see     java.io.DataInputStream
   16.38 + * @since   JDK1.0
   16.39 + */
   16.40 +public
   16.41 +class DataOutputStream extends FilterOutputStream implements DataOutput {
   16.42 +    /**
   16.43 +     * The number of bytes written to the data output stream so far.
   16.44 +     * If this counter overflows, it will be wrapped to Integer.MAX_VALUE.
   16.45 +     */
   16.46 +    protected int written;
   16.47 +
   16.48 +    /**
   16.49 +     * bytearr is initialized on demand by writeUTF
   16.50 +     */
   16.51 +    private byte[] bytearr = null;
   16.52 +
   16.53 +    /**
   16.54 +     * Creates a new data output stream to write data to the specified
   16.55 +     * underlying output stream. The counter <code>written</code> is
   16.56 +     * set to zero.
   16.57 +     *
   16.58 +     * @param   out   the underlying output stream, to be saved for later
   16.59 +     *                use.
   16.60 +     * @see     java.io.FilterOutputStream#out
   16.61 +     */
   16.62 +    public DataOutputStream(OutputStream out) {
   16.63 +        super(out);
   16.64 +    }
   16.65 +
   16.66 +    /**
   16.67 +     * Increases the written counter by the specified value
   16.68 +     * until it reaches Integer.MAX_VALUE.
   16.69 +     */
   16.70 +    private void incCount(int value) {
   16.71 +        int temp = written + value;
   16.72 +        if (temp < 0) {
   16.73 +            temp = Integer.MAX_VALUE;
   16.74 +        }
   16.75 +        written = temp;
   16.76 +    }
   16.77 +
   16.78 +    /**
   16.79 +     * Writes the specified byte (the low eight bits of the argument
   16.80 +     * <code>b</code>) to the underlying output stream. If no exception
   16.81 +     * is thrown, the counter <code>written</code> is incremented by
   16.82 +     * <code>1</code>.
   16.83 +     * <p>
   16.84 +     * Implements the <code>write</code> method of <code>OutputStream</code>.
   16.85 +     *
   16.86 +     * @param      b   the <code>byte</code> to be written.
   16.87 +     * @exception  IOException  if an I/O error occurs.
   16.88 +     * @see        java.io.FilterOutputStream#out
   16.89 +     */
   16.90 +    public synchronized void write(int b) throws IOException {
   16.91 +        out.write(b);
   16.92 +        incCount(1);
   16.93 +    }
   16.94 +
   16.95 +    /**
   16.96 +     * Writes <code>len</code> bytes from the specified byte array
   16.97 +     * starting at offset <code>off</code> to the underlying output stream.
   16.98 +     * If no exception is thrown, the counter <code>written</code> is
   16.99 +     * incremented by <code>len</code>.
  16.100 +     *
  16.101 +     * @param      b     the data.
  16.102 +     * @param      off   the start offset in the data.
  16.103 +     * @param      len   the number of bytes to write.
  16.104 +     * @exception  IOException  if an I/O error occurs.
  16.105 +     * @see        java.io.FilterOutputStream#out
  16.106 +     */
  16.107 +    public synchronized void write(byte b[], int off, int len)
  16.108 +        throws IOException
  16.109 +    {
  16.110 +        out.write(b, off, len);
  16.111 +        incCount(len);
  16.112 +    }
  16.113 +
  16.114 +    /**
  16.115 +     * Flushes this data output stream. This forces any buffered output
  16.116 +     * bytes to be written out to the stream.
  16.117 +     * <p>
  16.118 +     * The <code>flush</code> method of <code>DataOutputStream</code>
  16.119 +     * calls the <code>flush</code> method of its underlying output stream.
  16.120 +     *
  16.121 +     * @exception  IOException  if an I/O error occurs.
  16.122 +     * @see        java.io.FilterOutputStream#out
  16.123 +     * @see        java.io.OutputStream#flush()
  16.124 +     */
  16.125 +    public void flush() throws IOException {
  16.126 +        out.flush();
  16.127 +    }
  16.128 +
  16.129 +    /**
  16.130 +     * Writes a <code>boolean</code> to the underlying output stream as
  16.131 +     * a 1-byte value. The value <code>true</code> is written out as the
  16.132 +     * value <code>(byte)1</code>; the value <code>false</code> is
  16.133 +     * written out as the value <code>(byte)0</code>. If no exception is
  16.134 +     * thrown, the counter <code>written</code> is incremented by
  16.135 +     * <code>1</code>.
  16.136 +     *
  16.137 +     * @param      v   a <code>boolean</code> value to be written.
  16.138 +     * @exception  IOException  if an I/O error occurs.
  16.139 +     * @see        java.io.FilterOutputStream#out
  16.140 +     */
  16.141 +    public final void writeBoolean(boolean v) throws IOException {
  16.142 +        out.write(v ? 1 : 0);
  16.143 +        incCount(1);
  16.144 +    }
  16.145 +
  16.146 +    /**
  16.147 +     * Writes out a <code>byte</code> to the underlying output stream as
  16.148 +     * a 1-byte value. If no exception is thrown, the counter
  16.149 +     * <code>written</code> is incremented by <code>1</code>.
  16.150 +     *
  16.151 +     * @param      v   a <code>byte</code> value to be written.
  16.152 +     * @exception  IOException  if an I/O error occurs.
  16.153 +     * @see        java.io.FilterOutputStream#out
  16.154 +     */
  16.155 +    public final void writeByte(int v) throws IOException {
  16.156 +        out.write(v);
  16.157 +        incCount(1);
  16.158 +    }
  16.159 +
  16.160 +    /**
  16.161 +     * Writes a <code>short</code> to the underlying output stream as two
  16.162 +     * bytes, high byte first. If no exception is thrown, the counter
  16.163 +     * <code>written</code> is incremented by <code>2</code>.
  16.164 +     *
  16.165 +     * @param      v   a <code>short</code> to be written.
  16.166 +     * @exception  IOException  if an I/O error occurs.
  16.167 +     * @see        java.io.FilterOutputStream#out
  16.168 +     */
  16.169 +    public final void writeShort(int v) throws IOException {
  16.170 +        out.write((v >>> 8) & 0xFF);
  16.171 +        out.write((v >>> 0) & 0xFF);
  16.172 +        incCount(2);
  16.173 +    }
  16.174 +
  16.175 +    /**
  16.176 +     * Writes a <code>char</code> to the underlying output stream as a
  16.177 +     * 2-byte value, high byte first. If no exception is thrown, the
  16.178 +     * counter <code>written</code> is incremented by <code>2</code>.
  16.179 +     *
  16.180 +     * @param      v   a <code>char</code> value to be written.
  16.181 +     * @exception  IOException  if an I/O error occurs.
  16.182 +     * @see        java.io.FilterOutputStream#out
  16.183 +     */
  16.184 +    public final void writeChar(int v) throws IOException {
  16.185 +        out.write((v >>> 8) & 0xFF);
  16.186 +        out.write((v >>> 0) & 0xFF);
  16.187 +        incCount(2);
  16.188 +    }
  16.189 +
  16.190 +    /**
  16.191 +     * Writes an <code>int</code> to the underlying output stream as four
  16.192 +     * bytes, high byte first. If no exception is thrown, the counter
  16.193 +     * <code>written</code> is incremented by <code>4</code>.
  16.194 +     *
  16.195 +     * @param      v   an <code>int</code> to be written.
  16.196 +     * @exception  IOException  if an I/O error occurs.
  16.197 +     * @see        java.io.FilterOutputStream#out
  16.198 +     */
  16.199 +    public final void writeInt(int v) throws IOException {
  16.200 +        out.write((v >>> 24) & 0xFF);
  16.201 +        out.write((v >>> 16) & 0xFF);
  16.202 +        out.write((v >>>  8) & 0xFF);
  16.203 +        out.write((v >>>  0) & 0xFF);
  16.204 +        incCount(4);
  16.205 +    }
  16.206 +
  16.207 +    private byte writeBuffer[] = new byte[8];
  16.208 +
  16.209 +    /**
  16.210 +     * Writes a <code>long</code> to the underlying output stream as eight
  16.211 +     * bytes, high byte first. In no exception is thrown, the counter
  16.212 +     * <code>written</code> is incremented by <code>8</code>.
  16.213 +     *
  16.214 +     * @param      v   a <code>long</code> to be written.
  16.215 +     * @exception  IOException  if an I/O error occurs.
  16.216 +     * @see        java.io.FilterOutputStream#out
  16.217 +     */
  16.218 +    public final void writeLong(long v) throws IOException {
  16.219 +        writeBuffer[0] = (byte)(v >>> 56);
  16.220 +        writeBuffer[1] = (byte)(v >>> 48);
  16.221 +        writeBuffer[2] = (byte)(v >>> 40);
  16.222 +        writeBuffer[3] = (byte)(v >>> 32);
  16.223 +        writeBuffer[4] = (byte)(v >>> 24);
  16.224 +        writeBuffer[5] = (byte)(v >>> 16);
  16.225 +        writeBuffer[6] = (byte)(v >>>  8);
  16.226 +        writeBuffer[7] = (byte)(v >>>  0);
  16.227 +        out.write(writeBuffer, 0, 8);
  16.228 +        incCount(8);
  16.229 +    }
  16.230 +
  16.231 +    /**
  16.232 +     * Converts the float argument to an <code>int</code> using the
  16.233 +     * <code>floatToIntBits</code> method in class <code>Float</code>,
  16.234 +     * and then writes that <code>int</code> value to the underlying
  16.235 +     * output stream as a 4-byte quantity, high byte first. If no
  16.236 +     * exception is thrown, the counter <code>written</code> is
  16.237 +     * incremented by <code>4</code>.
  16.238 +     *
  16.239 +     * @param      v   a <code>float</code> value to be written.
  16.240 +     * @exception  IOException  if an I/O error occurs.
  16.241 +     * @see        java.io.FilterOutputStream#out
  16.242 +     * @see        java.lang.Float#floatToIntBits(float)
  16.243 +     */
  16.244 +    public final void writeFloat(float v) throws IOException {
  16.245 +        writeInt(Float.floatToIntBits(v));
  16.246 +    }
  16.247 +
  16.248 +    /**
  16.249 +     * Converts the double argument to a <code>long</code> using the
  16.250 +     * <code>doubleToLongBits</code> method in class <code>Double</code>,
  16.251 +     * and then writes that <code>long</code> value to the underlying
  16.252 +     * output stream as an 8-byte quantity, high byte first. If no
  16.253 +     * exception is thrown, the counter <code>written</code> is
  16.254 +     * incremented by <code>8</code>.
  16.255 +     *
  16.256 +     * @param      v   a <code>double</code> value to be written.
  16.257 +     * @exception  IOException  if an I/O error occurs.
  16.258 +     * @see        java.io.FilterOutputStream#out
  16.259 +     * @see        java.lang.Double#doubleToLongBits(double)
  16.260 +     */
  16.261 +    public final void writeDouble(double v) throws IOException {
  16.262 +        writeLong(Double.doubleToLongBits(v));
  16.263 +    }
  16.264 +
  16.265 +    /**
  16.266 +     * Writes out the string to the underlying output stream as a
  16.267 +     * sequence of bytes. Each character in the string is written out, in
  16.268 +     * sequence, by discarding its high eight bits. If no exception is
  16.269 +     * thrown, the counter <code>written</code> is incremented by the
  16.270 +     * length of <code>s</code>.
  16.271 +     *
  16.272 +     * @param      s   a string of bytes to be written.
  16.273 +     * @exception  IOException  if an I/O error occurs.
  16.274 +     * @see        java.io.FilterOutputStream#out
  16.275 +     */
  16.276 +    public final void writeBytes(String s) throws IOException {
  16.277 +        int len = s.length();
  16.278 +        for (int i = 0 ; i < len ; i++) {
  16.279 +            out.write((byte)s.charAt(i));
  16.280 +        }
  16.281 +        incCount(len);
  16.282 +    }
  16.283 +
  16.284 +    /**
  16.285 +     * Writes a string to the underlying output stream as a sequence of
  16.286 +     * characters. Each character is written to the data output stream as
  16.287 +     * if by the <code>writeChar</code> method. If no exception is
  16.288 +     * thrown, the counter <code>written</code> is incremented by twice
  16.289 +     * the length of <code>s</code>.
  16.290 +     *
  16.291 +     * @param      s   a <code>String</code> value to be written.
  16.292 +     * @exception  IOException  if an I/O error occurs.
  16.293 +     * @see        java.io.DataOutputStream#writeChar(int)
  16.294 +     * @see        java.io.FilterOutputStream#out
  16.295 +     */
  16.296 +    public final void writeChars(String s) throws IOException {
  16.297 +        int len = s.length();
  16.298 +        for (int i = 0 ; i < len ; i++) {
  16.299 +            int v = s.charAt(i);
  16.300 +            out.write((v >>> 8) & 0xFF);
  16.301 +            out.write((v >>> 0) & 0xFF);
  16.302 +        }
  16.303 +        incCount(len * 2);
  16.304 +    }
  16.305 +
  16.306 +    /**
  16.307 +     * Writes a string to the underlying output stream using
  16.308 +     * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
  16.309 +     * encoding in a machine-independent manner.
  16.310 +     * <p>
  16.311 +     * First, two bytes are written to the output stream as if by the
  16.312 +     * <code>writeShort</code> method giving the number of bytes to
  16.313 +     * follow. This value is the number of bytes actually written out,
  16.314 +     * not the length of the string. Following the length, each character
  16.315 +     * of the string is output, in sequence, using the modified UTF-8 encoding
  16.316 +     * for the character. If no exception is thrown, the counter
  16.317 +     * <code>written</code> is incremented by the total number of
  16.318 +     * bytes written to the output stream. This will be at least two
  16.319 +     * plus the length of <code>str</code>, and at most two plus
  16.320 +     * thrice the length of <code>str</code>.
  16.321 +     *
  16.322 +     * @param      str   a string to be written.
  16.323 +     * @exception  IOException  if an I/O error occurs.
  16.324 +     */
  16.325 +    public final void writeUTF(String str) throws IOException {
  16.326 +        writeUTF(str, this);
  16.327 +    }
  16.328 +
  16.329 +    /**
  16.330 +     * Writes a string to the specified DataOutput using
  16.331 +     * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
  16.332 +     * encoding in a machine-independent manner.
  16.333 +     * <p>
  16.334 +     * First, two bytes are written to out as if by the <code>writeShort</code>
  16.335 +     * method giving the number of bytes to follow. This value is the number of
  16.336 +     * bytes actually written out, not the length of the string. Following the
  16.337 +     * length, each character of the string is output, in sequence, using the
  16.338 +     * modified UTF-8 encoding for the character. If no exception is thrown, the
  16.339 +     * counter <code>written</code> is incremented by the total number of
  16.340 +     * bytes written to the output stream. This will be at least two
  16.341 +     * plus the length of <code>str</code>, and at most two plus
  16.342 +     * thrice the length of <code>str</code>.
  16.343 +     *
  16.344 +     * @param      str   a string to be written.
  16.345 +     * @param      out   destination to write to
  16.346 +     * @return     The number of bytes written out.
  16.347 +     * @exception  IOException  if an I/O error occurs.
  16.348 +     */
  16.349 +    static int writeUTF(String str, DataOutput out) throws IOException {
  16.350 +        int strlen = str.length();
  16.351 +        int utflen = 0;
  16.352 +        int c, count = 0;
  16.353 +
  16.354 +        /* use charAt instead of copying String to char array */
  16.355 +        for (int i = 0; i < strlen; i++) {
  16.356 +            c = str.charAt(i);
  16.357 +            if ((c >= 0x0001) && (c <= 0x007F)) {
  16.358 +                utflen++;
  16.359 +            } else if (c > 0x07FF) {
  16.360 +                utflen += 3;
  16.361 +            } else {
  16.362 +                utflen += 2;
  16.363 +            }
  16.364 +        }
  16.365 +
  16.366 +        if (utflen > 65535)
  16.367 +            throw new UTFDataFormatException(
  16.368 +                "encoded string too long: " + utflen + " bytes");
  16.369 +
  16.370 +        byte[] bytearr = null;
  16.371 +        if (out instanceof DataOutputStream) {
  16.372 +            DataOutputStream dos = (DataOutputStream)out;
  16.373 +            if(dos.bytearr == null || (dos.bytearr.length < (utflen+2)))
  16.374 +                dos.bytearr = new byte[(utflen*2) + 2];
  16.375 +            bytearr = dos.bytearr;
  16.376 +        } else {
  16.377 +            bytearr = new byte[utflen+2];
  16.378 +        }
  16.379 +
  16.380 +        bytearr[count++] = (byte) ((utflen >>> 8) & 0xFF);
  16.381 +        bytearr[count++] = (byte) ((utflen >>> 0) & 0xFF);
  16.382 +
  16.383 +        int i=0;
  16.384 +        for (i=0; i<strlen; i++) {
  16.385 +           c = str.charAt(i);
  16.386 +           if (!((c >= 0x0001) && (c <= 0x007F))) break;
  16.387 +           bytearr[count++] = (byte) c;
  16.388 +        }
  16.389 +
  16.390 +        for (;i < strlen; i++){
  16.391 +            c = str.charAt(i);
  16.392 +            if ((c >= 0x0001) && (c <= 0x007F)) {
  16.393 +                bytearr[count++] = (byte) c;
  16.394 +
  16.395 +            } else if (c > 0x07FF) {
  16.396 +                bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
  16.397 +                bytearr[count++] = (byte) (0x80 | ((c >>  6) & 0x3F));
  16.398 +                bytearr[count++] = (byte) (0x80 | ((c >>  0) & 0x3F));
  16.399 +            } else {
  16.400 +                bytearr[count++] = (byte) (0xC0 | ((c >>  6) & 0x1F));
  16.401 +                bytearr[count++] = (byte) (0x80 | ((c >>  0) & 0x3F));
  16.402 +            }
  16.403 +        }
  16.404 +        out.write(bytearr, 0, utflen+2);
  16.405 +        return utflen + 2;
  16.406 +    }
  16.407 +
  16.408 +    /**
  16.409 +     * Returns the current value of the counter <code>written</code>,
  16.410 +     * the number of bytes written to this data output stream so far.
  16.411 +     * If the counter overflows, it will be wrapped to Integer.MAX_VALUE.
  16.412 +     *
  16.413 +     * @return  the value of the <code>written</code> field.
  16.414 +     * @see     java.io.DataOutputStream#written
  16.415 +     */
  16.416 +    public final int size() {
  16.417 +        return written;
  16.418 +    }
  16.419 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/emul/compact/src/main/java/java/io/Externalizable.java	Tue Feb 05 17:04:22 2013 +0100
    17.3 @@ -0,0 +1,97 @@
    17.4 +/*
    17.5 + * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved.
    17.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    17.7 + *
    17.8 + * This code is free software; you can redistribute it and/or modify it
    17.9 + * under the terms of the GNU General Public License version 2 only, as
   17.10 + * published by the Free Software Foundation.  Oracle designates this
   17.11 + * particular file as subject to the "Classpath" exception as provided
   17.12 + * by Oracle in the LICENSE file that accompanied this code.
   17.13 + *
   17.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   17.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   17.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   17.17 + * version 2 for more details (a copy is included in the LICENSE file that
   17.18 + * accompanied this code).
   17.19 + *
   17.20 + * You should have received a copy of the GNU General Public License version
   17.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   17.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   17.23 + *
   17.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   17.25 + * or visit www.oracle.com if you need additional information or have any
   17.26 + * questions.
   17.27 + */
   17.28 +
   17.29 +package java.io;
   17.30 +
   17.31 +import java.io.ObjectOutput;
   17.32 +import java.io.ObjectInput;
   17.33 +
   17.34 +/**
   17.35 + * Only the identity of the class of an Externalizable instance is
   17.36 + * written in the serialization stream and it is the responsibility
   17.37 + * of the class to save and restore the contents of its instances.
   17.38 + *
   17.39 + * The writeExternal and readExternal methods of the Externalizable
   17.40 + * interface are implemented by a class to give the class complete
   17.41 + * control over the format and contents of the stream for an object
   17.42 + * and its supertypes. These methods must explicitly
   17.43 + * coordinate with the supertype to save its state. These methods supersede
   17.44 + * customized implementations of writeObject and readObject methods.<br>
   17.45 + *
   17.46 + * Object Serialization uses the Serializable and Externalizable
   17.47 + * interfaces.  Object persistence mechanisms can use them as well.  Each
   17.48 + * object to be stored is tested for the Externalizable interface. If
   17.49 + * the object supports Externalizable, the writeExternal method is called. If the
   17.50 + * object does not support Externalizable and does implement
   17.51 + * Serializable, the object is saved using
   17.52 + * ObjectOutputStream. <br> When an Externalizable object is
   17.53 + * reconstructed, an instance is created using the public no-arg
   17.54 + * constructor, then the readExternal method called.  Serializable
   17.55 + * objects are restored by reading them from an ObjectInputStream.<br>
   17.56 + *
   17.57 + * An Externalizable instance can designate a substitution object via
   17.58 + * the writeReplace and readResolve methods documented in the Serializable
   17.59 + * interface.<br>
   17.60 + *
   17.61 + * @author  unascribed
   17.62 + * @see java.io.ObjectOutputStream
   17.63 + * @see java.io.ObjectInputStream
   17.64 + * @see java.io.ObjectOutput
   17.65 + * @see java.io.ObjectInput
   17.66 + * @see java.io.Serializable
   17.67 + * @since   JDK1.1
   17.68 + */
   17.69 +public interface Externalizable extends java.io.Serializable {
   17.70 +    /**
   17.71 +     * The object implements the writeExternal method to save its contents
   17.72 +     * by calling the methods of DataOutput for its primitive values or
   17.73 +     * calling the writeObject method of ObjectOutput for objects, strings,
   17.74 +     * and arrays.
   17.75 +     *
   17.76 +     * @serialData Overriding methods should use this tag to describe
   17.77 +     *             the data layout of this Externalizable object.
   17.78 +     *             List the sequence of element types and, if possible,
   17.79 +     *             relate the element to a public/protected field and/or
   17.80 +     *             method of this Externalizable class.
   17.81 +     *
   17.82 +     * @param out the stream to write the object to
   17.83 +     * @exception IOException Includes any I/O exceptions that may occur
   17.84 +     */
   17.85 +    void writeExternal(ObjectOutput out) throws IOException;
   17.86 +
   17.87 +    /**
   17.88 +     * The object implements the readExternal method to restore its
   17.89 +     * contents by calling the methods of DataInput for primitive
   17.90 +     * types and readObject for objects, strings and arrays.  The
   17.91 +     * readExternal method must read the values in the same sequence
   17.92 +     * and with the same types as were written by writeExternal.
   17.93 +     *
   17.94 +     * @param in the stream to read data from in order to restore the object
   17.95 +     * @exception IOException if I/O errors occur
   17.96 +     * @exception ClassNotFoundException If the class for an object being
   17.97 +     *              restored cannot be found.
   17.98 +     */
   17.99 +    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
  17.100 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/emul/compact/src/main/java/java/io/FilterOutputStream.java	Tue Feb 05 17:04:22 2013 +0100
    18.3 @@ -0,0 +1,162 @@
    18.4 +/*
    18.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
    18.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    18.7 + *
    18.8 + * This code is free software; you can redistribute it and/or modify it
    18.9 + * under the terms of the GNU General Public License version 2 only, as
   18.10 + * published by the Free Software Foundation.  Oracle designates this
   18.11 + * particular file as subject to the "Classpath" exception as provided
   18.12 + * by Oracle in the LICENSE file that accompanied this code.
   18.13 + *
   18.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   18.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   18.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   18.17 + * version 2 for more details (a copy is included in the LICENSE file that
   18.18 + * accompanied this code).
   18.19 + *
   18.20 + * You should have received a copy of the GNU General Public License version
   18.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   18.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   18.23 + *
   18.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   18.25 + * or visit www.oracle.com if you need additional information or have any
   18.26 + * questions.
   18.27 + */
   18.28 +
   18.29 +package java.io;
   18.30 +
   18.31 +/**
   18.32 + * This class is the superclass of all classes that filter output
   18.33 + * streams. These streams sit on top of an already existing output
   18.34 + * stream (the <i>underlying</i> output stream) which it uses as its
   18.35 + * basic sink of data, but possibly transforming the data along the
   18.36 + * way or providing additional functionality.
   18.37 + * <p>
   18.38 + * The class <code>FilterOutputStream</code> itself simply overrides
   18.39 + * all methods of <code>OutputStream</code> with versions that pass
   18.40 + * all requests to the underlying output stream. Subclasses of
   18.41 + * <code>FilterOutputStream</code> may further override some of these
   18.42 + * methods as well as provide additional methods and fields.
   18.43 + *
   18.44 + * @author  Jonathan Payne
   18.45 + * @since   JDK1.0
   18.46 + */
   18.47 +public
   18.48 +class FilterOutputStream extends OutputStream {
   18.49 +    /**
   18.50 +     * The underlying output stream to be filtered.
   18.51 +     */
   18.52 +    protected OutputStream out;
   18.53 +
   18.54 +    /**
   18.55 +     * Creates an output stream filter built on top of the specified
   18.56 +     * underlying output stream.
   18.57 +     *
   18.58 +     * @param   out   the underlying output stream to be assigned to
   18.59 +     *                the field <tt>this.out</tt> for later use, or
   18.60 +     *                <code>null</code> if this instance is to be
   18.61 +     *                created without an underlying stream.
   18.62 +     */
   18.63 +    public FilterOutputStream(OutputStream out) {
   18.64 +        this.out = out;
   18.65 +    }
   18.66 +
   18.67 +    /**
   18.68 +     * Writes the specified <code>byte</code> to this output stream.
   18.69 +     * <p>
   18.70 +     * The <code>write</code> method of <code>FilterOutputStream</code>
   18.71 +     * calls the <code>write</code> method of its underlying output stream,
   18.72 +     * that is, it performs <tt>out.write(b)</tt>.
   18.73 +     * <p>
   18.74 +     * Implements the abstract <tt>write</tt> method of <tt>OutputStream</tt>.
   18.75 +     *
   18.76 +     * @param      b   the <code>byte</code>.
   18.77 +     * @exception  IOException  if an I/O error occurs.
   18.78 +     */
   18.79 +    public void write(int b) throws IOException {
   18.80 +        out.write(b);
   18.81 +    }
   18.82 +
   18.83 +    /**
   18.84 +     * Writes <code>b.length</code> bytes to this output stream.
   18.85 +     * <p>
   18.86 +     * The <code>write</code> method of <code>FilterOutputStream</code>
   18.87 +     * calls its <code>write</code> method of three arguments with the
   18.88 +     * arguments <code>b</code>, <code>0</code>, and
   18.89 +     * <code>b.length</code>.
   18.90 +     * <p>
   18.91 +     * Note that this method does not call the one-argument
   18.92 +     * <code>write</code> method of its underlying stream with the single
   18.93 +     * argument <code>b</code>.
   18.94 +     *
   18.95 +     * @param      b   the data to be written.
   18.96 +     * @exception  IOException  if an I/O error occurs.
   18.97 +     * @see        java.io.FilterOutputStream#write(byte[], int, int)
   18.98 +     */
   18.99 +    public void write(byte b[]) throws IOException {
  18.100 +        write(b, 0, b.length);
  18.101 +    }
  18.102 +
  18.103 +    /**
  18.104 +     * Writes <code>len</code> bytes from the specified
  18.105 +     * <code>byte</code> array starting at offset <code>off</code> to
  18.106 +     * this output stream.
  18.107 +     * <p>
  18.108 +     * The <code>write</code> method of <code>FilterOutputStream</code>
  18.109 +     * calls the <code>write</code> method of one argument on each
  18.110 +     * <code>byte</code> to output.
  18.111 +     * <p>
  18.112 +     * Note that this method does not call the <code>write</code> method
  18.113 +     * of its underlying input stream with the same arguments. Subclasses
  18.114 +     * of <code>FilterOutputStream</code> should provide a more efficient
  18.115 +     * implementation of this method.
  18.116 +     *
  18.117 +     * @param      b     the data.
  18.118 +     * @param      off   the start offset in the data.
  18.119 +     * @param      len   the number of bytes to write.
  18.120 +     * @exception  IOException  if an I/O error occurs.
  18.121 +     * @see        java.io.FilterOutputStream#write(int)
  18.122 +     */
  18.123 +    public void write(byte b[], int off, int len) throws IOException {
  18.124 +        if ((off | len | (b.length - (len + off)) | (off + len)) < 0)
  18.125 +            throw new IndexOutOfBoundsException();
  18.126 +
  18.127 +        for (int i = 0 ; i < len ; i++) {
  18.128 +            write(b[off + i]);
  18.129 +        }
  18.130 +    }
  18.131 +
  18.132 +    /**
  18.133 +     * Flushes this output stream and forces any buffered output bytes
  18.134 +     * to be written out to the stream.
  18.135 +     * <p>
  18.136 +     * The <code>flush</code> method of <code>FilterOutputStream</code>
  18.137 +     * calls the <code>flush</code> method of its underlying output stream.
  18.138 +     *
  18.139 +     * @exception  IOException  if an I/O error occurs.
  18.140 +     * @see        java.io.FilterOutputStream#out
  18.141 +     */
  18.142 +    public void flush() throws IOException {
  18.143 +        out.flush();
  18.144 +    }
  18.145 +
  18.146 +    /**
  18.147 +     * Closes this output stream and releases any system resources
  18.148 +     * associated with the stream.
  18.149 +     * <p>
  18.150 +     * The <code>close</code> method of <code>FilterOutputStream</code>
  18.151 +     * calls its <code>flush</code> method, and then calls the
  18.152 +     * <code>close</code> method of its underlying output stream.
  18.153 +     *
  18.154 +     * @exception  IOException  if an I/O error occurs.
  18.155 +     * @see        java.io.FilterOutputStream#flush()
  18.156 +     * @see        java.io.FilterOutputStream#out
  18.157 +     */
  18.158 +    public void close() throws IOException {
  18.159 +        try {
  18.160 +          flush();
  18.161 +        } catch (IOException ignored) {
  18.162 +        }
  18.163 +        out.close();
  18.164 +    }
  18.165 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/emul/compact/src/main/java/java/io/Flushable.java	Tue Feb 05 17:04:22 2013 +0100
    19.3 @@ -0,0 +1,47 @@
    19.4 +/*
    19.5 + * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
    19.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    19.7 + *
    19.8 + * This code is free software; you can redistribute it and/or modify it
    19.9 + * under the terms of the GNU General Public License version 2 only, as
   19.10 + * published by the Free Software Foundation.  Oracle designates this
   19.11 + * particular file as subject to the "Classpath" exception as provided
   19.12 + * by Oracle in the LICENSE file that accompanied this code.
   19.13 + *
   19.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   19.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   19.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   19.17 + * version 2 for more details (a copy is included in the LICENSE file that
   19.18 + * accompanied this code).
   19.19 + *
   19.20 + * You should have received a copy of the GNU General Public License version
   19.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   19.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   19.23 + *
   19.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   19.25 + * or visit www.oracle.com if you need additional information or have any
   19.26 + * questions.
   19.27 + */
   19.28 +
   19.29 +package java.io;
   19.30 +
   19.31 +import java.io.IOException;
   19.32 +
   19.33 +/**
   19.34 + * A <tt>Flushable</tt> is a destination of data that can be flushed.  The
   19.35 + * flush method is invoked to write any buffered output to the underlying
   19.36 + * stream.
   19.37 + *
   19.38 + * @since 1.5
   19.39 + */
   19.40 +
   19.41 +public interface Flushable {
   19.42 +
   19.43 +    /**
   19.44 +     * Flushes this stream by writing any buffered output to the underlying
   19.45 +     * stream.
   19.46 +     *
   19.47 +     * @throws IOException If an I/O error occurs
   19.48 +     */
   19.49 +    void flush() throws IOException;
   19.50 +}
    20.1 --- a/emul/compact/src/main/java/java/io/InputStreamReader.java	Tue Feb 05 16:40:01 2013 +0100
    20.2 +++ b/emul/compact/src/main/java/java/io/InputStreamReader.java	Tue Feb 05 17:04:22 2013 +0100
    20.3 @@ -156,9 +156,39 @@
    20.4       * @exception  IOException  If an I/O error occurs
    20.5       */
    20.6      public int read() throws IOException {
    20.7 -        return ((InputStream)lock).read();
    20.8 +        final InputStream is = (InputStream)lock;
    20.9 +        int c = is.read();
   20.10 +        if (c == -1) {
   20.11 +            return -1;
   20.12 +        }
   20.13 +        c = (int) c & 0xff;
   20.14 +        switch (c >> 4) {
   20.15 +            case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
   20.16 +                /* 0xxxxxxx*/
   20.17 +                return c;
   20.18 +            case 12: case 13: {
   20.19 +                /* 110x xxxx   10xx xxxx*/
   20.20 +                int char2 = (int) is.read();
   20.21 +                if ((char2 & 0xC0) != 0x80)
   20.22 +                    throw new UTFDataFormatException("malformed input");
   20.23 +                return (((c & 0x1F) << 6) | (char2 & 0x3F));
   20.24 +            }
   20.25 +            case 14: {
   20.26 +                /* 1110 xxxx  10xx xxxx  10xx xxxx */
   20.27 +                int char2 = is.read();
   20.28 +                int char3 = is.read();
   20.29 +                if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
   20.30 +                    throw new UTFDataFormatException("malformed input");
   20.31 +                return (((c    & 0x0F) << 12) |
   20.32 +                       ((char2 & 0x3F) << 6)  |
   20.33 +                       ((char3 & 0x3F) << 0));
   20.34 +            }
   20.35 +            default:
   20.36 +                /* 10xx xxxx,  1111 xxxx */
   20.37 +                throw new UTFDataFormatException("malformed input");
   20.38 +        }
   20.39      }
   20.40 -
   20.41 +    
   20.42      /**
   20.43       * Reads characters into a portion of an array.
   20.44       *
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/emul/compact/src/main/java/java/io/InvalidClassException.java	Tue Feb 05 17:04:22 2013 +0100
    21.3 @@ -0,0 +1,81 @@
    21.4 +/*
    21.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
    21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    21.7 + *
    21.8 + * This code is free software; you can redistribute it and/or modify it
    21.9 + * under the terms of the GNU General Public License version 2 only, as
   21.10 + * published by the Free Software Foundation.  Oracle designates this
   21.11 + * particular file as subject to the "Classpath" exception as provided
   21.12 + * by Oracle in the LICENSE file that accompanied this code.
   21.13 + *
   21.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   21.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   21.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   21.17 + * version 2 for more details (a copy is included in the LICENSE file that
   21.18 + * accompanied this code).
   21.19 + *
   21.20 + * You should have received a copy of the GNU General Public License version
   21.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   21.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   21.23 + *
   21.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   21.25 + * or visit www.oracle.com if you need additional information or have any
   21.26 + * questions.
   21.27 + */
   21.28 +
   21.29 +package java.io;
   21.30 +
   21.31 +/**
   21.32 + * Thrown when the Serialization runtime detects one of the following
   21.33 + * problems with a Class.
   21.34 + * <UL>
   21.35 + * <LI> The serial version of the class does not match that of the class
   21.36 + *      descriptor read from the stream
   21.37 + * <LI> The class contains unknown datatypes
   21.38 + * <LI> The class does not have an accessible no-arg constructor
   21.39 + * </UL>
   21.40 + *
   21.41 + * @author  unascribed
   21.42 + * @since   JDK1.1
   21.43 + */
   21.44 +public class InvalidClassException extends ObjectStreamException {
   21.45 +
   21.46 +    private static final long serialVersionUID = -4333316296251054416L;
   21.47 +
   21.48 +    /**
   21.49 +     * Name of the invalid class.
   21.50 +     *
   21.51 +     * @serial Name of the invalid class.
   21.52 +     */
   21.53 +    public String classname;
   21.54 +
   21.55 +    /**
   21.56 +     * Report an InvalidClassException for the reason specified.
   21.57 +     *
   21.58 +     * @param reason  String describing the reason for the exception.
   21.59 +     */
   21.60 +    public InvalidClassException(String reason) {
   21.61 +        super(reason);
   21.62 +    }
   21.63 +
   21.64 +    /**
   21.65 +     * Constructs an InvalidClassException object.
   21.66 +     *
   21.67 +     * @param cname   a String naming the invalid class.
   21.68 +     * @param reason  a String describing the reason for the exception.
   21.69 +     */
   21.70 +    public InvalidClassException(String cname, String reason) {
   21.71 +        super(reason);
   21.72 +        classname = cname;
   21.73 +    }
   21.74 +
   21.75 +    /**
   21.76 +     * Produce the message and include the classname, if present.
   21.77 +     */
   21.78 +    public String getMessage() {
   21.79 +        if (classname == null)
   21.80 +            return super.getMessage();
   21.81 +        else
   21.82 +            return classname + "; " + super.getMessage();
   21.83 +    }
   21.84 +}
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/emul/compact/src/main/java/java/io/InvalidObjectException.java	Tue Feb 05 17:04:22 2013 +0100
    22.3 @@ -0,0 +1,51 @@
    22.4 +/*
    22.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
    22.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    22.7 + *
    22.8 + * This code is free software; you can redistribute it and/or modify it
    22.9 + * under the terms of the GNU General Public License version 2 only, as
   22.10 + * published by the Free Software Foundation.  Oracle designates this
   22.11 + * particular file as subject to the "Classpath" exception as provided
   22.12 + * by Oracle in the LICENSE file that accompanied this code.
   22.13 + *
   22.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   22.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   22.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   22.17 + * version 2 for more details (a copy is included in the LICENSE file that
   22.18 + * accompanied this code).
   22.19 + *
   22.20 + * You should have received a copy of the GNU General Public License version
   22.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   22.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   22.23 + *
   22.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22.25 + * or visit www.oracle.com if you need additional information or have any
   22.26 + * questions.
   22.27 + */
   22.28 +
   22.29 +package java.io;
   22.30 +
   22.31 +/**
   22.32 + * Indicates that one or more deserialized objects failed validation
   22.33 + * tests.  The argument should provide the reason for the failure.
   22.34 + *
   22.35 + * @see ObjectInputValidation
   22.36 + * @since JDK1.1
   22.37 + *
   22.38 + * @author  unascribed
   22.39 + * @since   JDK1.1
   22.40 + */
   22.41 +public class InvalidObjectException extends ObjectStreamException {
   22.42 +
   22.43 +    private static final long serialVersionUID = 3233174318281839583L;
   22.44 +
   22.45 +    /**
   22.46 +     * Constructs an <code>InvalidObjectException</code>.
   22.47 +     * @param reason Detailed message explaining the reason for the failure.
   22.48 +     *
   22.49 +     * @see ObjectInputValidation
   22.50 +     */
   22.51 +    public  InvalidObjectException(String reason) {
   22.52 +        super(reason);
   22.53 +    }
   22.54 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/emul/compact/src/main/java/java/io/NotActiveException.java	Tue Feb 05 17:04:22 2013 +0100
    23.3 @@ -0,0 +1,53 @@
    23.4 +/*
    23.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
    23.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    23.7 + *
    23.8 + * This code is free software; you can redistribute it and/or modify it
    23.9 + * under the terms of the GNU General Public License version 2 only, as
   23.10 + * published by the Free Software Foundation.  Oracle designates this
   23.11 + * particular file as subject to the "Classpath" exception as provided
   23.12 + * by Oracle in the LICENSE file that accompanied this code.
   23.13 + *
   23.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   23.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   23.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   23.17 + * version 2 for more details (a copy is included in the LICENSE file that
   23.18 + * accompanied this code).
   23.19 + *
   23.20 + * You should have received a copy of the GNU General Public License version
   23.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   23.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   23.23 + *
   23.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   23.25 + * or visit www.oracle.com if you need additional information or have any
   23.26 + * questions.
   23.27 + */
   23.28 +
   23.29 +package java.io;
   23.30 +
   23.31 +/**
   23.32 + * Thrown when serialization or deserialization is not active.
   23.33 + *
   23.34 + * @author  unascribed
   23.35 + * @since   JDK1.1
   23.36 + */
   23.37 +public class NotActiveException extends ObjectStreamException {
   23.38 +
   23.39 +    private static final long serialVersionUID = -3893467273049808895L;
   23.40 +
   23.41 +    /**
   23.42 +     * Constructor to create a new NotActiveException with the reason given.
   23.43 +     *
   23.44 +     * @param reason  a String describing the reason for the exception.
   23.45 +     */
   23.46 +    public NotActiveException(String reason) {
   23.47 +        super(reason);
   23.48 +    }
   23.49 +
   23.50 +    /**
   23.51 +     * Constructor to create a new NotActiveException without a reason.
   23.52 +     */
   23.53 +    public NotActiveException() {
   23.54 +        super();
   23.55 +    }
   23.56 +}
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/emul/compact/src/main/java/java/io/NotSerializableException.java	Tue Feb 05 17:04:22 2013 +0100
    24.3 @@ -0,0 +1,55 @@
    24.4 +/*
    24.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
    24.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    24.7 + *
    24.8 + * This code is free software; you can redistribute it and/or modify it
    24.9 + * under the terms of the GNU General Public License version 2 only, as
   24.10 + * published by the Free Software Foundation.  Oracle designates this
   24.11 + * particular file as subject to the "Classpath" exception as provided
   24.12 + * by Oracle in the LICENSE file that accompanied this code.
   24.13 + *
   24.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   24.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   24.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   24.17 + * version 2 for more details (a copy is included in the LICENSE file that
   24.18 + * accompanied this code).
   24.19 + *
   24.20 + * You should have received a copy of the GNU General Public License version
   24.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   24.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   24.23 + *
   24.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   24.25 + * or visit www.oracle.com if you need additional information or have any
   24.26 + * questions.
   24.27 + */
   24.28 +
   24.29 +package java.io;
   24.30 +
   24.31 +/**
   24.32 + * Thrown when an instance is required to have a Serializable interface.
   24.33 + * The serialization runtime or the class of the instance can throw
   24.34 + * this exception. The argument should be the name of the class.
   24.35 + *
   24.36 + * @author  unascribed
   24.37 + * @since   JDK1.1
   24.38 + */
   24.39 +public class NotSerializableException extends ObjectStreamException {
   24.40 +
   24.41 +    private static final long serialVersionUID = 2906642554793891381L;
   24.42 +
   24.43 +    /**
   24.44 +     * Constructs a NotSerializableException object with message string.
   24.45 +     *
   24.46 +     * @param classname Class of the instance being serialized/deserialized.
   24.47 +     */
   24.48 +    public NotSerializableException(String classname) {
   24.49 +        super(classname);
   24.50 +    }
   24.51 +
   24.52 +    /**
   24.53 +     *  Constructs a NotSerializableException object.
   24.54 +     */
   24.55 +    public NotSerializableException() {
   24.56 +        super();
   24.57 +    }
   24.58 +}
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/emul/compact/src/main/java/java/io/ObjectInput.java	Tue Feb 05 17:04:22 2013 +0100
    25.3 @@ -0,0 +1,107 @@
    25.4 +/*
    25.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
    25.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    25.7 + *
    25.8 + * This code is free software; you can redistribute it and/or modify it
    25.9 + * under the terms of the GNU General Public License version 2 only, as
   25.10 + * published by the Free Software Foundation.  Oracle designates this
   25.11 + * particular file as subject to the "Classpath" exception as provided
   25.12 + * by Oracle in the LICENSE file that accompanied this code.
   25.13 + *
   25.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   25.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   25.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   25.17 + * version 2 for more details (a copy is included in the LICENSE file that
   25.18 + * accompanied this code).
   25.19 + *
   25.20 + * You should have received a copy of the GNU General Public License version
   25.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   25.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   25.23 + *
   25.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   25.25 + * or visit www.oracle.com if you need additional information or have any
   25.26 + * questions.
   25.27 + */
   25.28 +
   25.29 +package java.io;
   25.30 +
   25.31 +/**
   25.32 + * ObjectInput extends the DataInput interface to include the reading of
   25.33 + * objects. DataInput includes methods for the input of primitive types,
   25.34 + * ObjectInput extends that interface to include objects, arrays, and Strings.
   25.35 + *
   25.36 + * @author  unascribed
   25.37 + * @see java.io.InputStream
   25.38 + * @see java.io.ObjectOutputStream
   25.39 + * @see java.io.ObjectInputStream
   25.40 + * @since   JDK1.1
   25.41 + */
   25.42 +public interface ObjectInput extends DataInput, AutoCloseable {
   25.43 +    /**
   25.44 +     * Read and return an object. The class that implements this interface
   25.45 +     * defines where the object is "read" from.
   25.46 +     *
   25.47 +     * @return the object read from the stream
   25.48 +     * @exception java.lang.ClassNotFoundException If the class of a serialized
   25.49 +     *      object cannot be found.
   25.50 +     * @exception IOException If any of the usual Input/Output
   25.51 +     * related exceptions occur.
   25.52 +     */
   25.53 +    public Object readObject()
   25.54 +        throws ClassNotFoundException, IOException;
   25.55 +
   25.56 +    /**
   25.57 +     * Reads a byte of data. This method will block if no input is
   25.58 +     * available.
   25.59 +     * @return  the byte read, or -1 if the end of the
   25.60 +     *          stream is reached.
   25.61 +     * @exception IOException If an I/O error has occurred.
   25.62 +     */
   25.63 +    public int read() throws IOException;
   25.64 +
   25.65 +    /**
   25.66 +     * Reads into an array of bytes.  This method will
   25.67 +     * block until some input is available.
   25.68 +     * @param b the buffer into which the data is read
   25.69 +     * @return  the actual number of bytes read, -1 is
   25.70 +     *          returned when the end of the stream is reached.
   25.71 +     * @exception IOException If an I/O error has occurred.
   25.72 +     */
   25.73 +    public int read(byte b[]) throws IOException;
   25.74 +
   25.75 +    /**
   25.76 +     * Reads into an array of bytes.  This method will
   25.77 +     * block until some input is available.
   25.78 +     * @param b the buffer into which the data is read
   25.79 +     * @param off the start offset of the data
   25.80 +     * @param len the maximum number of bytes read
   25.81 +     * @return  the actual number of bytes read, -1 is
   25.82 +     *          returned when the end of the stream is reached.
   25.83 +     * @exception IOException If an I/O error has occurred.
   25.84 +     */
   25.85 +    public int read(byte b[], int off, int len) throws IOException;
   25.86 +
   25.87 +    /**
   25.88 +     * Skips n bytes of input.
   25.89 +     * @param n the number of bytes to be skipped
   25.90 +     * @return  the actual number of bytes skipped.
   25.91 +     * @exception IOException If an I/O error has occurred.
   25.92 +     */
   25.93 +    public long skip(long n) throws IOException;
   25.94 +
   25.95 +    /**
   25.96 +     * Returns the number of bytes that can be read
   25.97 +     * without blocking.
   25.98 +     * @return the number of available bytes.
   25.99 +     * @exception IOException If an I/O error has occurred.
  25.100 +     */
  25.101 +    public int available() throws IOException;
  25.102 +
  25.103 +    /**
  25.104 +     * Closes the input stream. Must be called
  25.105 +     * to release any resources associated with
  25.106 +     * the stream.
  25.107 +     * @exception IOException If an I/O error has occurred.
  25.108 +     */
  25.109 +    public void close() throws IOException;
  25.110 +}
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/emul/compact/src/main/java/java/io/ObjectInputStream.java	Tue Feb 05 17:04:22 2013 +0100
    26.3 @@ -0,0 +1,3357 @@
    26.4 +/*
    26.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
    26.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    26.7 + *
    26.8 + * This code is free software; you can redistribute it and/or modify it
    26.9 + * under the terms of the GNU General Public License version 2 only, as
   26.10 + * published by the Free Software Foundation.  Oracle designates this
   26.11 + * particular file as subject to the "Classpath" exception as provided
   26.12 + * by Oracle in the LICENSE file that accompanied this code.
   26.13 + *
   26.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   26.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   26.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   26.17 + * version 2 for more details (a copy is included in the LICENSE file that
   26.18 + * accompanied this code).
   26.19 + *
   26.20 + * You should have received a copy of the GNU General Public License version
   26.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   26.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   26.23 + *
   26.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   26.25 + * or visit www.oracle.com if you need additional information or have any
   26.26 + * questions.
   26.27 + */
   26.28 +
   26.29 +package java.io;
   26.30 +
   26.31 +import java.lang.reflect.Array;
   26.32 +import java.lang.reflect.Modifier;
   26.33 +import java.lang.reflect.Proxy;
   26.34 +import java.util.Arrays;
   26.35 +import java.util.HashMap;
   26.36 +import org.apidesign.bck2brwsr.emul.lang.System;
   26.37 +
   26.38 +/**
   26.39 + * An ObjectInputStream deserializes primitive data and objects previously
   26.40 + * written using an ObjectOutputStream.
   26.41 + *
   26.42 + * <p>ObjectOutputStream and ObjectInputStream can provide an application with
   26.43 + * persistent storage for graphs of objects when used with a FileOutputStream
   26.44 + * and FileInputStream respectively.  ObjectInputStream is used to recover
   26.45 + * those objects previously serialized. Other uses include passing objects
   26.46 + * between hosts using a socket stream or for marshaling and unmarshaling
   26.47 + * arguments and parameters in a remote communication system.
   26.48 + *
   26.49 + * <p>ObjectInputStream ensures that the types of all objects in the graph
   26.50 + * created from the stream match the classes present in the Java Virtual
   26.51 + * Machine.  Classes are loaded as required using the standard mechanisms.
   26.52 + *
   26.53 + * <p>Only objects that support the java.io.Serializable or
   26.54 + * java.io.Externalizable interface can be read from streams.
   26.55 + *
   26.56 + * <p>The method <code>readObject</code> is used to read an object from the
   26.57 + * stream.  Java's safe casting should be used to get the desired type.  In
   26.58 + * Java, strings and arrays are objects and are treated as objects during
   26.59 + * serialization. When read they need to be cast to the expected type.
   26.60 + *
   26.61 + * <p>Primitive data types can be read from the stream using the appropriate
   26.62 + * method on DataInput.
   26.63 + *
   26.64 + * <p>The default deserialization mechanism for objects restores the contents
   26.65 + * of each field to the value and type it had when it was written.  Fields
   26.66 + * declared as transient or static are ignored by the deserialization process.
   26.67 + * References to other objects cause those objects to be read from the stream
   26.68 + * as necessary.  Graphs of objects are restored correctly using a reference
   26.69 + * sharing mechanism.  New objects are always allocated when deserializing,
   26.70 + * which prevents existing objects from being overwritten.
   26.71 + *
   26.72 + * <p>Reading an object is analogous to running the constructors of a new
   26.73 + * object.  Memory is allocated for the object and initialized to zero (NULL).
   26.74 + * No-arg constructors are invoked for the non-serializable classes and then
   26.75 + * the fields of the serializable classes are restored from the stream starting
   26.76 + * with the serializable class closest to java.lang.object and finishing with
   26.77 + * the object's most specific class.
   26.78 + *
   26.79 + * <p>For example to read from a stream as written by the example in
   26.80 + * ObjectOutputStream:
   26.81 + * <br>
   26.82 + * <pre>
   26.83 + *      FileInputStream fis = new FileInputStream("t.tmp");
   26.84 + *      ObjectInputStream ois = new ObjectInputStream(fis);
   26.85 + *
   26.86 + *      int i = ois.readInt();
   26.87 + *      String today = (String) ois.readObject();
   26.88 + *      Date date = (Date) ois.readObject();
   26.89 + *
   26.90 + *      ois.close();
   26.91 + * </pre>
   26.92 + *
   26.93 + * <p>Classes control how they are serialized by implementing either the
   26.94 + * java.io.Serializable or java.io.Externalizable interfaces.
   26.95 + *
   26.96 + * <p>Implementing the Serializable interface allows object serialization to
   26.97 + * save and restore the entire state of the object and it allows classes to
   26.98 + * evolve between the time the stream is written and the time it is read.  It
   26.99 + * automatically traverses references between objects, saving and restoring
  26.100 + * entire graphs.
  26.101 + *
  26.102 + * <p>Serializable classes that require special handling during the
  26.103 + * serialization and deserialization process should implement the following
  26.104 + * methods:<p>
  26.105 + *
  26.106 + * <pre>
  26.107 + * private void writeObject(java.io.ObjectOutputStream stream)
  26.108 + *     throws IOException;
  26.109 + * private void readObject(java.io.ObjectInputStream stream)
  26.110 + *     throws IOException, ClassNotFoundException;
  26.111 + * private void readObjectNoData()
  26.112 + *     throws ObjectStreamException;
  26.113 + * </pre>
  26.114 + *
  26.115 + * <p>The readObject method is responsible for reading and restoring the state
  26.116 + * of the object for its particular class using data written to the stream by
  26.117 + * the corresponding writeObject method.  The method does not need to concern
  26.118 + * itself with the state belonging to its superclasses or subclasses.  State is
  26.119 + * restored by reading data from the ObjectInputStream for the individual
  26.120 + * fields and making assignments to the appropriate fields of the object.
  26.121 + * Reading primitive data types is supported by DataInput.
  26.122 + *
  26.123 + * <p>Any attempt to read object data which exceeds the boundaries of the
  26.124 + * custom data written by the corresponding writeObject method will cause an
  26.125 + * OptionalDataException to be thrown with an eof field value of true.
  26.126 + * Non-object reads which exceed the end of the allotted data will reflect the
  26.127 + * end of data in the same way that they would indicate the end of the stream:
  26.128 + * bytewise reads will return -1 as the byte read or number of bytes read, and
  26.129 + * primitive reads will throw EOFExceptions.  If there is no corresponding
  26.130 + * writeObject method, then the end of default serialized data marks the end of
  26.131 + * the allotted data.
  26.132 + *
  26.133 + * <p>Primitive and object read calls issued from within a readExternal method
  26.134 + * behave in the same manner--if the stream is already positioned at the end of
  26.135 + * data written by the corresponding writeExternal method, object reads will
  26.136 + * throw OptionalDataExceptions with eof set to true, bytewise reads will
  26.137 + * return -1, and primitive reads will throw EOFExceptions.  Note that this
  26.138 + * behavior does not hold for streams written with the old
  26.139 + * <code>ObjectStreamConstants.PROTOCOL_VERSION_1</code> protocol, in which the
  26.140 + * end of data written by writeExternal methods is not demarcated, and hence
  26.141 + * cannot be detected.
  26.142 + *
  26.143 + * <p>The readObjectNoData method is responsible for initializing the state of
  26.144 + * the object for its particular class in the event that the serialization
  26.145 + * stream does not list the given class as a superclass of the object being
  26.146 + * deserialized.  This may occur in cases where the receiving party uses a
  26.147 + * different version of the deserialized instance's class than the sending
  26.148 + * party, and the receiver's version extends classes that are not extended by
  26.149 + * the sender's version.  This may also occur if the serialization stream has
  26.150 + * been tampered; hence, readObjectNoData is useful for initializing
  26.151 + * deserialized objects properly despite a "hostile" or incomplete source
  26.152 + * stream.
  26.153 + *
  26.154 + * <p>Serialization does not read or assign values to the fields of any object
  26.155 + * that does not implement the java.io.Serializable interface.  Subclasses of
  26.156 + * Objects that are not serializable can be serializable. In this case the
  26.157 + * non-serializable class must have a no-arg constructor to allow its fields to
  26.158 + * be initialized.  In this case it is the responsibility of the subclass to
  26.159 + * save and restore the state of the non-serializable class. It is frequently
  26.160 + * the case that the fields of that class are accessible (public, package, or
  26.161 + * protected) or that there are get and set methods that can be used to restore
  26.162 + * the state.
  26.163 + *
  26.164 + * <p>Any exception that occurs while deserializing an object will be caught by
  26.165 + * the ObjectInputStream and abort the reading process.
  26.166 + *
  26.167 + * <p>Implementing the Externalizable interface allows the object to assume
  26.168 + * complete control over the contents and format of the object's serialized
  26.169 + * form.  The methods of the Externalizable interface, writeExternal and
  26.170 + * readExternal, are called to save and restore the objects state.  When
  26.171 + * implemented by a class they can write and read their own state using all of
  26.172 + * the methods of ObjectOutput and ObjectInput.  It is the responsibility of
  26.173 + * the objects to handle any versioning that occurs.
  26.174 + *
  26.175 + * <p>Enum constants are deserialized differently than ordinary serializable or
  26.176 + * externalizable objects.  The serialized form of an enum constant consists
  26.177 + * solely of its name; field values of the constant are not transmitted.  To
  26.178 + * deserialize an enum constant, ObjectInputStream reads the constant name from
  26.179 + * the stream; the deserialized constant is then obtained by calling the static
  26.180 + * method <code>Enum.valueOf(Class, String)</code> with the enum constant's
  26.181 + * base type and the received constant name as arguments.  Like other
  26.182 + * serializable or externalizable objects, enum constants can function as the
  26.183 + * targets of back references appearing subsequently in the serialization
  26.184 + * stream.  The process by which enum constants are deserialized cannot be
  26.185 + * customized: any class-specific readObject, readObjectNoData, and readResolve
  26.186 + * methods defined by enum types are ignored during deserialization.
  26.187 + * Similarly, any serialPersistentFields or serialVersionUID field declarations
  26.188 + * are also ignored--all enum types have a fixed serialVersionUID of 0L.
  26.189 + *
  26.190 + * @author      Mike Warres
  26.191 + * @author      Roger Riggs
  26.192 + * @see java.io.DataInput
  26.193 + * @see java.io.ObjectOutputStream
  26.194 + * @see java.io.Serializable
  26.195 + * @see <a href="../../../platform/serialization/spec/input.html"> Object Serialization Specification, Section 3, Object Input Classes</a>
  26.196 + * @since   JDK1.1
  26.197 + */
  26.198 +public class ObjectInputStream
  26.199 +    extends InputStream implements ObjectInput, ObjectStreamConstants
  26.200 +{
  26.201 +    /** handle value representing null */
  26.202 +    private static final int NULL_HANDLE = -1;
  26.203 +
  26.204 +    /** marker for unshared objects in internal handle table */
  26.205 +    private static final Object unsharedMarker = new Object();
  26.206 +
  26.207 +    /** table mapping primitive type names to corresponding class objects */
  26.208 +    private static final HashMap<String, Class<?>> primClasses
  26.209 +        = new HashMap<>(8, 1.0F);
  26.210 +    static {
  26.211 +        primClasses.put("boolean", boolean.class);
  26.212 +        primClasses.put("byte", byte.class);
  26.213 +        primClasses.put("char", char.class);
  26.214 +        primClasses.put("short", short.class);
  26.215 +        primClasses.put("int", int.class);
  26.216 +        primClasses.put("long", long.class);
  26.217 +        primClasses.put("float", float.class);
  26.218 +        primClasses.put("double", double.class);
  26.219 +        primClasses.put("void", void.class);
  26.220 +    }
  26.221 +
  26.222 +    /** filter stream for handling block data conversion */
  26.223 +    private final BlockDataInputStream bin;
  26.224 +    /** validation callback list */
  26.225 +    private final ValidationList vlist;
  26.226 +    /** recursion depth */
  26.227 +    private int depth;
  26.228 +    /** whether stream is closed */
  26.229 +    private boolean closed;
  26.230 +
  26.231 +    /** wire handle -> obj/exception map */
  26.232 +    private final HandleTable handles;
  26.233 +    /** scratch field for passing handle values up/down call stack */
  26.234 +    private int passHandle = NULL_HANDLE;
  26.235 +    /** flag set when at end of field value block with no TC_ENDBLOCKDATA */
  26.236 +    private boolean defaultDataEnd = false;
  26.237 +
  26.238 +    /** buffer for reading primitive field values */
  26.239 +    private byte[] primVals;
  26.240 +
  26.241 +    /** if true, invoke readObjectOverride() instead of readObject() */
  26.242 +    private final boolean enableOverride;
  26.243 +    /** if true, invoke resolveObject() */
  26.244 +    private boolean enableResolve;
  26.245 +
  26.246 +    /**
  26.247 +     * Context during upcalls to class-defined readObject methods; holds
  26.248 +     * object currently being deserialized and descriptor for current class.
  26.249 +     * Null when not during readObject upcall.
  26.250 +     */
  26.251 +    private Object curContext;
  26.252 +
  26.253 +    /**
  26.254 +     * Creates an ObjectInputStream that reads from the specified InputStream.
  26.255 +     * A serialization stream header is read from the stream and verified.
  26.256 +     * This constructor will block until the corresponding ObjectOutputStream
  26.257 +     * has written and flushed the header.
  26.258 +     *
  26.259 +     * <p>If a security manager is installed, this constructor will check for
  26.260 +     * the "enableSubclassImplementation" SerializablePermission when invoked
  26.261 +     * directly or indirectly by the constructor of a subclass which overrides
  26.262 +     * the ObjectInputStream.readFields or ObjectInputStream.readUnshared
  26.263 +     * methods.
  26.264 +     *
  26.265 +     * @param   in input stream to read from
  26.266 +     * @throws  StreamCorruptedException if the stream header is incorrect
  26.267 +     * @throws  IOException if an I/O error occurs while reading stream header
  26.268 +     * @throws  SecurityException if untrusted subclass illegally overrides
  26.269 +     *          security-sensitive methods
  26.270 +     * @throws  NullPointerException if <code>in</code> is <code>null</code>
  26.271 +     * @see     ObjectInputStream#ObjectInputStream()
  26.272 +     * @see     ObjectInputStream#readFields()
  26.273 +     * @see     ObjectOutputStream#ObjectOutputStream(OutputStream)
  26.274 +     */
  26.275 +    public ObjectInputStream(InputStream in) throws IOException {
  26.276 +        verifySubclass();
  26.277 +        bin = new BlockDataInputStream(in);
  26.278 +        handles = new HandleTable(10);
  26.279 +        vlist = new ValidationList();
  26.280 +        enableOverride = false;
  26.281 +        readStreamHeader();
  26.282 +        bin.setBlockDataMode(true);
  26.283 +    }
  26.284 +
  26.285 +    /**
  26.286 +     * Provide a way for subclasses that are completely reimplementing
  26.287 +     * ObjectInputStream to not have to allocate private data just used by this
  26.288 +     * implementation of ObjectInputStream.
  26.289 +     *
  26.290 +     * <p>If there is a security manager installed, this method first calls the
  26.291 +     * security manager's <code>checkPermission</code> method with the
  26.292 +     * <code>SerializablePermission("enableSubclassImplementation")</code>
  26.293 +     * permission to ensure it's ok to enable subclassing.
  26.294 +     *
  26.295 +     * @throws  SecurityException if a security manager exists and its
  26.296 +     *          <code>checkPermission</code> method denies enabling
  26.297 +     *          subclassing.
  26.298 +     * @see SecurityManager#checkPermission
  26.299 +     * @see java.io.SerializablePermission
  26.300 +     */
  26.301 +    protected ObjectInputStream() throws IOException, SecurityException {
  26.302 +        throw new SecurityException();
  26.303 +    }
  26.304 +
  26.305 +    /**
  26.306 +     * Read an object from the ObjectInputStream.  The class of the object, the
  26.307 +     * signature of the class, and the values of the non-transient and
  26.308 +     * non-static fields of the class and all of its supertypes are read.
  26.309 +     * Default deserializing for a class can be overriden using the writeObject
  26.310 +     * and readObject methods.  Objects referenced by this object are read
  26.311 +     * transitively so that a complete equivalent graph of objects is
  26.312 +     * reconstructed by readObject.
  26.313 +     *
  26.314 +     * <p>The root object is completely restored when all of its fields and the
  26.315 +     * objects it references are completely restored.  At this point the object
  26.316 +     * validation callbacks are executed in order based on their registered
  26.317 +     * priorities. The callbacks are registered by objects (in the readObject
  26.318 +     * special methods) as they are individually restored.
  26.319 +     *
  26.320 +     * <p>Exceptions are thrown for problems with the InputStream and for
  26.321 +     * classes that should not be deserialized.  All exceptions are fatal to
  26.322 +     * the InputStream and leave it in an indeterminate state; it is up to the
  26.323 +     * caller to ignore or recover the stream state.
  26.324 +     *
  26.325 +     * @throws  ClassNotFoundException Class of a serialized object cannot be
  26.326 +     *          found.
  26.327 +     * @throws  InvalidClassException Something is wrong with a class used by
  26.328 +     *          serialization.
  26.329 +     * @throws  StreamCorruptedException Control information in the
  26.330 +     *          stream is inconsistent.
  26.331 +     * @throws  OptionalDataException Primitive data was found in the
  26.332 +     *          stream instead of objects.
  26.333 +     * @throws  IOException Any of the usual Input/Output related exceptions.
  26.334 +     */
  26.335 +    public final Object readObject()
  26.336 +        throws IOException, ClassNotFoundException
  26.337 +    {
  26.338 +        throw new IOException();
  26.339 +    }
  26.340 +
  26.341 +    /**
  26.342 +     * This method is called by trusted subclasses of ObjectOutputStream that
  26.343 +     * constructed ObjectOutputStream using the protected no-arg constructor.
  26.344 +     * The subclass is expected to provide an override method with the modifier
  26.345 +     * "final".
  26.346 +     *
  26.347 +     * @return  the Object read from the stream.
  26.348 +     * @throws  ClassNotFoundException Class definition of a serialized object
  26.349 +     *          cannot be found.
  26.350 +     * @throws  OptionalDataException Primitive data was found in the stream
  26.351 +     *          instead of objects.
  26.352 +     * @throws  IOException if I/O errors occurred while reading from the
  26.353 +     *          underlying stream
  26.354 +     * @see #ObjectInputStream()
  26.355 +     * @see #readObject()
  26.356 +     * @since 1.2
  26.357 +     */
  26.358 +    protected Object readObjectOverride()
  26.359 +        throws IOException, ClassNotFoundException
  26.360 +    {
  26.361 +        return null;
  26.362 +    }
  26.363 +
  26.364 +    /**
  26.365 +     * Reads an "unshared" object from the ObjectInputStream.  This method is
  26.366 +     * identical to readObject, except that it prevents subsequent calls to
  26.367 +     * readObject and readUnshared from returning additional references to the
  26.368 +     * deserialized instance obtained via this call.  Specifically:
  26.369 +     * <ul>
  26.370 +     *   <li>If readUnshared is called to deserialize a back-reference (the
  26.371 +     *       stream representation of an object which has been written
  26.372 +     *       previously to the stream), an ObjectStreamException will be
  26.373 +     *       thrown.
  26.374 +     *
  26.375 +     *   <li>If readUnshared returns successfully, then any subsequent attempts
  26.376 +     *       to deserialize back-references to the stream handle deserialized
  26.377 +     *       by readUnshared will cause an ObjectStreamException to be thrown.
  26.378 +     * </ul>
  26.379 +     * Deserializing an object via readUnshared invalidates the stream handle
  26.380 +     * associated with the returned object.  Note that this in itself does not
  26.381 +     * always guarantee that the reference returned by readUnshared is unique;
  26.382 +     * the deserialized object may define a readResolve method which returns an
  26.383 +     * object visible to other parties, or readUnshared may return a Class
  26.384 +     * object or enum constant obtainable elsewhere in the stream or through
  26.385 +     * external means. If the deserialized object defines a readResolve method
  26.386 +     * and the invocation of that method returns an array, then readUnshared
  26.387 +     * returns a shallow clone of that array; this guarantees that the returned
  26.388 +     * array object is unique and cannot be obtained a second time from an
  26.389 +     * invocation of readObject or readUnshared on the ObjectInputStream,
  26.390 +     * even if the underlying data stream has been manipulated.
  26.391 +     *
  26.392 +     * <p>ObjectInputStream subclasses which override this method can only be
  26.393 +     * constructed in security contexts possessing the
  26.394 +     * "enableSubclassImplementation" SerializablePermission; any attempt to
  26.395 +     * instantiate such a subclass without this permission will cause a
  26.396 +     * SecurityException to be thrown.
  26.397 +     *
  26.398 +     * @return  reference to deserialized object
  26.399 +     * @throws  ClassNotFoundException if class of an object to deserialize
  26.400 +     *          cannot be found
  26.401 +     * @throws  StreamCorruptedException if control information in the stream
  26.402 +     *          is inconsistent
  26.403 +     * @throws  ObjectStreamException if object to deserialize has already
  26.404 +     *          appeared in stream
  26.405 +     * @throws  OptionalDataException if primitive data is next in stream
  26.406 +     * @throws  IOException if an I/O error occurs during deserialization
  26.407 +     * @since   1.4
  26.408 +     */
  26.409 +    public Object readUnshared() throws IOException, ClassNotFoundException {
  26.410 +        // if nested read, passHandle contains handle of enclosing object
  26.411 +        int outerHandle = passHandle;
  26.412 +        try {
  26.413 +            Object obj = readObject0(true);
  26.414 +            handles.markDependency(outerHandle, passHandle);
  26.415 +            ClassNotFoundException ex = handles.lookupException(passHandle);
  26.416 +            if (ex != null) {
  26.417 +                throw ex;
  26.418 +            }
  26.419 +            if (depth == 0) {
  26.420 +                vlist.doCallbacks();
  26.421 +            }
  26.422 +            return obj;
  26.423 +        } finally {
  26.424 +            passHandle = outerHandle;
  26.425 +            if (closed && depth == 0) {
  26.426 +                clear();
  26.427 +            }
  26.428 +        }
  26.429 +    }
  26.430 +
  26.431 +    /**
  26.432 +     * Read the non-static and non-transient fields of the current class from
  26.433 +     * this stream.  This may only be called from the readObject method of the
  26.434 +     * class being deserialized. It will throw the NotActiveException if it is
  26.435 +     * called otherwise.
  26.436 +     *
  26.437 +     * @throws  ClassNotFoundException if the class of a serialized object
  26.438 +     *          could not be found.
  26.439 +     * @throws  IOException if an I/O error occurs.
  26.440 +     * @throws  NotActiveException if the stream is not currently reading
  26.441 +     *          objects.
  26.442 +     */
  26.443 +    public void defaultReadObject()
  26.444 +        throws IOException, ClassNotFoundException
  26.445 +    {
  26.446 +        if (curContext == null) {
  26.447 +            throw new NotActiveException("not in call to readObject");
  26.448 +        }
  26.449 +        Object curObj = null; // curContext.getObj();
  26.450 +        ObjectStreamClass curDesc = null; // curContext.getDesc();
  26.451 +        bin.setBlockDataMode(false);
  26.452 +        defaultReadFields(curObj, curDesc);
  26.453 +        bin.setBlockDataMode(true);
  26.454 +        if (!curDesc.hasWriteObjectData()) {
  26.455 +            /*
  26.456 +             * Fix for 4360508: since stream does not contain terminating
  26.457 +             * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
  26.458 +             * knows to simulate end-of-custom-data behavior.
  26.459 +             */
  26.460 +            defaultDataEnd = true;
  26.461 +        }
  26.462 +        ClassNotFoundException ex = handles.lookupException(passHandle);
  26.463 +        if (ex != null) {
  26.464 +            throw ex;
  26.465 +        }
  26.466 +    }
  26.467 +
  26.468 +    /**
  26.469 +     * Reads the persistent fields from the stream and makes them available by
  26.470 +     * name.
  26.471 +     *
  26.472 +     * @return  the <code>GetField</code> object representing the persistent
  26.473 +     *          fields of the object being deserialized
  26.474 +     * @throws  ClassNotFoundException if the class of a serialized object
  26.475 +     *          could not be found.
  26.476 +     * @throws  IOException if an I/O error occurs.
  26.477 +     * @throws  NotActiveException if the stream is not currently reading
  26.478 +     *          objects.
  26.479 +     * @since 1.2
  26.480 +     */
  26.481 +    public ObjectInputStream.GetField readFields()
  26.482 +        throws IOException, ClassNotFoundException
  26.483 +    {
  26.484 +        if (curContext == null) {
  26.485 +            throw new NotActiveException("not in call to readObject");
  26.486 +        }
  26.487 +        Object curObj = null; // curContext.getObj();
  26.488 +        ObjectStreamClass curDesc = null; // curContext.getDesc();
  26.489 +        bin.setBlockDataMode(false);
  26.490 +        GetFieldImpl getField = new GetFieldImpl(curDesc);
  26.491 +        getField.readFields();
  26.492 +        bin.setBlockDataMode(true);
  26.493 +        if (!curDesc.hasWriteObjectData()) {
  26.494 +            /*
  26.495 +             * Fix for 4360508: since stream does not contain terminating
  26.496 +             * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
  26.497 +             * knows to simulate end-of-custom-data behavior.
  26.498 +             */
  26.499 +            defaultDataEnd = true;
  26.500 +        }
  26.501 +
  26.502 +        return getField;
  26.503 +    }
  26.504 +
  26.505 +    /**
  26.506 +     * Register an object to be validated before the graph is returned.  While
  26.507 +     * similar to resolveObject these validations are called after the entire
  26.508 +     * graph has been reconstituted.  Typically, a readObject method will
  26.509 +     * register the object with the stream so that when all of the objects are
  26.510 +     * restored a final set of validations can be performed.
  26.511 +     *
  26.512 +     * @param   obj the object to receive the validation callback.
  26.513 +     * @param   prio controls the order of callbacks;zero is a good default.
  26.514 +     *          Use higher numbers to be called back earlier, lower numbers for
  26.515 +     *          later callbacks. Within a priority, callbacks are processed in
  26.516 +     *          no particular order.
  26.517 +     * @throws  NotActiveException The stream is not currently reading objects
  26.518 +     *          so it is invalid to register a callback.
  26.519 +     * @throws  InvalidObjectException The validation object is null.
  26.520 +     */
  26.521 +    public void registerValidation(ObjectInputValidation obj, int prio)
  26.522 +        throws NotActiveException, InvalidObjectException
  26.523 +    {
  26.524 +        if (depth == 0) {
  26.525 +            throw new NotActiveException("stream inactive");
  26.526 +        }
  26.527 +        vlist.register(obj, prio);
  26.528 +    }
  26.529 +
  26.530 +    /**
  26.531 +     * Load the local class equivalent of the specified stream class
  26.532 +     * description.  Subclasses may implement this method to allow classes to
  26.533 +     * be fetched from an alternate source.
  26.534 +     *
  26.535 +     * <p>The corresponding method in <code>ObjectOutputStream</code> is
  26.536 +     * <code>annotateClass</code>.  This method will be invoked only once for
  26.537 +     * each unique class in the stream.  This method can be implemented by
  26.538 +     * subclasses to use an alternate loading mechanism but must return a
  26.539 +     * <code>Class</code> object. Once returned, if the class is not an array
  26.540 +     * class, its serialVersionUID is compared to the serialVersionUID of the
  26.541 +     * serialized class, and if there is a mismatch, the deserialization fails
  26.542 +     * and an {@link InvalidClassException} is thrown.
  26.543 +     *
  26.544 +     * <p>The default implementation of this method in
  26.545 +     * <code>ObjectInputStream</code> returns the result of calling
  26.546 +     * <pre>
  26.547 +     *     Class.forName(desc.getName(), false, loader)
  26.548 +     * </pre>
  26.549 +     * where <code>loader</code> is determined as follows: if there is a
  26.550 +     * method on the current thread's stack whose declaring class was
  26.551 +     * defined by a user-defined class loader (and was not a generated to
  26.552 +     * implement reflective invocations), then <code>loader</code> is class
  26.553 +     * loader corresponding to the closest such method to the currently
  26.554 +     * executing frame; otherwise, <code>loader</code> is
  26.555 +     * <code>null</code>. If this call results in a
  26.556 +     * <code>ClassNotFoundException</code> and the name of the passed
  26.557 +     * <code>ObjectStreamClass</code> instance is the Java language keyword
  26.558 +     * for a primitive type or void, then the <code>Class</code> object
  26.559 +     * representing that primitive type or void will be returned
  26.560 +     * (e.g., an <code>ObjectStreamClass</code> with the name
  26.561 +     * <code>"int"</code> will be resolved to <code>Integer.TYPE</code>).
  26.562 +     * Otherwise, the <code>ClassNotFoundException</code> will be thrown to
  26.563 +     * the caller of this method.
  26.564 +     *
  26.565 +     * @param   desc an instance of class <code>ObjectStreamClass</code>
  26.566 +     * @return  a <code>Class</code> object corresponding to <code>desc</code>
  26.567 +     * @throws  IOException any of the usual Input/Output exceptions.
  26.568 +     * @throws  ClassNotFoundException if class of a serialized object cannot
  26.569 +     *          be found.
  26.570 +     */
  26.571 +    protected Class<?> resolveClass(ObjectStreamClass desc)
  26.572 +        throws IOException, ClassNotFoundException
  26.573 +    {
  26.574 +        String name = desc.getName();
  26.575 +        try {
  26.576 +            return Class.forName(name, false, latestUserDefinedLoader());
  26.577 +        } catch (ClassNotFoundException ex) {
  26.578 +            Class<?> cl = primClasses.get(name);
  26.579 +            if (cl != null) {
  26.580 +                return cl;
  26.581 +            } else {
  26.582 +                throw ex;
  26.583 +            }
  26.584 +        }
  26.585 +    }
  26.586 +
  26.587 +    /**
  26.588 +     * Returns a proxy class that implements the interfaces named in a proxy
  26.589 +     * class descriptor; subclasses may implement this method to read custom
  26.590 +     * data from the stream along with the descriptors for dynamic proxy
  26.591 +     * classes, allowing them to use an alternate loading mechanism for the
  26.592 +     * interfaces and the proxy class.
  26.593 +     *
  26.594 +     * <p>This method is called exactly once for each unique proxy class
  26.595 +     * descriptor in the stream.
  26.596 +     *
  26.597 +     * <p>The corresponding method in <code>ObjectOutputStream</code> is
  26.598 +     * <code>annotateProxyClass</code>.  For a given subclass of
  26.599 +     * <code>ObjectInputStream</code> that overrides this method, the
  26.600 +     * <code>annotateProxyClass</code> method in the corresponding subclass of
  26.601 +     * <code>ObjectOutputStream</code> must write any data or objects read by
  26.602 +     * this method.
  26.603 +     *
  26.604 +     * <p>The default implementation of this method in
  26.605 +     * <code>ObjectInputStream</code> returns the result of calling
  26.606 +     * <code>Proxy.getProxyClass</code> with the list of <code>Class</code>
  26.607 +     * objects for the interfaces that are named in the <code>interfaces</code>
  26.608 +     * parameter.  The <code>Class</code> object for each interface name
  26.609 +     * <code>i</code> is the value returned by calling
  26.610 +     * <pre>
  26.611 +     *     Class.forName(i, false, loader)
  26.612 +     * </pre>
  26.613 +     * where <code>loader</code> is that of the first non-<code>null</code>
  26.614 +     * class loader up the execution stack, or <code>null</code> if no
  26.615 +     * non-<code>null</code> class loaders are on the stack (the same class
  26.616 +     * loader choice used by the <code>resolveClass</code> method).  Unless any
  26.617 +     * of the resolved interfaces are non-public, this same value of
  26.618 +     * <code>loader</code> is also the class loader passed to
  26.619 +     * <code>Proxy.getProxyClass</code>; if non-public interfaces are present,
  26.620 +     * their class loader is passed instead (if more than one non-public
  26.621 +     * interface class loader is encountered, an
  26.622 +     * <code>IllegalAccessError</code> is thrown).
  26.623 +     * If <code>Proxy.getProxyClass</code> throws an
  26.624 +     * <code>IllegalArgumentException</code>, <code>resolveProxyClass</code>
  26.625 +     * will throw a <code>ClassNotFoundException</code> containing the
  26.626 +     * <code>IllegalArgumentException</code>.
  26.627 +     *
  26.628 +     * @param interfaces the list of interface names that were
  26.629 +     *                deserialized in the proxy class descriptor
  26.630 +     * @return  a proxy class for the specified interfaces
  26.631 +     * @throws        IOException any exception thrown by the underlying
  26.632 +     *                <code>InputStream</code>
  26.633 +     * @throws        ClassNotFoundException if the proxy class or any of the
  26.634 +     *                named interfaces could not be found
  26.635 +     * @see ObjectOutputStream#annotateProxyClass(Class)
  26.636 +     * @since 1.3
  26.637 +     */
  26.638 +    protected Class<?> resolveProxyClass(String[] interfaces)
  26.639 +        throws IOException, ClassNotFoundException
  26.640 +    {
  26.641 +        ClassLoader latestLoader = latestUserDefinedLoader();
  26.642 +        ClassLoader nonPublicLoader = null;
  26.643 +        boolean hasNonPublicInterface = false;
  26.644 +
  26.645 +        // define proxy in class loader of non-public interface(s), if any
  26.646 +        Class[] classObjs = new Class[interfaces.length];
  26.647 +        for (int i = 0; i < interfaces.length; i++) {
  26.648 +            Class cl = Class.forName(interfaces[i], false, latestLoader);
  26.649 +            if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
  26.650 +                if (hasNonPublicInterface) {
  26.651 +                    if (nonPublicLoader != cl.getClassLoader()) {
  26.652 +                        throw new IllegalAccessError(
  26.653 +                            "conflicting non-public interface class loaders");
  26.654 +                    }
  26.655 +                } else {
  26.656 +                    nonPublicLoader = cl.getClassLoader();
  26.657 +                    hasNonPublicInterface = true;
  26.658 +                }
  26.659 +            }
  26.660 +            classObjs[i] = cl;
  26.661 +        }
  26.662 +        try {
  26.663 +            return Proxy.getProxyClass(
  26.664 +                hasNonPublicInterface ? nonPublicLoader : latestLoader,
  26.665 +                classObjs);
  26.666 +        } catch (IllegalArgumentException e) {
  26.667 +            throw new ClassNotFoundException(null, e);
  26.668 +        }
  26.669 +    }
  26.670 +
  26.671 +    /**
  26.672 +     * This method will allow trusted subclasses of ObjectInputStream to
  26.673 +     * substitute one object for another during deserialization. Replacing
  26.674 +     * objects is disabled until enableResolveObject is called. The
  26.675 +     * enableResolveObject method checks that the stream requesting to resolve
  26.676 +     * object can be trusted. Every reference to serializable objects is passed
  26.677 +     * to resolveObject.  To insure that the private state of objects is not
  26.678 +     * unintentionally exposed only trusted streams may use resolveObject.
  26.679 +     *
  26.680 +     * <p>This method is called after an object has been read but before it is
  26.681 +     * returned from readObject.  The default resolveObject method just returns
  26.682 +     * the same object.
  26.683 +     *
  26.684 +     * <p>When a subclass is replacing objects it must insure that the
  26.685 +     * substituted object is compatible with every field where the reference
  26.686 +     * will be stored.  Objects whose type is not a subclass of the type of the
  26.687 +     * field or array element abort the serialization by raising an exception
  26.688 +     * and the object is not be stored.
  26.689 +     *
  26.690 +     * <p>This method is called only once when each object is first
  26.691 +     * encountered.  All subsequent references to the object will be redirected
  26.692 +     * to the new object.
  26.693 +     *
  26.694 +     * @param   obj object to be substituted
  26.695 +     * @return  the substituted object
  26.696 +     * @throws  IOException Any of the usual Input/Output exceptions.
  26.697 +     */
  26.698 +    protected Object resolveObject(Object obj) throws IOException {
  26.699 +        return obj;
  26.700 +    }
  26.701 +
  26.702 +    /**
  26.703 +     * Enable the stream to allow objects read from the stream to be replaced.
  26.704 +     * When enabled, the resolveObject method is called for every object being
  26.705 +     * deserialized.
  26.706 +     *
  26.707 +     * <p>If <i>enable</i> is true, and there is a security manager installed,
  26.708 +     * this method first calls the security manager's
  26.709 +     * <code>checkPermission</code> method with the
  26.710 +     * <code>SerializablePermission("enableSubstitution")</code> permission to
  26.711 +     * ensure it's ok to enable the stream to allow objects read from the
  26.712 +     * stream to be replaced.
  26.713 +     *
  26.714 +     * @param   enable true for enabling use of <code>resolveObject</code> for
  26.715 +     *          every object being deserialized
  26.716 +     * @return  the previous setting before this method was invoked
  26.717 +     * @throws  SecurityException if a security manager exists and its
  26.718 +     *          <code>checkPermission</code> method denies enabling the stream
  26.719 +     *          to allow objects read from the stream to be replaced.
  26.720 +     * @see SecurityManager#checkPermission
  26.721 +     * @see java.io.SerializablePermission
  26.722 +     */
  26.723 +    protected boolean enableResolveObject(boolean enable)
  26.724 +        throws SecurityException
  26.725 +    {
  26.726 +        throw new SecurityException();
  26.727 +    }
  26.728 +
  26.729 +    /**
  26.730 +     * The readStreamHeader method is provided to allow subclasses to read and
  26.731 +     * verify their own stream headers. It reads and verifies the magic number
  26.732 +     * and version number.
  26.733 +     *
  26.734 +     * @throws  IOException if there are I/O errors while reading from the
  26.735 +     *          underlying <code>InputStream</code>
  26.736 +     * @throws  StreamCorruptedException if control information in the stream
  26.737 +     *          is inconsistent
  26.738 +     */
  26.739 +    protected void readStreamHeader()
  26.740 +        throws IOException, StreamCorruptedException
  26.741 +    {
  26.742 +        short s0 = bin.readShort();
  26.743 +        short s1 = bin.readShort();
  26.744 +        if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) {
  26.745 +            throw new StreamCorruptedException(
  26.746 +                String.format("invalid stream header: %04X%04X", s0, s1));
  26.747 +        }
  26.748 +    }
  26.749 +
  26.750 +    /**
  26.751 +     * Read a class descriptor from the serialization stream.  This method is
  26.752 +     * called when the ObjectInputStream expects a class descriptor as the next
  26.753 +     * item in the serialization stream.  Subclasses of ObjectInputStream may
  26.754 +     * override this method to read in class descriptors that have been written
  26.755 +     * in non-standard formats (by subclasses of ObjectOutputStream which have
  26.756 +     * overridden the <code>writeClassDescriptor</code> method).  By default,
  26.757 +     * this method reads class descriptors according to the format defined in
  26.758 +     * the Object Serialization specification.
  26.759 +     *
  26.760 +     * @return  the class descriptor read
  26.761 +     * @throws  IOException If an I/O error has occurred.
  26.762 +     * @throws  ClassNotFoundException If the Class of a serialized object used
  26.763 +     *          in the class descriptor representation cannot be found
  26.764 +     * @see java.io.ObjectOutputStream#writeClassDescriptor(java.io.ObjectStreamClass)
  26.765 +     * @since 1.3
  26.766 +     */
  26.767 +    protected ObjectStreamClass readClassDescriptor()
  26.768 +        throws IOException, ClassNotFoundException
  26.769 +    {
  26.770 +        ObjectStreamClass desc = new ObjectStreamClass();
  26.771 +        desc.readNonProxy(this);
  26.772 +        return desc;
  26.773 +    }
  26.774 +
  26.775 +    /**
  26.776 +     * Reads a byte of data. This method will block if no input is available.
  26.777 +     *
  26.778 +     * @return  the byte read, or -1 if the end of the stream is reached.
  26.779 +     * @throws  IOException If an I/O error has occurred.
  26.780 +     */
  26.781 +    public int read() throws IOException {
  26.782 +        return bin.read();
  26.783 +    }
  26.784 +
  26.785 +    /**
  26.786 +     * Reads into an array of bytes.  This method will block until some input
  26.787 +     * is available. Consider using java.io.DataInputStream.readFully to read
  26.788 +     * exactly 'length' bytes.
  26.789 +     *
  26.790 +     * @param   buf the buffer into which the data is read
  26.791 +     * @param   off the start offset of the data
  26.792 +     * @param   len the maximum number of bytes read
  26.793 +     * @return  the actual number of bytes read, -1 is returned when the end of
  26.794 +     *          the stream is reached.
  26.795 +     * @throws  IOException If an I/O error has occurred.
  26.796 +     * @see java.io.DataInputStream#readFully(byte[],int,int)
  26.797 +     */
  26.798 +    public int read(byte[] buf, int off, int len) throws IOException {
  26.799 +        if (buf == null) {
  26.800 +            throw new NullPointerException();
  26.801 +        }
  26.802 +        int endoff = off + len;
  26.803 +        if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) {
  26.804 +            throw new IndexOutOfBoundsException();
  26.805 +        }
  26.806 +        return bin.read(buf, off, len, false);
  26.807 +    }
  26.808 +
  26.809 +    /**
  26.810 +     * Returns the number of bytes that can be read without blocking.
  26.811 +     *
  26.812 +     * @return  the number of available bytes.
  26.813 +     * @throws  IOException if there are I/O errors while reading from the
  26.814 +     *          underlying <code>InputStream</code>
  26.815 +     */
  26.816 +    public int available() throws IOException {
  26.817 +        return bin.available();
  26.818 +    }
  26.819 +
  26.820 +    /**
  26.821 +     * Closes the input stream. Must be called to release any resources
  26.822 +     * associated with the stream.
  26.823 +     *
  26.824 +     * @throws  IOException If an I/O error has occurred.
  26.825 +     */
  26.826 +    public void close() throws IOException {
  26.827 +        /*
  26.828 +         * Even if stream already closed, propagate redundant close to
  26.829 +         * underlying stream to stay consistent with previous implementations.
  26.830 +         */
  26.831 +        closed = true;
  26.832 +        if (depth == 0) {
  26.833 +            clear();
  26.834 +        }
  26.835 +        bin.close();
  26.836 +    }
  26.837 +
  26.838 +    /**
  26.839 +     * Reads in a boolean.
  26.840 +     *
  26.841 +     * @return  the boolean read.
  26.842 +     * @throws  EOFException If end of file is reached.
  26.843 +     * @throws  IOException If other I/O error has occurred.
  26.844 +     */
  26.845 +    public boolean readBoolean() throws IOException {
  26.846 +        return bin.readBoolean();
  26.847 +    }
  26.848 +
  26.849 +    /**
  26.850 +     * Reads an 8 bit byte.
  26.851 +     *
  26.852 +     * @return  the 8 bit byte read.
  26.853 +     * @throws  EOFException If end of file is reached.
  26.854 +     * @throws  IOException If other I/O error has occurred.
  26.855 +     */
  26.856 +    public byte readByte() throws IOException  {
  26.857 +        return bin.readByte();
  26.858 +    }
  26.859 +
  26.860 +    /**
  26.861 +     * Reads an unsigned 8 bit byte.
  26.862 +     *
  26.863 +     * @return  the 8 bit byte read.
  26.864 +     * @throws  EOFException If end of file is reached.
  26.865 +     * @throws  IOException If other I/O error has occurred.
  26.866 +     */
  26.867 +    public int readUnsignedByte()  throws IOException {
  26.868 +        return bin.readUnsignedByte();
  26.869 +    }
  26.870 +
  26.871 +    /**
  26.872 +     * Reads a 16 bit char.
  26.873 +     *
  26.874 +     * @return  the 16 bit char read.
  26.875 +     * @throws  EOFException If end of file is reached.
  26.876 +     * @throws  IOException If other I/O error has occurred.
  26.877 +     */
  26.878 +    public char readChar()  throws IOException {
  26.879 +        return bin.readChar();
  26.880 +    }
  26.881 +
  26.882 +    /**
  26.883 +     * Reads a 16 bit short.
  26.884 +     *
  26.885 +     * @return  the 16 bit short read.
  26.886 +     * @throws  EOFException If end of file is reached.
  26.887 +     * @throws  IOException If other I/O error has occurred.
  26.888 +     */
  26.889 +    public short readShort()  throws IOException {
  26.890 +        return bin.readShort();
  26.891 +    }
  26.892 +
  26.893 +    /**
  26.894 +     * Reads an unsigned 16 bit short.
  26.895 +     *
  26.896 +     * @return  the 16 bit short read.
  26.897 +     * @throws  EOFException If end of file is reached.
  26.898 +     * @throws  IOException If other I/O error has occurred.
  26.899 +     */
  26.900 +    public int readUnsignedShort() throws IOException {
  26.901 +        return bin.readUnsignedShort();
  26.902 +    }
  26.903 +
  26.904 +    /**
  26.905 +     * Reads a 32 bit int.
  26.906 +     *
  26.907 +     * @return  the 32 bit integer read.
  26.908 +     * @throws  EOFException If end of file is reached.
  26.909 +     * @throws  IOException If other I/O error has occurred.
  26.910 +     */
  26.911 +    public int readInt()  throws IOException {
  26.912 +        return bin.readInt();
  26.913 +    }
  26.914 +
  26.915 +    /**
  26.916 +     * Reads a 64 bit long.
  26.917 +     *
  26.918 +     * @return  the read 64 bit long.
  26.919 +     * @throws  EOFException If end of file is reached.
  26.920 +     * @throws  IOException If other I/O error has occurred.
  26.921 +     */
  26.922 +    public long readLong()  throws IOException {
  26.923 +        return bin.readLong();
  26.924 +    }
  26.925 +
  26.926 +    /**
  26.927 +     * Reads a 32 bit float.
  26.928 +     *
  26.929 +     * @return  the 32 bit float read.
  26.930 +     * @throws  EOFException If end of file is reached.
  26.931 +     * @throws  IOException If other I/O error has occurred.
  26.932 +     */
  26.933 +    public float readFloat() throws IOException {
  26.934 +        return bin.readFloat();
  26.935 +    }
  26.936 +
  26.937 +    /**
  26.938 +     * Reads a 64 bit double.
  26.939 +     *
  26.940 +     * @return  the 64 bit double read.
  26.941 +     * @throws  EOFException If end of file is reached.
  26.942 +     * @throws  IOException If other I/O error has occurred.
  26.943 +     */
  26.944 +    public double readDouble() throws IOException {
  26.945 +        return bin.readDouble();
  26.946 +    }
  26.947 +
  26.948 +    /**
  26.949 +     * Reads bytes, blocking until all bytes are read.
  26.950 +     *
  26.951 +     * @param   buf the buffer into which the data is read
  26.952 +     * @throws  EOFException If end of file is reached.
  26.953 +     * @throws  IOException If other I/O error has occurred.
  26.954 +     */
  26.955 +    public void readFully(byte[] buf) throws IOException {
  26.956 +        bin.readFully(buf, 0, buf.length, false);
  26.957 +    }
  26.958 +
  26.959 +    /**
  26.960 +     * Reads bytes, blocking until all bytes are read.
  26.961 +     *
  26.962 +     * @param   buf the buffer into which the data is read
  26.963 +     * @param   off the start offset of the data
  26.964 +     * @param   len the maximum number of bytes to read
  26.965 +     * @throws  EOFException If end of file is reached.
  26.966 +     * @throws  IOException If other I/O error has occurred.
  26.967 +     */
  26.968 +    public void readFully(byte[] buf, int off, int len) throws IOException {
  26.969 +        int endoff = off + len;
  26.970 +        if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) {
  26.971 +            throw new IndexOutOfBoundsException();
  26.972 +        }
  26.973 +        bin.readFully(buf, off, len, false);
  26.974 +    }
  26.975 +
  26.976 +    /**
  26.977 +     * Skips bytes.
  26.978 +     *
  26.979 +     * @param   len the number of bytes to be skipped
  26.980 +     * @return  the actual number of bytes skipped.
  26.981 +     * @throws  IOException If an I/O error has occurred.
  26.982 +     */
  26.983 +    public int skipBytes(int len) throws IOException {
  26.984 +        return bin.skipBytes(len);
  26.985 +    }
  26.986 +
  26.987 +    /**
  26.988 +     * Reads in a line that has been terminated by a \n, \r, \r\n or EOF.
  26.989 +     *
  26.990 +     * @return  a String copy of the line.
  26.991 +     * @throws  IOException if there are I/O errors while reading from the
  26.992 +     *          underlying <code>InputStream</code>
  26.993 +     * @deprecated This method does not properly convert bytes to characters.
  26.994 +     *          see DataInputStream for the details and alternatives.
  26.995 +     */
  26.996 +    @Deprecated
  26.997 +    public String readLine() throws IOException {
  26.998 +        return bin.readLine();
  26.999 +    }
 26.1000 +
 26.1001 +    /**
 26.1002 +     * Reads a String in
 26.1003 +     * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
 26.1004 +     * format.
 26.1005 +     *
 26.1006 +     * @return  the String.
 26.1007 +     * @throws  IOException if there are I/O errors while reading from the
 26.1008 +     *          underlying <code>InputStream</code>
 26.1009 +     * @throws  UTFDataFormatException if read bytes do not represent a valid
 26.1010 +     *          modified UTF-8 encoding of a string
 26.1011 +     */
 26.1012 +    public String readUTF() throws IOException {
 26.1013 +        return bin.readUTF();
 26.1014 +    }
 26.1015 +
 26.1016 +    /**
 26.1017 +     * Provide access to the persistent fields read from the input stream.
 26.1018 +     */
 26.1019 +    public static abstract class GetField {
 26.1020 +
 26.1021 +        /**
 26.1022 +         * Get the ObjectStreamClass that describes the fields in the stream.
 26.1023 +         *
 26.1024 +         * @return  the descriptor class that describes the serializable fields
 26.1025 +         */
 26.1026 +        public abstract ObjectStreamClass getObjectStreamClass();
 26.1027 +
 26.1028 +        /**
 26.1029 +         * Return true if the named field is defaulted and has no value in this
 26.1030 +         * stream.
 26.1031 +         *
 26.1032 +         * @param  name the name of the field
 26.1033 +         * @return true, if and only if the named field is defaulted
 26.1034 +         * @throws IOException if there are I/O errors while reading from
 26.1035 +         *         the underlying <code>InputStream</code>
 26.1036 +         * @throws IllegalArgumentException if <code>name</code> does not
 26.1037 +         *         correspond to a serializable field
 26.1038 +         */
 26.1039 +        public abstract boolean defaulted(String name) throws IOException;
 26.1040 +
 26.1041 +        /**
 26.1042 +         * Get the value of the named boolean field from the persistent field.
 26.1043 +         *
 26.1044 +         * @param  name the name of the field
 26.1045 +         * @param  val the default value to use if <code>name</code> does not
 26.1046 +         *         have a value
 26.1047 +         * @return the value of the named <code>boolean</code> field
 26.1048 +         * @throws IOException if there are I/O errors while reading from the
 26.1049 +         *         underlying <code>InputStream</code>
 26.1050 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1051 +         *         not serializable or if the field type is incorrect
 26.1052 +         */
 26.1053 +        public abstract boolean get(String name, boolean val)
 26.1054 +            throws IOException;
 26.1055 +
 26.1056 +        /**
 26.1057 +         * Get the value of the named byte field from the persistent field.
 26.1058 +         *
 26.1059 +         * @param  name the name of the field
 26.1060 +         * @param  val the default value to use if <code>name</code> does not
 26.1061 +         *         have a value
 26.1062 +         * @return the value of the named <code>byte</code> field
 26.1063 +         * @throws IOException if there are I/O errors while reading from the
 26.1064 +         *         underlying <code>InputStream</code>
 26.1065 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1066 +         *         not serializable or if the field type is incorrect
 26.1067 +         */
 26.1068 +        public abstract byte get(String name, byte val) throws IOException;
 26.1069 +
 26.1070 +        /**
 26.1071 +         * Get the value of the named char field from the persistent field.
 26.1072 +         *
 26.1073 +         * @param  name the name of the field
 26.1074 +         * @param  val the default value to use if <code>name</code> does not
 26.1075 +         *         have a value
 26.1076 +         * @return the value of the named <code>char</code> field
 26.1077 +         * @throws IOException if there are I/O errors while reading from the
 26.1078 +         *         underlying <code>InputStream</code>
 26.1079 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1080 +         *         not serializable or if the field type is incorrect
 26.1081 +         */
 26.1082 +        public abstract char get(String name, char val) throws IOException;
 26.1083 +
 26.1084 +        /**
 26.1085 +         * Get the value of the named short field from the persistent field.
 26.1086 +         *
 26.1087 +         * @param  name the name of the field
 26.1088 +         * @param  val the default value to use if <code>name</code> does not
 26.1089 +         *         have a value
 26.1090 +         * @return the value of the named <code>short</code> field
 26.1091 +         * @throws IOException if there are I/O errors while reading from the
 26.1092 +         *         underlying <code>InputStream</code>
 26.1093 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1094 +         *         not serializable or if the field type is incorrect
 26.1095 +         */
 26.1096 +        public abstract short get(String name, short val) throws IOException;
 26.1097 +
 26.1098 +        /**
 26.1099 +         * Get the value of the named int field from the persistent field.
 26.1100 +         *
 26.1101 +         * @param  name the name of the field
 26.1102 +         * @param  val the default value to use if <code>name</code> does not
 26.1103 +         *         have a value
 26.1104 +         * @return the value of the named <code>int</code> field
 26.1105 +         * @throws IOException if there are I/O errors while reading from the
 26.1106 +         *         underlying <code>InputStream</code>
 26.1107 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1108 +         *         not serializable or if the field type is incorrect
 26.1109 +         */
 26.1110 +        public abstract int get(String name, int val) throws IOException;
 26.1111 +
 26.1112 +        /**
 26.1113 +         * Get the value of the named long field from the persistent field.
 26.1114 +         *
 26.1115 +         * @param  name the name of the field
 26.1116 +         * @param  val the default value to use if <code>name</code> does not
 26.1117 +         *         have a value
 26.1118 +         * @return the value of the named <code>long</code> field
 26.1119 +         * @throws IOException if there are I/O errors while reading from the
 26.1120 +         *         underlying <code>InputStream</code>
 26.1121 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1122 +         *         not serializable or if the field type is incorrect
 26.1123 +         */
 26.1124 +        public abstract long get(String name, long val) throws IOException;
 26.1125 +
 26.1126 +        /**
 26.1127 +         * Get the value of the named float field from the persistent field.
 26.1128 +         *
 26.1129 +         * @param  name the name of the field
 26.1130 +         * @param  val the default value to use if <code>name</code> does not
 26.1131 +         *         have a value
 26.1132 +         * @return the value of the named <code>float</code> field
 26.1133 +         * @throws IOException if there are I/O errors while reading from the
 26.1134 +         *         underlying <code>InputStream</code>
 26.1135 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1136 +         *         not serializable or if the field type is incorrect
 26.1137 +         */
 26.1138 +        public abstract float get(String name, float val) throws IOException;
 26.1139 +
 26.1140 +        /**
 26.1141 +         * Get the value of the named double field from the persistent field.
 26.1142 +         *
 26.1143 +         * @param  name the name of the field
 26.1144 +         * @param  val the default value to use if <code>name</code> does not
 26.1145 +         *         have a value
 26.1146 +         * @return the value of the named <code>double</code> field
 26.1147 +         * @throws IOException if there are I/O errors while reading from the
 26.1148 +         *         underlying <code>InputStream</code>
 26.1149 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1150 +         *         not serializable or if the field type is incorrect
 26.1151 +         */
 26.1152 +        public abstract double get(String name, double val) throws IOException;
 26.1153 +
 26.1154 +        /**
 26.1155 +         * Get the value of the named Object field from the persistent field.
 26.1156 +         *
 26.1157 +         * @param  name the name of the field
 26.1158 +         * @param  val the default value to use if <code>name</code> does not
 26.1159 +         *         have a value
 26.1160 +         * @return the value of the named <code>Object</code> field
 26.1161 +         * @throws IOException if there are I/O errors while reading from the
 26.1162 +         *         underlying <code>InputStream</code>
 26.1163 +         * @throws IllegalArgumentException if type of <code>name</code> is
 26.1164 +         *         not serializable or if the field type is incorrect
 26.1165 +         */
 26.1166 +        public abstract Object get(String name, Object val) throws IOException;
 26.1167 +    }
 26.1168 +
 26.1169 +    /**
 26.1170 +     * Verifies that this (possibly subclass) instance can be constructed
 26.1171 +     * without violating security constraints: the subclass must not override
 26.1172 +     * security-sensitive non-final methods, or else the
 26.1173 +     * "enableSubclassImplementation" SerializablePermission is checked.
 26.1174 +     */
 26.1175 +    private void verifySubclass() {
 26.1176 +        Class cl = getClass();
 26.1177 +        if (cl == ObjectInputStream.class) {
 26.1178 +            return;
 26.1179 +        }
 26.1180 +        throw new SecurityException();
 26.1181 +    }
 26.1182 +
 26.1183 +    /**
 26.1184 +     * Clears internal data structures.
 26.1185 +     */
 26.1186 +    private void clear() {
 26.1187 +        handles.clear();
 26.1188 +        vlist.clear();
 26.1189 +    }
 26.1190 +
 26.1191 +    /**
 26.1192 +     * Underlying readObject implementation.
 26.1193 +     */
 26.1194 +    private Object readObject0(boolean unshared) throws IOException {
 26.1195 +        boolean oldMode = bin.getBlockDataMode();
 26.1196 +        if (oldMode) {
 26.1197 +            int remain = bin.currentBlockRemaining();
 26.1198 +            if (remain > 0) {
 26.1199 +                throw new OptionalDataException(remain);
 26.1200 +            } else if (defaultDataEnd) {
 26.1201 +                /*
 26.1202 +                 * Fix for 4360508: stream is currently at the end of a field
 26.1203 +                 * value block written via default serialization; since there
 26.1204 +                 * is no terminating TC_ENDBLOCKDATA tag, simulate
 26.1205 +                 * end-of-custom-data behavior explicitly.
 26.1206 +                 */
 26.1207 +                throw new OptionalDataException(true);
 26.1208 +            }
 26.1209 +            bin.setBlockDataMode(false);
 26.1210 +        }
 26.1211 +
 26.1212 +        byte tc;
 26.1213 +        while ((tc = bin.peekByte()) == TC_RESET) {
 26.1214 +            bin.readByte();
 26.1215 +            handleReset();
 26.1216 +        }
 26.1217 +
 26.1218 +        depth++;
 26.1219 +        try {
 26.1220 +            switch (tc) {
 26.1221 +                case TC_NULL:
 26.1222 +                    return readNull();
 26.1223 +
 26.1224 +                case TC_REFERENCE:
 26.1225 +                    return readHandle(unshared);
 26.1226 +
 26.1227 +                case TC_CLASS:
 26.1228 +                    return readClass(unshared);
 26.1229 +
 26.1230 +                case TC_CLASSDESC:
 26.1231 +                case TC_PROXYCLASSDESC:
 26.1232 +                    return readClassDesc(unshared);
 26.1233 +
 26.1234 +                case TC_STRING:
 26.1235 +                case TC_LONGSTRING:
 26.1236 +                    return checkResolve(readString(unshared));
 26.1237 +
 26.1238 +                case TC_ARRAY:
 26.1239 +                    return checkResolve(readArray(unshared));
 26.1240 +
 26.1241 +                case TC_ENUM:
 26.1242 +                    return checkResolve(readEnum(unshared));
 26.1243 +
 26.1244 +                case TC_OBJECT:
 26.1245 +                    return checkResolve(readOrdinaryObject(unshared));
 26.1246 +
 26.1247 +                case TC_EXCEPTION:
 26.1248 +                    IOException ex = readFatalException();
 26.1249 +                    throw new WriteAbortedException("writing aborted", ex);
 26.1250 +
 26.1251 +                case TC_BLOCKDATA:
 26.1252 +                case TC_BLOCKDATALONG:
 26.1253 +                    if (oldMode) {
 26.1254 +                        bin.setBlockDataMode(true);
 26.1255 +                        bin.peek();             // force header read
 26.1256 +                        throw new OptionalDataException(
 26.1257 +                            bin.currentBlockRemaining());
 26.1258 +                    } else {
 26.1259 +                        throw new StreamCorruptedException(
 26.1260 +                            "unexpected block data");
 26.1261 +                    }
 26.1262 +
 26.1263 +                case TC_ENDBLOCKDATA:
 26.1264 +                    if (oldMode) {
 26.1265 +                        throw new OptionalDataException(true);
 26.1266 +                    } else {
 26.1267 +                        throw new StreamCorruptedException(
 26.1268 +                            "unexpected end of block data");
 26.1269 +                    }
 26.1270 +
 26.1271 +                default:
 26.1272 +                    throw new StreamCorruptedException(
 26.1273 +                        String.format("invalid type code: %02X", tc));
 26.1274 +            }
 26.1275 +        } finally {
 26.1276 +            depth--;
 26.1277 +            bin.setBlockDataMode(oldMode);
 26.1278 +        }
 26.1279 +    }
 26.1280 +
 26.1281 +    /**
 26.1282 +     * If resolveObject has been enabled and given object does not have an
 26.1283 +     * exception associated with it, calls resolveObject to determine
 26.1284 +     * replacement for object, and updates handle table accordingly.  Returns
 26.1285 +     * replacement object, or echoes provided object if no replacement
 26.1286 +     * occurred.  Expects that passHandle is set to given object's handle prior
 26.1287 +     * to calling this method.
 26.1288 +     */
 26.1289 +    private Object checkResolve(Object obj) throws IOException {
 26.1290 +        if (!enableResolve || handles.lookupException(passHandle) != null) {
 26.1291 +            return obj;
 26.1292 +        }
 26.1293 +        Object rep = resolveObject(obj);
 26.1294 +        if (rep != obj) {
 26.1295 +            handles.setObject(passHandle, rep);
 26.1296 +        }
 26.1297 +        return rep;
 26.1298 +    }
 26.1299 +
 26.1300 +    /**
 26.1301 +     * Reads string without allowing it to be replaced in stream.  Called from
 26.1302 +     * within ObjectStreamClass.read().
 26.1303 +     */
 26.1304 +    String readTypeString() throws IOException {
 26.1305 +        int oldHandle = passHandle;
 26.1306 +        try {
 26.1307 +            byte tc = bin.peekByte();
 26.1308 +            switch (tc) {
 26.1309 +                case TC_NULL:
 26.1310 +                    return (String) readNull();
 26.1311 +
 26.1312 +                case TC_REFERENCE:
 26.1313 +                    return (String) readHandle(false);
 26.1314 +
 26.1315 +                case TC_STRING:
 26.1316 +                case TC_LONGSTRING:
 26.1317 +                    return readString(false);
 26.1318 +
 26.1319 +                default:
 26.1320 +                    throw new StreamCorruptedException(
 26.1321 +                        String.format("invalid type code: %02X", tc));
 26.1322 +            }
 26.1323 +        } finally {
 26.1324 +            passHandle = oldHandle;
 26.1325 +        }
 26.1326 +    }
 26.1327 +
 26.1328 +    /**
 26.1329 +     * Reads in null code, sets passHandle to NULL_HANDLE and returns null.
 26.1330 +     */
 26.1331 +    private Object readNull() throws IOException {
 26.1332 +        if (bin.readByte() != TC_NULL) {
 26.1333 +            throw new InternalError();
 26.1334 +        }
 26.1335 +        passHandle = NULL_HANDLE;
 26.1336 +        return null;
 26.1337 +    }
 26.1338 +
 26.1339 +    /**
 26.1340 +     * Reads in object handle, sets passHandle to the read handle, and returns
 26.1341 +     * object associated with the handle.
 26.1342 +     */
 26.1343 +    private Object readHandle(boolean unshared) throws IOException {
 26.1344 +        if (bin.readByte() != TC_REFERENCE) {
 26.1345 +            throw new InternalError();
 26.1346 +        }
 26.1347 +        passHandle = bin.readInt() - baseWireHandle;
 26.1348 +        if (passHandle < 0 || passHandle >= handles.size()) {
 26.1349 +            throw new StreamCorruptedException(
 26.1350 +                String.format("invalid handle value: %08X", passHandle +
 26.1351 +                baseWireHandle));
 26.1352 +        }
 26.1353 +        if (unshared) {
 26.1354 +            // REMIND: what type of exception to throw here?
 26.1355 +            throw new InvalidObjectException(
 26.1356 +                "cannot read back reference as unshared");
 26.1357 +        }
 26.1358 +
 26.1359 +        Object obj = handles.lookupObject(passHandle);
 26.1360 +        if (obj == unsharedMarker) {
 26.1361 +            // REMIND: what type of exception to throw here?
 26.1362 +            throw new InvalidObjectException(
 26.1363 +                "cannot read back reference to unshared object");
 26.1364 +        }
 26.1365 +        return obj;
 26.1366 +    }
 26.1367 +
 26.1368 +    /**
 26.1369 +     * Reads in and returns class object.  Sets passHandle to class object's
 26.1370 +     * assigned handle.  Returns null if class is unresolvable (in which case a
 26.1371 +     * ClassNotFoundException will be associated with the class' handle in the
 26.1372 +     * handle table).
 26.1373 +     */
 26.1374 +    private Class readClass(boolean unshared) throws IOException {
 26.1375 +        if (bin.readByte() != TC_CLASS) {
 26.1376 +            throw new InternalError();
 26.1377 +        }
 26.1378 +        ObjectStreamClass desc = readClassDesc(false);
 26.1379 +        Class cl = desc.forClass();
 26.1380 +        passHandle = handles.assign(unshared ? unsharedMarker : cl);
 26.1381 +
 26.1382 +        ClassNotFoundException resolveEx = desc.getResolveException();
 26.1383 +        if (resolveEx != null) {
 26.1384 +            handles.markException(passHandle, resolveEx);
 26.1385 +        }
 26.1386 +
 26.1387 +        handles.finish(passHandle);
 26.1388 +        return cl;
 26.1389 +    }
 26.1390 +
 26.1391 +    /**
 26.1392 +     * Reads in and returns (possibly null) class descriptor.  Sets passHandle
 26.1393 +     * to class descriptor's assigned handle.  If class descriptor cannot be
 26.1394 +     * resolved to a class in the local VM, a ClassNotFoundException is
 26.1395 +     * associated with the class descriptor's handle.
 26.1396 +     */
 26.1397 +    private ObjectStreamClass readClassDesc(boolean unshared)
 26.1398 +        throws IOException
 26.1399 +    {
 26.1400 +        byte tc = bin.peekByte();
 26.1401 +        switch (tc) {
 26.1402 +            case TC_NULL:
 26.1403 +                return (ObjectStreamClass) readNull();
 26.1404 +
 26.1405 +            case TC_REFERENCE:
 26.1406 +                return (ObjectStreamClass) readHandle(unshared);
 26.1407 +
 26.1408 +            case TC_PROXYCLASSDESC:
 26.1409 +                return readProxyDesc(unshared);
 26.1410 +
 26.1411 +            case TC_CLASSDESC:
 26.1412 +                return readNonProxyDesc(unshared);
 26.1413 +
 26.1414 +            default:
 26.1415 +                throw new StreamCorruptedException(
 26.1416 +                    String.format("invalid type code: %02X", tc));
 26.1417 +        }
 26.1418 +    }
 26.1419 +
 26.1420 +    /**
 26.1421 +     * Reads in and returns class descriptor for a dynamic proxy class.  Sets
 26.1422 +     * passHandle to proxy class descriptor's assigned handle.  If proxy class
 26.1423 +     * descriptor cannot be resolved to a class in the local VM, a
 26.1424 +     * ClassNotFoundException is associated with the descriptor's handle.
 26.1425 +     */
 26.1426 +    private ObjectStreamClass readProxyDesc(boolean unshared)
 26.1427 +        throws IOException
 26.1428 +    {
 26.1429 +        if (bin.readByte() != TC_PROXYCLASSDESC) {
 26.1430 +            throw new InternalError();
 26.1431 +        }
 26.1432 +
 26.1433 +        ObjectStreamClass desc = new ObjectStreamClass();
 26.1434 +        int descHandle = handles.assign(unshared ? unsharedMarker : desc);
 26.1435 +        passHandle = NULL_HANDLE;
 26.1436 +
 26.1437 +        int numIfaces = bin.readInt();
 26.1438 +        String[] ifaces = new String[numIfaces];
 26.1439 +        for (int i = 0; i < numIfaces; i++) {
 26.1440 +            ifaces[i] = bin.readUTF();
 26.1441 +        }
 26.1442 +
 26.1443 +        Class cl = null;
 26.1444 +        ClassNotFoundException resolveEx = null;
 26.1445 +        bin.setBlockDataMode(true);
 26.1446 +        try {
 26.1447 +            if ((cl = resolveProxyClass(ifaces)) == null) {
 26.1448 +                resolveEx = new ClassNotFoundException("null class");
 26.1449 +            }
 26.1450 +        } catch (ClassNotFoundException ex) {
 26.1451 +            resolveEx = ex;
 26.1452 +        }
 26.1453 +        skipCustomData();
 26.1454 +
 26.1455 +        desc.initProxy(cl, resolveEx, readClassDesc(false));
 26.1456 +
 26.1457 +        handles.finish(descHandle);
 26.1458 +        passHandle = descHandle;
 26.1459 +        return desc;
 26.1460 +    }
 26.1461 +
 26.1462 +    /**
 26.1463 +     * Reads in and returns class descriptor for a class that is not a dynamic
 26.1464 +     * proxy class.  Sets passHandle to class descriptor's assigned handle.  If
 26.1465 +     * class descriptor cannot be resolved to a class in the local VM, a
 26.1466 +     * ClassNotFoundException is associated with the descriptor's handle.
 26.1467 +     */
 26.1468 +    private ObjectStreamClass readNonProxyDesc(boolean unshared)
 26.1469 +        throws IOException
 26.1470 +    {
 26.1471 +        if (bin.readByte() != TC_CLASSDESC) {
 26.1472 +            throw new InternalError();
 26.1473 +        }
 26.1474 +
 26.1475 +        ObjectStreamClass desc = new ObjectStreamClass();
 26.1476 +        int descHandle = handles.assign(unshared ? unsharedMarker : desc);
 26.1477 +        passHandle = NULL_HANDLE;
 26.1478 +
 26.1479 +        ObjectStreamClass readDesc = null;
 26.1480 +        try {
 26.1481 +            readDesc = readClassDescriptor();
 26.1482 +        } catch (ClassNotFoundException ex) {
 26.1483 +            throw (IOException) new InvalidClassException(
 26.1484 +                "failed to read class descriptor").initCause(ex);
 26.1485 +        }
 26.1486 +
 26.1487 +        Class cl = null;
 26.1488 +        ClassNotFoundException resolveEx = null;
 26.1489 +        bin.setBlockDataMode(true);
 26.1490 +        try {
 26.1491 +            if ((cl = resolveClass(readDesc)) == null) {
 26.1492 +                resolveEx = new ClassNotFoundException("null class");
 26.1493 +            }
 26.1494 +        } catch (ClassNotFoundException ex) {
 26.1495 +            resolveEx = ex;
 26.1496 +        }
 26.1497 +        skipCustomData();
 26.1498 +
 26.1499 +        desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));
 26.1500 +
 26.1501 +        handles.finish(descHandle);
 26.1502 +        passHandle = descHandle;
 26.1503 +        return desc;
 26.1504 +    }
 26.1505 +
 26.1506 +    /**
 26.1507 +     * Reads in and returns new string.  Sets passHandle to new string's
 26.1508 +     * assigned handle.
 26.1509 +     */
 26.1510 +    private String readString(boolean unshared) throws IOException {
 26.1511 +        String str;
 26.1512 +        byte tc = bin.readByte();
 26.1513 +        switch (tc) {
 26.1514 +            case TC_STRING:
 26.1515 +                str = bin.readUTF();
 26.1516 +                break;
 26.1517 +
 26.1518 +            case TC_LONGSTRING:
 26.1519 +                str = bin.readLongUTF();
 26.1520 +                break;
 26.1521 +
 26.1522 +            default:
 26.1523 +                throw new StreamCorruptedException(
 26.1524 +                    String.format("invalid type code: %02X", tc));
 26.1525 +        }
 26.1526 +        passHandle = handles.assign(unshared ? unsharedMarker : str);
 26.1527 +        handles.finish(passHandle);
 26.1528 +        return str;
 26.1529 +    }
 26.1530 +
 26.1531 +    /**
 26.1532 +     * Reads in and returns array object, or null if array class is
 26.1533 +     * unresolvable.  Sets passHandle to array's assigned handle.
 26.1534 +     */
 26.1535 +    private Object readArray(boolean unshared) throws IOException {
 26.1536 +        if (bin.readByte() != TC_ARRAY) {
 26.1537 +            throw new InternalError();
 26.1538 +        }
 26.1539 +
 26.1540 +        ObjectStreamClass desc = readClassDesc(false);
 26.1541 +        int len = bin.readInt();
 26.1542 +
 26.1543 +        Object array = null;
 26.1544 +        Class cl, ccl = null;
 26.1545 +        if ((cl = desc.forClass()) != null) {
 26.1546 +            ccl = cl.getComponentType();
 26.1547 +            array = Array.newInstance(ccl, len);
 26.1548 +        }
 26.1549 +
 26.1550 +        int arrayHandle = handles.assign(unshared ? unsharedMarker : array);
 26.1551 +        ClassNotFoundException resolveEx = desc.getResolveException();
 26.1552 +        if (resolveEx != null) {
 26.1553 +            handles.markException(arrayHandle, resolveEx);
 26.1554 +        }
 26.1555 +
 26.1556 +        if (ccl == null) {
 26.1557 +            for (int i = 0; i < len; i++) {
 26.1558 +                readObject0(false);
 26.1559 +            }
 26.1560 +        } else if (ccl.isPrimitive()) {
 26.1561 +            if (ccl == Integer.TYPE) {
 26.1562 +                bin.readInts((int[]) array, 0, len);
 26.1563 +            } else if (ccl == Byte.TYPE) {
 26.1564 +                bin.readFully((byte[]) array, 0, len, true);
 26.1565 +            } else if (ccl == Long.TYPE) {
 26.1566 +                bin.readLongs((long[]) array, 0, len);
 26.1567 +            } else if (ccl == Float.TYPE) {
 26.1568 +                bin.readFloats((float[]) array, 0, len);
 26.1569 +            } else if (ccl == Double.TYPE) {
 26.1570 +                bin.readDoubles((double[]) array, 0, len);
 26.1571 +            } else if (ccl == Short.TYPE) {
 26.1572 +                bin.readShorts((short[]) array, 0, len);
 26.1573 +            } else if (ccl == Character.TYPE) {
 26.1574 +                bin.readChars((char[]) array, 0, len);
 26.1575 +            } else if (ccl == Boolean.TYPE) {
 26.1576 +                bin.readBooleans((boolean[]) array, 0, len);
 26.1577 +            } else {
 26.1578 +                throw new InternalError();
 26.1579 +            }
 26.1580 +        } else {
 26.1581 +            Object[] oa = (Object[]) array;
 26.1582 +            for (int i = 0; i < len; i++) {
 26.1583 +                oa[i] = readObject0(false);
 26.1584 +                handles.markDependency(arrayHandle, passHandle);
 26.1585 +            }
 26.1586 +        }
 26.1587 +
 26.1588 +        handles.finish(arrayHandle);
 26.1589 +        passHandle = arrayHandle;
 26.1590 +        return array;
 26.1591 +    }
 26.1592 +
 26.1593 +    /**
 26.1594 +     * Reads in and returns enum constant, or null if enum type is
 26.1595 +     * unresolvable.  Sets passHandle to enum constant's assigned handle.
 26.1596 +     */
 26.1597 +    private Enum readEnum(boolean unshared) throws IOException {
 26.1598 +        if (bin.readByte() != TC_ENUM) {
 26.1599 +            throw new InternalError();
 26.1600 +        }
 26.1601 +
 26.1602 +        ObjectStreamClass desc = readClassDesc(false);
 26.1603 +        if (!desc.isEnum()) {
 26.1604 +            throw new InvalidClassException("non-enum class: " + desc);
 26.1605 +        }
 26.1606 +
 26.1607 +        int enumHandle = handles.assign(unshared ? unsharedMarker : null);
 26.1608 +        ClassNotFoundException resolveEx = desc.getResolveException();
 26.1609 +        if (resolveEx != null) {
 26.1610 +            handles.markException(enumHandle, resolveEx);
 26.1611 +        }
 26.1612 +
 26.1613 +        String name = readString(false);
 26.1614 +        Enum en = null;
 26.1615 +        Class cl = desc.forClass();
 26.1616 +        if (cl != null) {
 26.1617 +            try {
 26.1618 +                en = Enum.valueOf(cl, name);
 26.1619 +            } catch (IllegalArgumentException ex) {
 26.1620 +                throw (IOException) new InvalidObjectException(
 26.1621 +                    "enum constant " + name + " does not exist in " +
 26.1622 +                    cl).initCause(ex);
 26.1623 +            }
 26.1624 +            if (!unshared) {
 26.1625 +                handles.setObject(enumHandle, en);
 26.1626 +            }
 26.1627 +        }
 26.1628 +
 26.1629 +        handles.finish(enumHandle);
 26.1630 +        passHandle = enumHandle;
 26.1631 +        return en;
 26.1632 +    }
 26.1633 +
 26.1634 +    /**
 26.1635 +     * Reads and returns "ordinary" (i.e., not a String, Class,
 26.1636 +     * ObjectStreamClass, array, or enum constant) object, or null if object's
 26.1637 +     * class is unresolvable (in which case a ClassNotFoundException will be
 26.1638 +     * associated with object's handle).  Sets passHandle to object's assigned
 26.1639 +     * handle.
 26.1640 +     */
 26.1641 +    private Object readOrdinaryObject(boolean unshared)
 26.1642 +        throws IOException
 26.1643 +    {
 26.1644 +        if (bin.readByte() != TC_OBJECT) {
 26.1645 +            throw new InternalError();
 26.1646 +        }
 26.1647 +
 26.1648 +        ObjectStreamClass desc = readClassDesc(false);
 26.1649 +        desc.checkDeserialize();
 26.1650 +
 26.1651 +        Object obj;
 26.1652 +        try {
 26.1653 +            obj = desc.isInstantiable() ? desc.newInstance() : null;
 26.1654 +        } catch (Exception ex) {
 26.1655 +            throw (IOException) new InvalidClassException(
 26.1656 +                desc.forClass().getName(),
 26.1657 +                "unable to create instance").initCause(ex);
 26.1658 +        }
 26.1659 +
 26.1660 +        passHandle = handles.assign(unshared ? unsharedMarker : obj);
 26.1661 +        ClassNotFoundException resolveEx = desc.getResolveException();
 26.1662 +        if (resolveEx != null) {
 26.1663 +            handles.markException(passHandle, resolveEx);
 26.1664 +        }
 26.1665 +
 26.1666 +        if (desc.isExternalizable()) {
 26.1667 +            readExternalData((Externalizable) obj, desc);
 26.1668 +        } else {
 26.1669 +            readSerialData(obj, desc);
 26.1670 +        }
 26.1671 +
 26.1672 +        handles.finish(passHandle);
 26.1673 +
 26.1674 +        if (obj != null &&
 26.1675 +            handles.lookupException(passHandle) == null &&
 26.1676 +            desc.hasReadResolveMethod())
 26.1677 +        {
 26.1678 +            Object rep = desc.invokeReadResolve(obj);
 26.1679 +            if (unshared && rep.getClass().isArray()) {
 26.1680 +                rep = cloneArray(rep);
 26.1681 +            }
 26.1682 +            if (rep != obj) {
 26.1683 +                handles.setObject(passHandle, obj = rep);
 26.1684 +            }
 26.1685 +        }
 26.1686 +
 26.1687 +        return obj;
 26.1688 +    }
 26.1689 +
 26.1690 +    /**
 26.1691 +     * If obj is non-null, reads externalizable data by invoking readExternal()
 26.1692 +     * method of obj; otherwise, attempts to skip over externalizable data.
 26.1693 +     * Expects that passHandle is set to obj's handle before this method is
 26.1694 +     * called.
 26.1695 +     */
 26.1696 +    private void readExternalData(Externalizable obj, ObjectStreamClass desc)
 26.1697 +        throws IOException
 26.1698 +    {
 26.1699 +        Object oldContext = curContext;
 26.1700 +        curContext = null;
 26.1701 +        try {
 26.1702 +            boolean blocked = desc.hasBlockExternalData();
 26.1703 +            if (blocked) {
 26.1704 +                bin.setBlockDataMode(true);
 26.1705 +            }
 26.1706 +            if (obj != null) {
 26.1707 +                try {
 26.1708 +                    obj.readExternal(this);
 26.1709 +                } catch (ClassNotFoundException ex) {
 26.1710 +                    /*
 26.1711 +                     * In most cases, the handle table has already propagated
 26.1712 +                     * a CNFException to passHandle at this point; this mark
 26.1713 +                     * call is included to address cases where the readExternal
 26.1714 +                     * method has cons'ed and thrown a new CNFException of its
 26.1715 +                     * own.
 26.1716 +                     */
 26.1717 +                     handles.markException(passHandle, ex);
 26.1718 +                }
 26.1719 +            }
 26.1720 +            if (blocked) {
 26.1721 +                skipCustomData();
 26.1722 +            }
 26.1723 +        } finally {
 26.1724 +            curContext = oldContext;
 26.1725 +        }
 26.1726 +        /*
 26.1727 +         * At this point, if the externalizable data was not written in
 26.1728 +         * block-data form and either the externalizable class doesn't exist
 26.1729 +         * locally (i.e., obj == null) or readExternal() just threw a
 26.1730 +         * CNFException, then the stream is probably in an inconsistent state,
 26.1731 +         * since some (or all) of the externalizable data may not have been
 26.1732 +         * consumed.  Since there's no "correct" action to take in this case,
 26.1733 +         * we mimic the behavior of past serialization implementations and
 26.1734 +         * blindly hope that the stream is in sync; if it isn't and additional
 26.1735 +         * externalizable data remains in the stream, a subsequent read will
 26.1736 +         * most likely throw a StreamCorruptedException.
 26.1737 +         */
 26.1738 +    }
 26.1739 +
 26.1740 +    /**
 26.1741 +     * Reads (or attempts to skip, if obj is null or is tagged with a
 26.1742 +     * ClassNotFoundException) instance data for each serializable class of
 26.1743 +     * object in stream, from superclass to subclass.  Expects that passHandle
 26.1744 +     * is set to obj's handle before this method is called.
 26.1745 +     */
 26.1746 +    private void readSerialData(Object obj, ObjectStreamClass desc)
 26.1747 +        throws IOException
 26.1748 +    {
 26.1749 +        ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
 26.1750 +        for (int i = 0; i < slots.length; i++) {
 26.1751 +            ObjectStreamClass slotDesc = slots[i].desc;
 26.1752 +
 26.1753 +            if (slots[i].hasData) {
 26.1754 +                if (obj != null &&
 26.1755 +                    slotDesc.hasReadObjectMethod() &&
 26.1756 +                    handles.lookupException(passHandle) == null)
 26.1757 +                {
 26.1758 +                    Object oldContext = curContext;
 26.1759 +
 26.1760 +                    try {
 26.1761 +                        curContext = null; //new SerialCallbackContext(obj, slotDesc);
 26.1762 +
 26.1763 +                        bin.setBlockDataMode(true);
 26.1764 +                        slotDesc.invokeReadObject(obj, this);
 26.1765 +                    } catch (ClassNotFoundException ex) {
 26.1766 +                        /*
 26.1767 +                         * In most cases, the handle table has already
 26.1768 +                         * propagated a CNFException to passHandle at this
 26.1769 +                         * point; this mark call is included to address cases
 26.1770 +                         * where the custom readObject method has cons'ed and
 26.1771 +                         * thrown a new CNFException of its own.
 26.1772 +                         */
 26.1773 +                        handles.markException(passHandle, ex);
 26.1774 +                    } finally {
 26.1775 +                        //curContext.setUsed();
 26.1776 +                        curContext = oldContext;
 26.1777 +                    }
 26.1778 +
 26.1779 +                    /*
 26.1780 +                     * defaultDataEnd may have been set indirectly by custom
 26.1781 +                     * readObject() method when calling defaultReadObject() or
 26.1782 +                     * readFields(); clear it to restore normal read behavior.
 26.1783 +                     */
 26.1784 +                    defaultDataEnd = false;
 26.1785 +                } else {
 26.1786 +                    defaultReadFields(obj, slotDesc);
 26.1787 +                }
 26.1788 +                if (slotDesc.hasWriteObjectData()) {
 26.1789 +                    skipCustomData();
 26.1790 +                } else {
 26.1791 +                    bin.setBlockDataMode(false);
 26.1792 +                }
 26.1793 +            } else {
 26.1794 +                if (obj != null &&
 26.1795 +                    slotDesc.hasReadObjectNoDataMethod() &&
 26.1796 +                    handles.lookupException(passHandle) == null)
 26.1797 +                {
 26.1798 +                    slotDesc.invokeReadObjectNoData(obj);
 26.1799 +                }
 26.1800 +            }
 26.1801 +        }
 26.1802 +    }
 26.1803 +
 26.1804 +    /**
 26.1805 +     * Skips over all block data and objects until TC_ENDBLOCKDATA is
 26.1806 +     * encountered.
 26.1807 +     */
 26.1808 +    private void skipCustomData() throws IOException {
 26.1809 +        int oldHandle = passHandle;
 26.1810 +        for (;;) {
 26.1811 +            if (bin.getBlockDataMode()) {
 26.1812 +                bin.skipBlockData();
 26.1813 +                bin.setBlockDataMode(false);
 26.1814 +            }
 26.1815 +            switch (bin.peekByte()) {
 26.1816 +                case TC_BLOCKDATA:
 26.1817 +                case TC_BLOCKDATALONG:
 26.1818 +                    bin.setBlockDataMode(true);
 26.1819 +                    break;
 26.1820 +
 26.1821 +                case TC_ENDBLOCKDATA:
 26.1822 +                    bin.readByte();
 26.1823 +                    passHandle = oldHandle;
 26.1824 +                    return;
 26.1825 +
 26.1826 +                default:
 26.1827 +                    readObject0(false);
 26.1828 +                    break;
 26.1829 +            }
 26.1830 +        }
 26.1831 +    }
 26.1832 +
 26.1833 +    /**
 26.1834 +     * Reads in values of serializable fields declared by given class
 26.1835 +     * descriptor.  If obj is non-null, sets field values in obj.  Expects that
 26.1836 +     * passHandle is set to obj's handle before this method is called.
 26.1837 +     */
 26.1838 +    private void defaultReadFields(Object obj, ObjectStreamClass desc)
 26.1839 +        throws IOException
 26.1840 +    {
 26.1841 +        // REMIND: is isInstance check necessary?
 26.1842 +        Class cl = desc.forClass();
 26.1843 +        if (cl != null && obj != null && !cl.isInstance(obj)) {
 26.1844 +            throw new ClassCastException();
 26.1845 +        }
 26.1846 +
 26.1847 +        int primDataSize = desc.getPrimDataSize();
 26.1848 +        if (primVals == null || primVals.length < primDataSize) {
 26.1849 +            primVals = new byte[primDataSize];
 26.1850 +        }
 26.1851 +        bin.readFully(primVals, 0, primDataSize, false);
 26.1852 +        if (obj != null) {
 26.1853 +            desc.setPrimFieldValues(obj, primVals);
 26.1854 +        }
 26.1855 +
 26.1856 +        int objHandle = passHandle;
 26.1857 +        ObjectStreamField[] fields = desc.getFields(false);
 26.1858 +        Object[] objVals = new Object[desc.getNumObjFields()];
 26.1859 +        int numPrimFields = fields.length - objVals.length;
 26.1860 +        for (int i = 0; i < objVals.length; i++) {
 26.1861 +            ObjectStreamField f = fields[numPrimFields + i];
 26.1862 +            objVals[i] = readObject0(f.isUnshared());
 26.1863 +            if (f.getField() != null) {
 26.1864 +                handles.markDependency(objHandle, passHandle);
 26.1865 +            }
 26.1866 +        }
 26.1867 +        if (obj != null) {
 26.1868 +            desc.setObjFieldValues(obj, objVals);
 26.1869 +        }
 26.1870 +        passHandle = objHandle;
 26.1871 +    }
 26.1872 +
 26.1873 +    /**
 26.1874 +     * Reads in and returns IOException that caused serialization to abort.
 26.1875 +     * All stream state is discarded prior to reading in fatal exception.  Sets
 26.1876 +     * passHandle to fatal exception's handle.
 26.1877 +     */
 26.1878 +    private IOException readFatalException() throws IOException {
 26.1879 +        if (bin.readByte() != TC_EXCEPTION) {
 26.1880 +            throw new InternalError();
 26.1881 +        }
 26.1882 +        clear();
 26.1883 +        return (IOException) readObject0(false);
 26.1884 +    }
 26.1885 +
 26.1886 +    /**
 26.1887 +     * If recursion depth is 0, clears internal data structures; otherwise,
 26.1888 +     * throws a StreamCorruptedException.  This method is called when a
 26.1889 +     * TC_RESET typecode is encountered.
 26.1890 +     */
 26.1891 +    private void handleReset() throws StreamCorruptedException {
 26.1892 +        if (depth > 0) {
 26.1893 +            throw new StreamCorruptedException(
 26.1894 +                "unexpected reset; recursion depth: " + depth);
 26.1895 +        }
 26.1896 +        clear();
 26.1897 +    }
 26.1898 +
 26.1899 +    /**
 26.1900 +     * Converts specified span of bytes into float values.
 26.1901 +     */
 26.1902 +    // REMIND: remove once hotspot inlines Float.intBitsToFloat
 26.1903 +    private static native void bytesToFloats(byte[] src, int srcpos,
 26.1904 +                                             float[] dst, int dstpos,
 26.1905 +                                             int nfloats);
 26.1906 +
 26.1907 +    /**
 26.1908 +     * Converts specified span of bytes into double values.
 26.1909 +     */
 26.1910 +    // REMIND: remove once hotspot inlines Double.longBitsToDouble
 26.1911 +    private static native void bytesToDoubles(byte[] src, int srcpos,
 26.1912 +                                              double[] dst, int dstpos,
 26.1913 +                                              int ndoubles);
 26.1914 +
 26.1915 +    /**
 26.1916 +     * Returns the first non-null class loader (not counting class loaders of
 26.1917 +     * generated reflection implementation classes) up the execution stack, or
 26.1918 +     * null if only code from the null class loader is on the stack.  This
 26.1919 +     * method is also called via reflection by the following RMI-IIOP class:
 26.1920 +     *
 26.1921 +     *     com.sun.corba.se.internal.util.JDKClassLoader
 26.1922 +     *
 26.1923 +     * This method should not be removed or its signature changed without
 26.1924 +     * corresponding modifications to the above class.
 26.1925 +     */
 26.1926 +    // REMIND: change name to something more accurate?
 26.1927 +    private static native ClassLoader latestUserDefinedLoader();
 26.1928 +
 26.1929 +    /**
 26.1930 +     * Default GetField implementation.
 26.1931 +     */
 26.1932 +    private class GetFieldImpl extends GetField {
 26.1933 +
 26.1934 +        /** class descriptor describing serializable fields */
 26.1935 +        private final ObjectStreamClass desc;
 26.1936 +        /** primitive field values */
 26.1937 +        private final byte[] primVals;
 26.1938 +        /** object field values */
 26.1939 +        private final Object[] objVals;
 26.1940 +        /** object field value handles */
 26.1941 +        private final int[] objHandles;
 26.1942 +
 26.1943 +        /**
 26.1944 +         * Creates GetFieldImpl object for reading fields defined in given
 26.1945 +         * class descriptor.
 26.1946 +         */
 26.1947 +        GetFieldImpl(ObjectStreamClass desc) {
 26.1948 +            this.desc = desc;
 26.1949 +            primVals = new byte[desc.getPrimDataSize()];
 26.1950 +            objVals = new Object[desc.getNumObjFields()];
 26.1951 +            objHandles = new int[objVals.length];
 26.1952 +        }
 26.1953 +
 26.1954 +        public ObjectStreamClass getObjectStreamClass() {
 26.1955 +            return desc;
 26.1956 +        }
 26.1957 +
 26.1958 +        public boolean defaulted(String name) throws IOException {
 26.1959 +            return (getFieldOffset(name, null) < 0);
 26.1960 +        }
 26.1961 +
 26.1962 +        public boolean get(String name, boolean val) throws IOException {
 26.1963 +            int off = getFieldOffset(name, Boolean.TYPE);
 26.1964 +            return (off >= 0) ? Bits.getBoolean(primVals, off) : val;
 26.1965 +        }
 26.1966 +
 26.1967 +        public byte get(String name, byte val) throws IOException {
 26.1968 +            int off = getFieldOffset(name, Byte.TYPE);
 26.1969 +            return (off >= 0) ? primVals[off] : val;
 26.1970 +        }
 26.1971 +
 26.1972 +        public char get(String name, char val) throws IOException {
 26.1973 +            int off = getFieldOffset(name, Character.TYPE);
 26.1974 +            return (off >= 0) ? Bits.getChar(primVals, off) : val;
 26.1975 +        }
 26.1976 +
 26.1977 +        public short get(String name, short val) throws IOException {
 26.1978 +            int off = getFieldOffset(name, Short.TYPE);
 26.1979 +            return (off >= 0) ? Bits.getShort(primVals, off) : val;
 26.1980 +        }
 26.1981 +
 26.1982 +        public int get(String name, int val) throws IOException {
 26.1983 +            int off = getFieldOffset(name, Integer.TYPE);
 26.1984 +            return (off >= 0) ? Bits.getInt(primVals, off) : val;
 26.1985 +        }
 26.1986 +
 26.1987 +        public float get(String name, float val) throws IOException {
 26.1988 +            int off = getFieldOffset(name, Float.TYPE);
 26.1989 +            return (off >= 0) ? Bits.getFloat(primVals, off) : val;
 26.1990 +        }
 26.1991 +
 26.1992 +        public long get(String name, long val) throws IOException {
 26.1993 +            int off = getFieldOffset(name, Long.TYPE);
 26.1994 +            return (off >= 0) ? Bits.getLong(primVals, off) : val;
 26.1995 +        }
 26.1996 +
 26.1997 +        public double get(String name, double val) throws IOException {
 26.1998 +            int off = getFieldOffset(name, Double.TYPE);
 26.1999 +            return (off >= 0) ? Bits.getDouble(primVals, off) : val;
 26.2000 +        }
 26.2001 +
 26.2002 +        public Object get(String name, Object val) throws IOException {
 26.2003 +            int off = getFieldOffset(name, Object.class);
 26.2004 +            if (off >= 0) {
 26.2005 +                int objHandle = objHandles[off];
 26.2006 +                handles.markDependency(passHandle, objHandle);
 26.2007 +                return (handles.lookupException(objHandle) == null) ?
 26.2008 +                    objVals[off] : null;
 26.2009 +            } else {
 26.2010 +                return val;
 26.2011 +            }
 26.2012 +        }
 26.2013 +
 26.2014 +        /**
 26.2015 +         * Reads primitive and object field values from stream.
 26.2016 +         */
 26.2017 +        void readFields() throws IOException {
 26.2018 +            bin.readFully(primVals, 0, primVals.length, false);
 26.2019 +
 26.2020 +            int oldHandle = passHandle;
 26.2021 +            ObjectStreamField[] fields = desc.getFields(false);
 26.2022 +            int numPrimFields = fields.length - objVals.length;
 26.2023 +            for (int i = 0; i < objVals.length; i++) {
 26.2024 +                objVals[i] =
 26.2025 +                    readObject0(fields[numPrimFields + i].isUnshared());
 26.2026 +                objHandles[i] = passHandle;
 26.2027 +            }
 26.2028 +            passHandle = oldHandle;
 26.2029 +        }
 26.2030 +
 26.2031 +        /**
 26.2032 +         * Returns offset of field with given name and type.  A specified type
 26.2033 +         * of null matches all types, Object.class matches all non-primitive
 26.2034 +         * types, and any other non-null type matches assignable types only.
 26.2035 +         * If no matching field is found in the (incoming) class
 26.2036 +         * descriptor but a matching field is present in the associated local
 26.2037 +         * class descriptor, returns -1.  Throws IllegalArgumentException if
 26.2038 +         * neither incoming nor local class descriptor contains a match.
 26.2039 +         */
 26.2040 +        private int getFieldOffset(String name, Class type) {
 26.2041 +            ObjectStreamField field = desc.getField(name, type);
 26.2042 +            if (field != null) {
 26.2043 +                return field.getOffset();
 26.2044 +            } else if (desc.getLocalDesc().getField(name, type) != null) {
 26.2045 +                return -1;
 26.2046 +            } else {
 26.2047 +                throw new IllegalArgumentException("no such field " + name +
 26.2048 +                                                   " with type " + type);
 26.2049 +            }
 26.2050 +        }
 26.2051 +    }
 26.2052 +
 26.2053 +    /**
 26.2054 +     * Prioritized list of callbacks to be performed once object graph has been
 26.2055 +     * completely deserialized.
 26.2056 +     */
 26.2057 +    private static class ValidationList {
 26.2058 +
 26.2059 +
 26.2060 +        /**
 26.2061 +         * Creates new (empty) ValidationList.
 26.2062 +         */
 26.2063 +        ValidationList() {
 26.2064 +        }
 26.2065 +
 26.2066 +        /**
 26.2067 +         * Registers callback.  Throws InvalidObjectException if callback
 26.2068 +         * object is null.
 26.2069 +         */
 26.2070 +        void register(ObjectInputValidation obj, int priority)
 26.2071 +            throws InvalidObjectException
 26.2072 +        {
 26.2073 +            if (obj == null) {
 26.2074 +                throw new InvalidObjectException("null callback");
 26.2075 +            }
 26.2076 +            throw new InvalidObjectException("Does not work.");
 26.2077 +        }
 26.2078 +
 26.2079 +        /**
 26.2080 +         * Invokes all registered callbacks and clears the callback list.
 26.2081 +         * Callbacks with higher priorities are called first; those with equal
 26.2082 +         * priorities may be called in any order.  If any of the callbacks
 26.2083 +         * throws an InvalidObjectException, the callback process is terminated
 26.2084 +         * and the exception propagated upwards.
 26.2085 +         */
 26.2086 +        void doCallbacks() throws InvalidObjectException {
 26.2087 +        }
 26.2088 +
 26.2089 +        /**
 26.2090 +         * Resets the callback list to its initial (empty) state.
 26.2091 +         */
 26.2092 +        public void clear() {
 26.2093 +        }
 26.2094 +    }
 26.2095 +
 26.2096 +    /**
 26.2097 +     * Input stream supporting single-byte peek operations.
 26.2098 +     */
 26.2099 +    private static class PeekInputStream extends InputStream {
 26.2100 +
 26.2101 +        /** underlying stream */
 26.2102 +        private final InputStream in;
 26.2103 +        /** peeked byte */
 26.2104 +        private int peekb = -1;
 26.2105 +
 26.2106 +        /**
 26.2107 +         * Creates new PeekInputStream on top of given underlying stream.
 26.2108 +         */
 26.2109 +        PeekInputStream(InputStream in) {
 26.2110 +            this.in = in;
 26.2111 +        }
 26.2112 +
 26.2113 +        /**
 26.2114 +         * Peeks at next byte value in stream.  Similar to read(), except
 26.2115 +         * that it does not consume the read value.
 26.2116 +         */
 26.2117 +        int peek() throws IOException {
 26.2118 +            return (peekb >= 0) ? peekb : (peekb = in.read());
 26.2119 +        }
 26.2120 +
 26.2121 +        public int read() throws IOException {
 26.2122 +            if (peekb >= 0) {
 26.2123 +                int v = peekb;
 26.2124 +                peekb = -1;
 26.2125 +                return v;
 26.2126 +            } else {
 26.2127 +                return in.read();
 26.2128 +            }
 26.2129 +        }
 26.2130 +
 26.2131 +        public int read(byte[] b, int off, int len) throws IOException {
 26.2132 +            if (len == 0) {
 26.2133 +                return 0;
 26.2134 +            } else if (peekb < 0) {
 26.2135 +                return in.read(b, off, len);
 26.2136 +            } else {
 26.2137 +                b[off++] = (byte) peekb;
 26.2138 +                len--;
 26.2139 +                peekb = -1;
 26.2140 +                int n = in.read(b, off, len);
 26.2141 +                return (n >= 0) ? (n + 1) : 1;
 26.2142 +            }
 26.2143 +        }
 26.2144 +
 26.2145 +        void readFully(byte[] b, int off, int len) throws IOException {
 26.2146 +            int n = 0;
 26.2147 +            while (n < len) {
 26.2148 +                int count = read(b, off + n, len - n);
 26.2149 +                if (count < 0) {
 26.2150 +                    throw new EOFException();
 26.2151 +                }
 26.2152 +                n += count;
 26.2153 +            }
 26.2154 +        }
 26.2155 +
 26.2156 +        public long skip(long n) throws IOException {
 26.2157 +            if (n <= 0) {
 26.2158 +                return 0;
 26.2159 +            }
 26.2160 +            int skipped = 0;
 26.2161 +            if (peekb >= 0) {
 26.2162 +                peekb = -1;
 26.2163 +                skipped++;
 26.2164 +                n--;
 26.2165 +            }
 26.2166 +            return skipped + skip(n);
 26.2167 +        }
 26.2168 +
 26.2169 +        public int available() throws IOException {
 26.2170 +            return in.available() + ((peekb >= 0) ? 1 : 0);
 26.2171 +        }
 26.2172 +
 26.2173 +        public void close() throws IOException {
 26.2174 +            in.close();
 26.2175 +        }
 26.2176 +    }
 26.2177 +
 26.2178 +    /**
 26.2179 +     * Input stream with two modes: in default mode, inputs data written in the
 26.2180 +     * same format as DataOutputStream; in "block data" mode, inputs data
 26.2181 +     * bracketed by block data markers (see object serialization specification
 26.2182 +     * for details).  Buffering depends on block data mode: when in default
 26.2183 +     * mode, no data is buffered in advance; when in block data mode, all data
 26.2184 +     * for the current data block is read in at once (and buffered).
 26.2185 +     */
 26.2186 +    private class BlockDataInputStream
 26.2187 +        extends InputStream implements DataInput
 26.2188 +    {
 26.2189 +        /** maximum data block length */
 26.2190 +        private static final int MAX_BLOCK_SIZE = 1024;
 26.2191 +        /** maximum data block header length */
 26.2192 +        private static final int MAX_HEADER_SIZE = 5;
 26.2193 +        /** (tunable) length of char buffer (for reading strings) */
 26.2194 +        private static final int CHAR_BUF_SIZE = 256;
 26.2195 +        /** readBlockHeader() return value indicating header read may block */
 26.2196 +        private static final int HEADER_BLOCKED = -2;
 26.2197 +
 26.2198 +        /** buffer for reading general/block data */
 26.2199 +        private final byte[] buf = new byte[MAX_BLOCK_SIZE];
 26.2200 +        /** buffer for reading block data headers */
 26.2201 +        private final byte[] hbuf = new byte[MAX_HEADER_SIZE];
 26.2202 +        /** char buffer for fast string reads */
 26.2203 +        private final char[] cbuf = new char[CHAR_BUF_SIZE];
 26.2204 +
 26.2205 +        /** block data mode */
 26.2206 +        private boolean blkmode = false;
 26.2207 +
 26.2208 +        // block data state fields; values meaningful only when blkmode true
 26.2209 +        /** current offset into buf */
 26.2210 +        private int pos = 0;
 26.2211 +        /** end offset of valid data in buf, or -1 if no more block data */
 26.2212 +        private int end = -1;
 26.2213 +        /** number of bytes in current block yet to be read from stream */
 26.2214 +        private int unread = 0;
 26.2215 +
 26.2216 +        /** underlying stream (wrapped in peekable filter stream) */
 26.2217 +        private final PeekInputStream in;
 26.2218 +        /** loopback stream (for data reads that span data blocks) */
 26.2219 +        private final DataInputStream din;
 26.2220 +
 26.2221 +        /**
 26.2222 +         * Creates new BlockDataInputStream on top of given underlying stream.
 26.2223 +         * Block data mode is turned off by default.
 26.2224 +         */
 26.2225 +        BlockDataInputStream(InputStream in) {
 26.2226 +            this.in = new PeekInputStream(in);
 26.2227 +            din = new DataInputStream(this);
 26.2228 +        }
 26.2229 +
 26.2230 +        /**
 26.2231 +         * Sets block data mode to the given mode (true == on, false == off)
 26.2232 +         * and returns the previous mode value.  If the new mode is the same as
 26.2233 +         * the old mode, no action is taken.  Throws IllegalStateException if
 26.2234 +         * block data mode is being switched from on to off while unconsumed
 26.2235 +         * block data is still present in the stream.
 26.2236 +         */
 26.2237 +        boolean setBlockDataMode(boolean newmode) throws IOException {
 26.2238 +            if (blkmode == newmode) {
 26.2239 +                return blkmode;
 26.2240 +            }
 26.2241 +            if (newmode) {
 26.2242 +                pos = 0;
 26.2243 +                end = 0;
 26.2244 +                unread = 0;
 26.2245 +            } else if (pos < end) {
 26.2246 +                throw new IllegalStateException("unread block data");
 26.2247 +            }
 26.2248 +            blkmode = newmode;
 26.2249 +            return !blkmode;
 26.2250 +        }
 26.2251 +
 26.2252 +        /**
 26.2253 +         * Returns true if the stream is currently in block data mode, false
 26.2254 +         * otherwise.
 26.2255 +         */
 26.2256 +        boolean getBlockDataMode() {
 26.2257 +            return blkmode;
 26.2258 +        }
 26.2259 +
 26.2260 +        /**
 26.2261 +         * If in block data mode, skips to the end of the current group of data
 26.2262 +         * blocks (but does not unset block data mode).  If not in block data
 26.2263 +         * mode, throws an IllegalStateException.
 26.2264 +         */
 26.2265 +        void skipBlockData() throws IOException {
 26.2266 +            if (!blkmode) {
 26.2267 +                throw new IllegalStateException("not in block data mode");
 26.2268 +            }
 26.2269 +            while (end >= 0) {
 26.2270 +                refill();
 26.2271 +            }
 26.2272 +        }
 26.2273 +
 26.2274 +        /**
 26.2275 +         * Attempts to read in the next block data header (if any).  If
 26.2276 +         * canBlock is false and a full header cannot be read without possibly
 26.2277 +         * blocking, returns HEADER_BLOCKED, else if the next element in the
 26.2278 +         * stream is a block data header, returns the block data length
 26.2279 +         * specified by the header, else returns -1.
 26.2280 +         */
 26.2281 +        private int readBlockHeader(boolean canBlock) throws IOException {
 26.2282 +            if (defaultDataEnd) {
 26.2283 +                /*
 26.2284 +                 * Fix for 4360508: stream is currently at the end of a field
 26.2285 +                 * value block written via default serialization; since there
 26.2286 +                 * is no terminating TC_ENDBLOCKDATA tag, simulate
 26.2287 +                 * end-of-custom-data behavior explicitly.
 26.2288 +                 */
 26.2289 +                return -1;
 26.2290 +            }
 26.2291 +            try {
 26.2292 +                for (;;) {
 26.2293 +                    int avail = canBlock ? Integer.MAX_VALUE : in.available();
 26.2294 +                    if (avail == 0) {
 26.2295 +                        return HEADER_BLOCKED;
 26.2296 +                    }
 26.2297 +
 26.2298 +                    int tc = in.peek();
 26.2299 +                    switch (tc) {
 26.2300 +                        case TC_BLOCKDATA:
 26.2301 +                            if (avail < 2) {
 26.2302 +                                return HEADER_BLOCKED;
 26.2303 +                            }
 26.2304 +                            in.readFully(hbuf, 0, 2);
 26.2305 +                            return hbuf[1] & 0xFF;
 26.2306 +
 26.2307 +                        case TC_BLOCKDATALONG:
 26.2308 +                            if (avail < 5) {
 26.2309 +                                return HEADER_BLOCKED;
 26.2310 +                            }
 26.2311 +                            in.readFully(hbuf, 0, 5);
 26.2312 +                            int len = Bits.getInt(hbuf, 1);
 26.2313 +                            if (len < 0) {
 26.2314 +                                throw new StreamCorruptedException(
 26.2315 +                                    "illegal block data header length: " +
 26.2316 +                                    len);
 26.2317 +                            }
 26.2318 +                            return len;
 26.2319 +
 26.2320 +                        /*
 26.2321 +                         * TC_RESETs may occur in between data blocks.
 26.2322 +                         * Unfortunately, this case must be parsed at a lower
 26.2323 +                         * level than other typecodes, since primitive data
 26.2324 +                         * reads may span data blocks separated by a TC_RESET.
 26.2325 +                         */
 26.2326 +                        case TC_RESET:
 26.2327 +                            in.read();
 26.2328 +                            handleReset();
 26.2329 +                            break;
 26.2330 +
 26.2331 +                        default:
 26.2332 +                            if (tc >= 0 && (tc < TC_BASE || tc > TC_MAX)) {
 26.2333 +                                throw new StreamCorruptedException(
 26.2334 +                                    String.format("invalid type code: %02X",
 26.2335 +                                    tc));
 26.2336 +                            }
 26.2337 +                            return -1;
 26.2338 +                    }
 26.2339 +                }
 26.2340 +            } catch (EOFException ex) {
 26.2341 +                throw new StreamCorruptedException(
 26.2342 +                    "unexpected EOF while reading block data header");
 26.2343 +            }
 26.2344 +        }
 26.2345 +
 26.2346 +        /**
 26.2347 +         * Refills internal buffer buf with block data.  Any data in buf at the
 26.2348 +         * time of the call is considered consumed.  Sets the pos, end, and
 26.2349 +         * unread fields to reflect the new amount of available block data; if
 26.2350 +         * the next element in the stream is not a data block, sets pos and
 26.2351 +         * unread to 0 and end to -1.
 26.2352 +         */
 26.2353 +        private void refill() throws IOException {
 26.2354 +            try {
 26.2355 +                do {
 26.2356 +                    pos = 0;
 26.2357 +                    if (unread > 0) {
 26.2358 +                        int n =
 26.2359 +                            in.read(buf, 0, Math.min(unread, MAX_BLOCK_SIZE));
 26.2360 +                        if (n >= 0) {
 26.2361 +                            end = n;
 26.2362 +                            unread -= n;
 26.2363 +                        } else {
 26.2364 +                            throw new StreamCorruptedException(
 26.2365 +                                "unexpected EOF in middle of data block");
 26.2366 +                        }
 26.2367 +                    } else {
 26.2368 +                        int n = readBlockHeader(true);
 26.2369 +                        if (n >= 0) {
 26.2370 +                            end = 0;
 26.2371 +                            unread = n;
 26.2372 +                        } else {
 26.2373 +                            end = -1;
 26.2374 +                            unread = 0;
 26.2375 +                        }
 26.2376 +                    }
 26.2377 +                } while (pos == end);
 26.2378 +            } catch (IOException ex) {
 26.2379 +                pos = 0;
 26.2380 +                end = -1;
 26.2381 +                unread = 0;
 26.2382 +                throw ex;
 26.2383 +            }
 26.2384 +        }
 26.2385 +
 26.2386 +        /**
 26.2387 +         * If in block data mode, returns the number of unconsumed bytes
 26.2388 +         * remaining in the current data block.  If not in block data mode,
 26.2389 +         * throws an IllegalStateException.
 26.2390 +         */
 26.2391 +        int currentBlockRemaining() {
 26.2392 +            if (blkmode) {
 26.2393 +                return (end >= 0) ? (end - pos) + unread : 0;
 26.2394 +            } else {
 26.2395 +                throw new IllegalStateException();
 26.2396 +            }
 26.2397 +        }
 26.2398 +
 26.2399 +        /**
 26.2400 +         * Peeks at (but does not consume) and returns the next byte value in
 26.2401 +         * the stream, or -1 if the end of the stream/block data (if in block
 26.2402 +         * data mode) has been reached.
 26.2403 +         */
 26.2404 +        int peek() throws IOException {
 26.2405 +            if (blkmode) {
 26.2406 +                if (pos == end) {
 26.2407 +                    refill();
 26.2408 +                }
 26.2409 +                return (end >= 0) ? (buf[pos] & 0xFF) : -1;
 26.2410 +            } else {
 26.2411 +                return in.peek();
 26.2412 +            }
 26.2413 +        }
 26.2414 +
 26.2415 +        /**
 26.2416 +         * Peeks at (but does not consume) and returns the next byte value in
 26.2417 +         * the stream, or throws EOFException if end of stream/block data has
 26.2418 +         * been reached.
 26.2419 +         */
 26.2420 +        byte peekByte() throws IOException {
 26.2421 +            int val = peek();
 26.2422 +            if (val < 0) {
 26.2423 +                throw new EOFException();
 26.2424 +            }
 26.2425 +            return (byte) val;
 26.2426 +        }
 26.2427 +
 26.2428 +
 26.2429 +        /* ----------------- generic input stream methods ------------------ */
 26.2430 +        /*
 26.2431 +         * The following methods are equivalent to their counterparts in
 26.2432 +         * InputStream, except that they interpret data block boundaries and
 26.2433 +         * read the requested data from within data blocks when in block data
 26.2434 +         * mode.
 26.2435 +         */
 26.2436 +
 26.2437 +        public int read() throws IOException {
 26.2438 +            if (blkmode) {
 26.2439 +                if (pos == end) {
 26.2440 +                    refill();
 26.2441 +                }
 26.2442 +                return (end >= 0) ? (buf[pos++] & 0xFF) : -1;
 26.2443 +            } else {
 26.2444 +                return in.read();
 26.2445 +            }
 26.2446 +        }
 26.2447 +
 26.2448 +        public int read(byte[] b, int off, int len) throws IOException {
 26.2449 +            return read(b, off, len, false);
 26.2450 +        }
 26.2451 +
 26.2452 +        public long skip(long len) throws IOException {
 26.2453 +            long remain = len;
 26.2454 +            while (remain > 0) {
 26.2455 +                if (blkmode) {
 26.2456 +                    if (pos == end) {
 26.2457 +                        refill();
 26.2458 +                    }
 26.2459 +                    if (end < 0) {
 26.2460 +                        break;
 26.2461 +                    }
 26.2462 +                    int nread = (int) Math.min(remain, end - pos);
 26.2463 +                    remain -= nread;
 26.2464 +                    pos += nread;
 26.2465 +                } else {
 26.2466 +                    int nread = (int) Math.min(remain, MAX_BLOCK_SIZE);
 26.2467 +                    if ((nread = in.read(buf, 0, nread)) < 0) {
 26.2468 +                        break;
 26.2469 +                    }
 26.2470 +                    remain -= nread;
 26.2471 +                }
 26.2472 +            }
 26.2473 +            return len - remain;
 26.2474 +        }
 26.2475 +
 26.2476 +        public int available() throws IOException {
 26.2477 +            if (blkmode) {
 26.2478 +                if ((pos == end) && (unread == 0)) {
 26.2479 +                    int n;
 26.2480 +                    while ((n = readBlockHeader(false)) == 0) ;
 26.2481 +                    switch (n) {
 26.2482 +                        case HEADER_BLOCKED:
 26.2483 +                            break;
 26.2484 +
 26.2485 +                        case -1:
 26.2486 +                            pos = 0;
 26.2487 +                            end = -1;
 26.2488 +                            break;
 26.2489 +
 26.2490 +                        default:
 26.2491 +                            pos = 0;
 26.2492 +                            end = 0;
 26.2493 +                            unread = n;
 26.2494 +                            break;
 26.2495 +                    }
 26.2496 +                }
 26.2497 +                // avoid unnecessary call to in.available() if possible
 26.2498 +                int unreadAvail = (unread > 0) ?
 26.2499 +                    Math.min(in.available(), unread) : 0;
 26.2500 +                return (end >= 0) ? (end - pos) + unreadAvail : 0;
 26.2501 +            } else {
 26.2502 +                return in.available();
 26.2503 +            }
 26.2504 +        }
 26.2505 +
 26.2506 +        public void close() throws IOException {
 26.2507 +            if (blkmode) {
 26.2508 +                pos = 0;
 26.2509 +                end = -1;
 26.2510 +                unread = 0;
 26.2511 +            }
 26.2512 +            in.close();
 26.2513 +        }
 26.2514 +
 26.2515 +        /**
 26.2516 +         * Attempts to read len bytes into byte array b at offset off.  Returns
 26.2517 +         * the number of bytes read, or -1 if the end of stream/block data has
 26.2518 +         * been reached.  If copy is true, reads values into an intermediate
 26.2519 +         * buffer before copying them to b (to avoid exposing a reference to
 26.2520 +         * b).
 26.2521 +         */
 26.2522 +        int read(byte[] b, int off, int len, boolean copy) throws IOException {
 26.2523 +            if (len == 0) {
 26.2524 +                return 0;
 26.2525 +            } else if (blkmode) {
 26.2526 +                if (pos == end) {
 26.2527 +                    refill();
 26.2528 +                }
 26.2529 +                if (end < 0) {
 26.2530 +                    return -1;
 26.2531 +                }
 26.2532 +                int nread = Math.min(len, end - pos);
 26.2533 +                System.arraycopy(buf, pos, b, off, nread);
 26.2534 +                pos += nread;
 26.2535 +                return nread;
 26.2536 +            } else if (copy) {
 26.2537 +                int nread = in.read(buf, 0, Math.min(len, MAX_BLOCK_SIZE));
 26.2538 +                if (nread > 0) {
 26.2539 +                    System.arraycopy(buf, 0, b, off, nread);
 26.2540 +                }
 26.2541 +                return nread;
 26.2542 +            } else {
 26.2543 +                return in.read(b, off, len);
 26.2544 +            }
 26.2545 +        }
 26.2546 +
 26.2547 +        /* ----------------- primitive data input methods ------------------ */
 26.2548 +        /*
 26.2549 +         * The following methods are equivalent to their counterparts in
 26.2550 +         * DataInputStream, except that they interpret data block boundaries
 26.2551 +         * and read the requested data from within data blocks when in block
 26.2552 +         * data mode.
 26.2553 +         */
 26.2554 +
 26.2555 +        public void readFully(byte[] b) throws IOException {
 26.2556 +            readFully(b, 0, b.length, false);
 26.2557 +        }
 26.2558 +
 26.2559 +        public void readFully(byte[] b, int off, int len) throws IOException {
 26.2560 +            readFully(b, off, len, false);
 26.2561 +        }
 26.2562 +
 26.2563 +        public void readFully(byte[] b, int off, int len, boolean copy)
 26.2564 +            throws IOException
 26.2565 +        {
 26.2566 +            while (len > 0) {
 26.2567 +                int n = read(b, off, len, copy);
 26.2568 +                if (n < 0) {
 26.2569 +                    throw new EOFException();
 26.2570 +                }
 26.2571 +                off += n;
 26.2572 +                len -= n;
 26.2573 +            }
 26.2574 +        }
 26.2575 +
 26.2576 +        public int skipBytes(int n) throws IOException {
 26.2577 +            return din.skipBytes(n);
 26.2578 +        }
 26.2579 +
 26.2580 +        public boolean readBoolean() throws IOException {
 26.2581 +            int v = read();
 26.2582 +            if (v < 0) {
 26.2583 +                throw new EOFException();
 26.2584 +            }
 26.2585 +            return (v != 0);
 26.2586 +        }
 26.2587 +
 26.2588 +        public byte readByte() throws IOException {
 26.2589 +            int v = read();
 26.2590 +            if (v < 0) {
 26.2591 +                throw new EOFException();
 26.2592 +            }
 26.2593 +            return (byte) v;
 26.2594 +        }
 26.2595 +
 26.2596 +        public int readUnsignedByte() throws IOException {
 26.2597 +            int v = read();
 26.2598 +            if (v < 0) {
 26.2599 +                throw new EOFException();
 26.2600 +            }
 26.2601 +            return v;
 26.2602 +        }
 26.2603 +
 26.2604 +        public char readChar() throws IOException {
 26.2605 +            if (!blkmode) {
 26.2606 +                pos = 0;
 26.2607 +                in.readFully(buf, 0, 2);
 26.2608 +            } else if (end - pos < 2) {
 26.2609 +                return din.readChar();
 26.2610 +            }
 26.2611 +            char v = Bits.getChar(buf, pos);
 26.2612 +            pos += 2;
 26.2613 +            return v;
 26.2614 +        }
 26.2615 +
 26.2616 +        public short readShort() throws IOException {
 26.2617 +            if (!blkmode) {
 26.2618 +                pos = 0;
 26.2619 +                in.readFully(buf, 0, 2);
 26.2620 +            } else if (end - pos < 2) {
 26.2621 +                return din.readShort();
 26.2622 +            }
 26.2623 +            short v = Bits.getShort(buf, pos);
 26.2624 +            pos += 2;
 26.2625 +            return v;
 26.2626 +        }
 26.2627 +
 26.2628 +        public int readUnsignedShort() throws IOException {
 26.2629 +            if (!blkmode) {
 26.2630 +                pos = 0;
 26.2631 +                in.readFully(buf, 0, 2);
 26.2632 +            } else if (end - pos < 2) {
 26.2633 +                return din.readUnsignedShort();
 26.2634 +            }
 26.2635 +            int v = Bits.getShort(buf, pos) & 0xFFFF;
 26.2636 +            pos += 2;
 26.2637 +            return v;
 26.2638 +        }
 26.2639 +
 26.2640 +        public int readInt() throws IOException {
 26.2641 +            if (!blkmode) {
 26.2642 +                pos = 0;
 26.2643 +                in.readFully(buf, 0, 4);
 26.2644 +            } else if (end - pos < 4) {
 26.2645 +                return din.readInt();
 26.2646 +            }
 26.2647 +            int v = Bits.getInt(buf, pos);
 26.2648 +            pos += 4;
 26.2649 +            return v;
 26.2650 +        }
 26.2651 +
 26.2652 +        public float readFloat() throws IOException {
 26.2653 +            if (!blkmode) {
 26.2654 +                pos = 0;
 26.2655 +                in.readFully(buf, 0, 4);
 26.2656 +            } else if (end - pos < 4) {
 26.2657 +                return din.readFloat();
 26.2658 +            }
 26.2659 +            float v = Bits.getFloat(buf, pos);
 26.2660 +            pos += 4;
 26.2661 +            return v;
 26.2662 +        }
 26.2663 +
 26.2664 +        public long readLong() throws IOException {
 26.2665 +            if (!blkmode) {
 26.2666 +                pos = 0;
 26.2667 +                in.readFully(buf, 0, 8);
 26.2668 +            } else if (end - pos < 8) {
 26.2669 +                return din.readLong();
 26.2670 +            }
 26.2671 +            long v = Bits.getLong(buf, pos);
 26.2672 +            pos += 8;
 26.2673 +            return v;
 26.2674 +        }
 26.2675 +
 26.2676 +        public double readDouble() throws IOException {
 26.2677 +            if (!blkmode) {
 26.2678 +                pos = 0;
 26.2679 +                in.readFully(buf, 0, 8);
 26.2680 +            } else if (end - pos < 8) {
 26.2681 +                return din.readDouble();
 26.2682 +            }
 26.2683 +            double v = Bits.getDouble(buf, pos);
 26.2684 +            pos += 8;
 26.2685 +            return v;
 26.2686 +        }
 26.2687 +
 26.2688 +        public String readUTF() throws IOException {
 26.2689 +            return readUTFBody(readUnsignedShort());
 26.2690 +        }
 26.2691 +
 26.2692 +        public String readLine() throws IOException {
 26.2693 +            return din.readLine();      // deprecated, not worth optimizing
 26.2694 +        }
 26.2695 +
 26.2696 +        /* -------------- primitive data array input methods --------------- */
 26.2697 +        /*
 26.2698 +         * The following methods read in spans of primitive data values.
 26.2699 +         * Though equivalent to calling the corresponding primitive read
 26.2700 +         * methods repeatedly, these methods are optimized for reading groups
 26.2701 +         * of primitive data values more efficiently.
 26.2702 +         */
 26.2703 +
 26.2704 +        void readBooleans(boolean[] v, int off, int len) throws IOException {
 26.2705 +            int stop, endoff = off + len;
 26.2706 +            while (off < endoff) {
 26.2707 +                if (!blkmode) {
 26.2708 +                    int span = Math.min(endoff - off, MAX_BLOCK_SIZE);
 26.2709 +                    in.readFully(buf, 0, span);
 26.2710 +                    stop = off + span;
 26.2711 +                    pos = 0;
 26.2712 +                } else if (end - pos < 1) {
 26.2713 +                    v[off++] = din.readBoolean();
 26.2714 +                    continue;
 26.2715 +                } else {
 26.2716 +                    stop = Math.min(endoff, off + end - pos);
 26.2717 +                }
 26.2718 +
 26.2719 +                while (off < stop) {
 26.2720 +                    v[off++] = Bits.getBoolean(buf, pos++);
 26.2721 +                }
 26.2722 +            }
 26.2723 +        }
 26.2724 +
 26.2725 +        void readChars(char[] v, int off, int len) throws IOException {
 26.2726 +            int stop, endoff = off + len;
 26.2727 +            while (off < endoff) {
 26.2728 +                if (!blkmode) {
 26.2729 +                    int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1);
 26.2730 +                    in.readFully(buf, 0, span << 1);
 26.2731 +                    stop = off + span;
 26.2732 +                    pos = 0;
 26.2733 +                } else if (end - pos < 2) {
 26.2734 +                    v[off++] = din.readChar();
 26.2735 +                    continue;
 26.2736 +                } else {
 26.2737 +                    stop = Math.min(endoff, off + ((end - pos) >> 1));
 26.2738 +                }
 26.2739 +
 26.2740 +                while (off < stop) {
 26.2741 +                    v[off++] = Bits.getChar(buf, pos);
 26.2742 +                    pos += 2;
 26.2743 +                }
 26.2744 +            }
 26.2745 +        }
 26.2746 +
 26.2747 +        void readShorts(short[] v, int off, int len) throws IOException {
 26.2748 +            int stop, endoff = off + len;
 26.2749 +            while (off < endoff) {
 26.2750 +                if (!blkmode) {
 26.2751 +                    int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1);
 26.2752 +                    in.readFully(buf, 0, span << 1);
 26.2753 +                    stop = off + span;
 26.2754 +                    pos = 0;
 26.2755 +                } else if (end - pos < 2) {
 26.2756 +                    v[off++] = din.readShort();
 26.2757 +                    continue;
 26.2758 +                } else {
 26.2759 +                    stop = Math.min(endoff, off + ((end - pos) >> 1));
 26.2760 +                }
 26.2761 +
 26.2762 +                while (off < stop) {
 26.2763 +                    v[off++] = Bits.getShort(buf, pos);
 26.2764 +                    pos += 2;
 26.2765 +                }
 26.2766 +            }
 26.2767 +        }
 26.2768 +
 26.2769 +        void readInts(int[] v, int off, int len) throws IOException {
 26.2770 +            int stop, endoff = off + len;
 26.2771 +            while (off < endoff) {
 26.2772 +                if (!blkmode) {
 26.2773 +                    int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2);
 26.2774 +                    in.readFully(buf, 0, span << 2);
 26.2775 +                    stop = off + span;
 26.2776 +                    pos = 0;
 26.2777 +                } else if (end - pos < 4) {
 26.2778 +                    v[off++] = din.readInt();
 26.2779 +                    continue;
 26.2780 +                } else {
 26.2781 +                    stop = Math.min(endoff, off + ((end - pos) >> 2));
 26.2782 +                }
 26.2783 +
 26.2784 +                while (off < stop) {
 26.2785 +                    v[off++] = Bits.getInt(buf, pos);
 26.2786 +                    pos += 4;
 26.2787 +                }
 26.2788 +            }
 26.2789 +        }
 26.2790 +
 26.2791 +        void readFloats(float[] v, int off, int len) throws IOException {
 26.2792 +            int span, endoff = off + len;
 26.2793 +            while (off < endoff) {
 26.2794 +                if (!blkmode) {
 26.2795 +                    span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2);
 26.2796 +                    in.readFully(buf, 0, span << 2);
 26.2797 +                    pos = 0;
 26.2798 +                } else if (end - pos < 4) {
 26.2799 +                    v[off++] = din.readFloat();
 26.2800 +                    continue;
 26.2801 +                } else {
 26.2802 +                    span = Math.min(endoff - off, ((end - pos) >> 2));
 26.2803 +                }
 26.2804 +
 26.2805 +                bytesToFloats(buf, pos, v, off, span);
 26.2806 +                off += span;
 26.2807 +                pos += span << 2;
 26.2808 +            }
 26.2809 +        }
 26.2810 +
 26.2811 +        void readLongs(long[] v, int off, int len) throws IOException {
 26.2812 +            int stop, endoff = off + len;
 26.2813 +            while (off < endoff) {
 26.2814 +                if (!blkmode) {
 26.2815 +                    int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3);
 26.2816 +                    in.readFully(buf, 0, span << 3);
 26.2817 +                    stop = off + span;
 26.2818 +                    pos = 0;
 26.2819 +                } else if (end - pos < 8) {
 26.2820 +                    v[off++] = din.readLong();
 26.2821 +                    continue;
 26.2822 +                } else {
 26.2823 +                    stop = Math.min(endoff, off + ((end - pos) >> 3));
 26.2824 +                }
 26.2825 +
 26.2826 +                while (off < stop) {
 26.2827 +                    v[off++] = Bits.getLong(buf, pos);
 26.2828 +                    pos += 8;
 26.2829 +                }
 26.2830 +            }
 26.2831 +        }
 26.2832 +
 26.2833 +        void readDoubles(double[] v, int off, int len) throws IOException {
 26.2834 +            int span, endoff = off + len;
 26.2835 +            while (off < endoff) {
 26.2836 +                if (!blkmode) {
 26.2837 +                    span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3);
 26.2838 +                    in.readFully(buf, 0, span << 3);
 26.2839 +                    pos = 0;
 26.2840 +                } else if (end - pos < 8) {
 26.2841 +                    v[off++] = din.readDouble();
 26.2842 +                    continue;
 26.2843 +                } else {
 26.2844 +                    span = Math.min(endoff - off, ((end - pos) >> 3));
 26.2845 +                }
 26.2846 +
 26.2847 +                bytesToDoubles(buf, pos, v, off, span);
 26.2848 +                off += span;
 26.2849 +                pos += span << 3;
 26.2850 +            }
 26.2851 +        }
 26.2852 +
 26.2853 +        /**
 26.2854 +         * Reads in string written in "long" UTF format.  "Long" UTF format is
 26.2855 +         * identical to standard UTF, except that it uses an 8 byte header
 26.2856 +         * (instead of the standard 2 bytes) to convey the UTF encoding length.
 26.2857 +         */
 26.2858 +        String readLongUTF() throws IOException {
 26.2859 +            return readUTFBody(readLong());
 26.2860 +        }
 26.2861 +
 26.2862 +        /**
 26.2863 +         * Reads in the "body" (i.e., the UTF representation minus the 2-byte
 26.2864 +         * or 8-byte length header) of a UTF encoding, which occupies the next
 26.2865 +         * utflen bytes.
 26.2866 +         */
 26.2867 +        private String readUTFBody(long utflen) throws IOException {
 26.2868 +            StringBuilder sbuf = new StringBuilder();
 26.2869 +            if (!blkmode) {
 26.2870 +                end = pos = 0;
 26.2871 +            }
 26.2872 +
 26.2873 +            while (utflen > 0) {
 26.2874 +                int avail = end - pos;
 26.2875 +                if (avail >= 3 || (long) avail == utflen) {
 26.2876 +                    utflen -= readUTFSpan(sbuf, utflen);
 26.2877 +                } else {
 26.2878 +                    if (blkmode) {
 26.2879 +                        // near block boundary, read one byte at a time
 26.2880 +                        utflen -= readUTFChar(sbuf, utflen);
 26.2881 +                    } else {
 26.2882 +                        // shift and refill buffer manually
 26.2883 +                        if (avail > 0) {
 26.2884 +                            System.arraycopy(buf, pos, buf, 0, avail);
 26.2885 +                        }
 26.2886 +                        pos = 0;
 26.2887 +                        end = (int) Math.min(MAX_BLOCK_SIZE, utflen);
 26.2888 +                        in.readFully(buf, avail, end - avail);
 26.2889 +                    }
 26.2890 +                }
 26.2891 +            }
 26.2892 +
 26.2893 +            return sbuf.toString();
 26.2894 +        }
 26.2895 +
 26.2896 +        /**
 26.2897 +         * Reads span of UTF-encoded characters out of internal buffer
 26.2898 +         * (starting at offset pos and ending at or before offset end),
 26.2899 +         * consuming no more than utflen bytes.  Appends read characters to
 26.2900 +         * sbuf.  Returns the number of bytes consumed.
 26.2901 +         */
 26.2902 +        private long readUTFSpan(StringBuilder sbuf, long utflen)
 26.2903 +            throws IOException
 26.2904 +        {
 26.2905 +            int cpos = 0;
 26.2906 +            int start = pos;
 26.2907 +            int avail = Math.min(end - pos, CHAR_BUF_SIZE);
 26.2908 +            // stop short of last char unless all of utf bytes in buffer
 26.2909 +            int stop = pos + ((utflen > avail) ? avail - 2 : (int) utflen);
 26.2910 +            boolean outOfBounds = false;
 26.2911 +
 26.2912 +            try {
 26.2913 +                while (pos < stop) {
 26.2914 +                    int b1, b2, b3;
 26.2915 +                    b1 = buf[pos++] & 0xFF;
 26.2916 +                    switch (b1 >> 4) {
 26.2917 +                        case 0:
 26.2918 +                        case 1:
 26.2919 +                        case 2:
 26.2920 +                        case 3:
 26.2921 +                        case 4:
 26.2922 +                        case 5:
 26.2923 +                        case 6:
 26.2924 +                        case 7:   // 1 byte format: 0xxxxxxx
 26.2925 +                            cbuf[cpos++] = (char) b1;
 26.2926 +                            break;
 26.2927 +
 26.2928 +                        case 12:
 26.2929 +                        case 13:  // 2 byte format: 110xxxxx 10xxxxxx
 26.2930 +                            b2 = buf[pos++];
 26.2931 +                            if ((b2 & 0xC0) != 0x80) {
 26.2932 +                                throw new UTFDataFormatException();
 26.2933 +                            }
 26.2934 +                            cbuf[cpos++] = (char) (((b1 & 0x1F) << 6) |
 26.2935 +                                                   ((b2 & 0x3F) << 0));
 26.2936 +                            break;
 26.2937 +
 26.2938 +                        case 14:  // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx
 26.2939 +                            b3 = buf[pos + 1];
 26.2940 +                            b2 = buf[pos + 0];
 26.2941 +                            pos += 2;
 26.2942 +                            if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) {
 26.2943 +                                throw new UTFDataFormatException();
 26.2944 +                            }
 26.2945 +                            cbuf[cpos++] = (char) (((b1 & 0x0F) << 12) |
 26.2946 +                                                   ((b2 & 0x3F) << 6) |
 26.2947 +                                                   ((b3 & 0x3F) << 0));
 26.2948 +                            break;
 26.2949 +
 26.2950 +                        default:  // 10xx xxxx, 1111 xxxx
 26.2951 +                            throw new UTFDataFormatException();
 26.2952 +                    }
 26.2953 +                }
 26.2954 +            } catch (ArrayIndexOutOfBoundsException ex) {
 26.2955 +                outOfBounds = true;
 26.2956 +            } finally {
 26.2957 +                if (outOfBounds || (pos - start) > utflen) {
 26.2958 +                    /*
 26.2959 +                     * Fix for 4450867: if a malformed utf char causes the
 26.2960 +                     * conversion loop to scan past the expected end of the utf
 26.2961 +                     * string, only consume the expected number of utf bytes.
 26.2962 +                     */
 26.2963 +                    pos = start + (int) utflen;
 26.2964 +                    throw new UTFDataFormatException();
 26.2965 +                }
 26.2966 +            }
 26.2967 +
 26.2968 +            sbuf.append(cbuf, 0, cpos);
 26.2969 +            return pos - start;
 26.2970 +        }
 26.2971 +
 26.2972 +        /**
 26.2973 +         * Reads in single UTF-encoded character one byte at a time, appends
 26.2974 +         * the character to sbuf, and returns the number of bytes consumed.
 26.2975 +         * This method is used when reading in UTF strings written in block
 26.2976 +         * data mode to handle UTF-encoded characters which (potentially)
 26.2977 +         * straddle block-data boundaries.
 26.2978 +         */
 26.2979 +        private int readUTFChar(StringBuilder sbuf, long utflen)
 26.2980 +            throws IOException
 26.2981 +        {
 26.2982 +            int b1, b2, b3;
 26.2983 +            b1 = readByte() & 0xFF;
 26.2984 +            switch (b1 >> 4) {
 26.2985 +                case 0:
 26.2986 +                case 1:
 26.2987 +                case 2:
 26.2988 +                case 3:
 26.2989 +                case 4:
 26.2990 +                case 5:
 26.2991 +                case 6:
 26.2992 +                case 7:     // 1 byte format: 0xxxxxxx
 26.2993 +                    sbuf.append((char) b1);
 26.2994 +                    return 1;
 26.2995 +
 26.2996 +                case 12:
 26.2997 +                case 13:    // 2 byte format: 110xxxxx 10xxxxxx
 26.2998 +                    if (utflen < 2) {
 26.2999 +                        throw new UTFDataFormatException();
 26.3000 +                    }
 26.3001 +                    b2 = readByte();
 26.3002 +                    if ((b2 & 0xC0) != 0x80) {
 26.3003 +                        throw new UTFDataFormatException();
 26.3004 +                    }
 26.3005 +                    sbuf.append((char) (((b1 & 0x1F) << 6) |
 26.3006 +                                        ((b2 & 0x3F) << 0)));
 26.3007 +                    return 2;
 26.3008 +
 26.3009 +                case 14:    // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx
 26.3010 +                    if (utflen < 3) {
 26.3011 +                        if (utflen == 2) {
 26.3012 +                            readByte();         // consume remaining byte
 26.3013 +                        }
 26.3014 +                        throw new UTFDataFormatException();
 26.3015 +                    }
 26.3016 +                    b2 = readByte();
 26.3017 +                    b3 = readByte();
 26.3018 +                    if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) {
 26.3019 +                        throw new UTFDataFormatException();
 26.3020 +                    }
 26.3021 +                    sbuf.append((char) (((b1 & 0x0F) << 12) |
 26.3022 +                                        ((b2 & 0x3F) << 6) |
 26.3023 +                                        ((b3 & 0x3F) << 0)));
 26.3024 +                    return 3;
 26.3025 +
 26.3026 +                default:   // 10xx xxxx, 1111 xxxx
 26.3027 +                    throw new UTFDataFormatException();
 26.3028 +            }
 26.3029 +        }
 26.3030 +    }
 26.3031 +
 26.3032 +    /**
 26.3033 +     * Unsynchronized table which tracks wire handle to object mappings, as
 26.3034 +     * well as ClassNotFoundExceptions associated with deserialized objects.
 26.3035 +     * This class implements an exception-propagation algorithm for
 26.3036 +     * determining which objects should have ClassNotFoundExceptions associated
 26.3037 +     * with them, taking into account cycles and discontinuities (e.g., skipped
 26.3038 +     * fields) in the object graph.
 26.3039 +     *
 26.3040 +     * <p>General use of the table is as follows: during deserialization, a
 26.3041 +     * given object is first assigned a handle by calling the assign method.
 26.3042 +     * This method leaves the assigned handle in an "open" state, wherein
 26.3043 +     * dependencies on the exception status of other handles can be registered
 26.3044 +     * by calling the markDependency method, or an exception can be directly
 26.3045 +     * associated with the handle by calling markException.  When a handle is
 26.3046 +     * tagged with an exception, the HandleTable assumes responsibility for
 26.3047 +     * propagating the exception to any other objects which depend
 26.3048 +     * (transitively) on the exception-tagged object.
 26.3049 +     *
 26.3050 +     * <p>Once all exception information/dependencies for the handle have been
 26.3051 +     * registered, the handle should be "closed" by calling the finish method
 26.3052 +     * on it.  The act of finishing a handle allows the exception propagation
 26.3053 +     * algorithm to aggressively prune dependency links, lessening the
 26.3054 +     * performance/memory impact of exception tracking.
 26.3055 +     *
 26.3056 +     * <p>Note that the exception propagation algorithm used depends on handles
 26.3057 +     * being assigned/finished in LIFO order; however, for simplicity as well
 26.3058 +     * as memory conservation, it does not enforce this constraint.
 26.3059 +     */
 26.3060 +    // REMIND: add full description of exception propagation algorithm?
 26.3061 +    private static class HandleTable {
 26.3062 +
 26.3063 +        /* status codes indicating whether object has associated exception */
 26.3064 +        private static final byte STATUS_OK = 1;
 26.3065 +        private static final byte STATUS_UNKNOWN = 2;
 26.3066 +        private static final byte STATUS_EXCEPTION = 3;
 26.3067 +
 26.3068 +        /** array mapping handle -> object status */
 26.3069 +        byte[] status;
 26.3070 +        /** array mapping handle -> object/exception (depending on status) */
 26.3071 +        Object[] entries;
 26.3072 +        /** array mapping handle -> list of dependent handles (if any) */
 26.3073 +        HandleList[] deps;
 26.3074 +        /** lowest unresolved dependency */
 26.3075 +        int lowDep = -1;
 26.3076 +        /** number of handles in table */
 26.3077 +        int size = 0;
 26.3078 +
 26.3079 +        /**
 26.3080 +         * Creates handle table with the given initial capacity.
 26.3081 +         */
 26.3082 +        HandleTable(int initialCapacity) {
 26.3083 +            status = new byte[initialCapacity];
 26.3084 +            entries = new Object[initialCapacity];
 26.3085 +            deps = new HandleList[initialCapacity];
 26.3086 +        }
 26.3087 +
 26.3088 +        /**
 26.3089 +         * Assigns next available handle to given object, and returns assigned
 26.3090 +         * handle.  Once object has been completely deserialized (and all
 26.3091 +         * dependencies on other objects identified), the handle should be
 26.3092 +         * "closed" by passing it to finish().
 26.3093 +         */
 26.3094 +        int assign(Object obj) {
 26.3095 +            if (size >= entries.length) {
 26.3096 +                grow();
 26.3097 +            }
 26.3098 +            status[size] = STATUS_UNKNOWN;
 26.3099 +            entries[size] = obj;
 26.3100 +            return size++;
 26.3101 +        }
 26.3102 +
 26.3103 +        /**
 26.3104 +         * Registers a dependency (in exception status) of one handle on
 26.3105 +         * another.  The dependent handle must be "open" (i.e., assigned, but
 26.3106 +         * not finished yet).  No action is taken if either dependent or target
 26.3107 +         * handle is NULL_HANDLE.
 26.3108 +         */
 26.3109 +        void markDependency(int dependent, int target) {
 26.3110 +            if (dependent == NULL_HANDLE || target == NULL_HANDLE) {
 26.3111 +                return;
 26.3112 +            }
 26.3113 +            switch (status[dependent]) {
 26.3114 +
 26.3115 +                case STATUS_UNKNOWN:
 26.3116 +                    switch (status[target]) {
 26.3117 +                        case STATUS_OK:
 26.3118 +                            // ignore dependencies on objs with no exception
 26.3119 +                            break;
 26.3120 +
 26.3121 +                        case STATUS_EXCEPTION:
 26.3122 +                            // eagerly propagate exception
 26.3123 +                            markException(dependent,
 26.3124 +                                (ClassNotFoundException) entries[target]);
 26.3125 +                            break;
 26.3126 +
 26.3127 +                        case STATUS_UNKNOWN:
 26.3128 +                            // add to dependency list of target
 26.3129 +                            if (deps[target] == null) {
 26.3130 +                                deps[target] = new HandleList();
 26.3131 +                            }
 26.3132 +                            deps[target].add(dependent);
 26.3133 +
 26.3134 +                            // remember lowest unresolved target seen
 26.3135 +                            if (lowDep < 0 || lowDep > target) {
 26.3136 +                                lowDep = target;
 26.3137 +                            }
 26.3138 +                            break;
 26.3139 +
 26.3140 +                        default:
 26.3141 +                            throw new InternalError();
 26.3142 +                    }
 26.3143 +                    break;
 26.3144 +
 26.3145 +                case STATUS_EXCEPTION:
 26.3146 +                    break;
 26.3147 +
 26.3148 +                default:
 26.3149 +                    throw new InternalError();
 26.3150 +            }
 26.3151 +        }
 26.3152 +
 26.3153 +        /**
 26.3154 +         * Associates a ClassNotFoundException (if one not already associated)
 26.3155 +         * with the currently active handle and propagates it to other
 26.3156 +         * referencing objects as appropriate.  The specified handle must be
 26.3157 +         * "open" (i.e., assigned, but not finished yet).
 26.3158 +         */
 26.3159 +        void markException(int handle, ClassNotFoundException ex) {
 26.3160 +            switch (status[handle]) {
 26.3161 +                case STATUS_UNKNOWN:
 26.3162 +                    status[handle] = STATUS_EXCEPTION;
 26.3163 +                    entries[handle] = ex;
 26.3164 +
 26.3165 +                    // propagate exception to dependents
 26.3166 +                    HandleList dlist = deps[handle];
 26.3167 +                    if (dlist != null) {
 26.3168 +                        int ndeps = dlist.size();
 26.3169 +                        for (int i = 0; i < ndeps; i++) {
 26.3170 +                            markException(dlist.get(i), ex);
 26.3171 +                        }
 26.3172 +                        deps[handle] = null;
 26.3173 +                    }
 26.3174 +                    break;
 26.3175 +
 26.3176 +                case STATUS_EXCEPTION:
 26.3177 +                    break;
 26.3178 +
 26.3179 +                default:
 26.3180 +                    throw new InternalError();
 26.3181 +            }
 26.3182 +        }
 26.3183 +
 26.3184 +        /**
 26.3185 +         * Marks given handle as finished, meaning that no new dependencies
 26.3186 +         * will be marked for handle.  Calls to the assign and finish methods
 26.3187 +         * must occur in LIFO order.
 26.3188 +         */
 26.3189 +        void finish(int handle) {
 26.3190 +            int end;
 26.3191 +            if (lowDep < 0) {
 26.3192 +                // no pending unknowns, only resolve current handle
 26.3193 +                end = handle + 1;
 26.3194 +            } else if (lowDep >= handle) {
 26.3195 +                // pending unknowns now clearable, resolve all upward handles
 26.3196 +                end = size;
 26.3197 +                lowDep = -1;
 26.3198 +            } else {
 26.3199 +                // unresolved backrefs present, can't resolve anything yet
 26.3200 +                return;
 26.3201 +            }
 26.3202 +
 26.3203 +            // change STATUS_UNKNOWN -> STATUS_OK in selected span of handles
 26.3204 +            for (int i = handle; i < end; i++) {
 26.3205 +                switch (status[i]) {
 26.3206 +                    case STATUS_UNKNOWN:
 26.3207 +                        status[i] = STATUS_OK;
 26.3208 +                        deps[i] = null;
 26.3209 +                        break;
 26.3210 +
 26.3211 +                    case STATUS_OK:
 26.3212 +                    case STATUS_EXCEPTION:
 26.3213 +                        break;
 26.3214 +
 26.3215 +                    default:
 26.3216 +                        throw new InternalError();
 26.3217 +                }
 26.3218 +            }
 26.3219 +        }
 26.3220 +
 26.3221 +        /**
 26.3222 +         * Assigns a new object to the given handle.  The object previously
 26.3223 +         * associated with the handle is forgotten.  This method has no effect
 26.3224 +         * if the given handle already has an exception associated with it.
 26.3225 +         * This method may be called at any time after the handle is assigned.
 26.3226 +         */
 26.3227 +        void setObject(int handle, Object obj) {
 26.3228 +            switch (status[handle]) {
 26.3229 +                case STATUS_UNKNOWN:
 26.3230 +                case STATUS_OK:
 26.3231 +                    entries[handle] = obj;
 26.3232 +                    break;
 26.3233 +
 26.3234 +                case STATUS_EXCEPTION:
 26.3235 +                    break;
 26.3236 +
 26.3237 +                default:
 26.3238 +                    throw new InternalError();
 26.3239 +            }
 26.3240 +        }
 26.3241 +
 26.3242 +        /**
 26.3243 +         * Looks up and returns object associated with the given handle.
 26.3244 +         * Returns null if the given handle is NULL_HANDLE, or if it has an
 26.3245 +         * associated ClassNotFoundException.
 26.3246 +         */
 26.3247 +        Object lookupObject(int handle) {
 26.3248 +            return (handle != NULL_HANDLE &&
 26.3249 +                    status[handle] != STATUS_EXCEPTION) ?
 26.3250 +                entries[handle] : null;
 26.3251 +        }
 26.3252 +
 26.3253 +        /**
 26.3254 +         * Looks up and returns ClassNotFoundException associated with the
 26.3255 +         * given handle.  Returns null if the given handle is NULL_HANDLE, or
 26.3256 +         * if there is no ClassNotFoundException associated with the handle.
 26.3257 +         */
 26.3258 +        ClassNotFoundException lookupException(int handle) {
 26.3259 +            return (handle != NULL_HANDLE &&
 26.3260 +                    status[handle] == STATUS_EXCEPTION) ?
 26.3261 +                (ClassNotFoundException) entries[handle] : null;
 26.3262 +        }
 26.3263 +
 26.3264 +        /**
 26.3265 +         * Resets table to its initial state.
 26.3266 +         */
 26.3267 +        void clear() {
 26.3268 +            Arrays.fill(status, 0, size, (byte) 0);
 26.3269 +            Arrays.fill(entries, 0, size, null);
 26.3270 +            Arrays.fill(deps, 0, size, null);
 26.3271 +            lowDep = -1;
 26.3272 +            size = 0;
 26.3273 +        }
 26.3274 +
 26.3275 +        /**
 26.3276 +         * Returns number of handles registered in table.
 26.3277 +         */
 26.3278 +        int size() {
 26.3279 +            return size;
 26.3280 +        }
 26.3281 +
 26.3282 +        /**
 26.3283 +         * Expands capacity of internal arrays.
 26.3284 +         */
 26.3285 +        private void grow() {
 26.3286 +            int newCapacity = (entries.length << 1) + 1;
 26.3287 +
 26.3288 +            byte[] newStatus = new byte[newCapacity];
 26.3289 +            Object[] newEntries = new Object[newCapacity];
 26.3290 +            HandleList[] newDeps = new HandleList[newCapacity];
 26.3291 +
 26.3292 +            System.arraycopy(status, 0, newStatus, 0, size);
 26.3293 +            System.arraycopy(entries, 0, newEntries, 0, size);
 26.3294 +            System.arraycopy(deps, 0, newDeps, 0, size);
 26.3295 +
 26.3296 +            status = newStatus;
 26.3297 +            entries = newEntries;
 26.3298 +            deps = newDeps;
 26.3299 +        }
 26.3300 +
 26.3301 +        /**
 26.3302 +         * Simple growable list of (integer) handles.
 26.3303 +         */
 26.3304 +        private static class HandleList {
 26.3305 +            private int[] list = new int[4];
 26.3306 +            private int size = 0;
 26.3307 +
 26.3308 +            public HandleList() {
 26.3309 +            }
 26.3310 +
 26.3311 +            public void add(int handle) {
 26.3312 +                if (size >= list.length) {
 26.3313 +                    int[] newList = new int[list.length << 1];
 26.3314 +                    System.arraycopy(list, 0, newList, 0, list.length);
 26.3315 +                    list = newList;
 26.3316 +                }
 26.3317 +                list[size++] = handle;
 26.3318 +            }
 26.3319 +
 26.3320 +            public int get(int index) {
 26.3321 +                if (index >= size) {
 26.3322 +                    throw new ArrayIndexOutOfBoundsException();
 26.3323 +                }
 26.3324 +                return list[index];
 26.3325 +            }
 26.3326 +
 26.3327 +            public int size() {
 26.3328 +                return size;
 26.3329 +            }
 26.3330 +        }
 26.3331 +    }
 26.3332 +
 26.3333 +    /**
 26.3334 +     * Method for cloning arrays in case of using unsharing reading
 26.3335 +     */
 26.3336 +    private static Object cloneArray(Object array) {
 26.3337 +        if (array instanceof Object[]) {
 26.3338 +            return ((Object[]) array).clone();
 26.3339 +        } else if (array instanceof boolean[]) {
 26.3340 +            return ((boolean[]) array).clone();
 26.3341 +        } else if (array instanceof byte[]) {
 26.3342 +            return ((byte[]) array).clone();
 26.3343 +        } else if (array instanceof char[]) {
 26.3344 +            return ((char[]) array).clone();
 26.3345 +        } else if (array instanceof double[]) {
 26.3346 +            return ((double[]) array).clone();
 26.3347 +        } else if (array instanceof float[]) {
 26.3348 +            return ((float[]) array).clone();
 26.3349 +        } else if (array instanceof int[]) {
 26.3350 +            return ((int[]) array).clone();
 26.3351 +        } else if (array instanceof long[]) {
 26.3352 +            return ((long[]) array).clone();
 26.3353 +        } else if (array instanceof short[]) {
 26.3354 +            return ((short[]) array).clone();
 26.3355 +        } else {
 26.3356 +            throw new AssertionError();
 26.3357 +        }
 26.3358 +    }
 26.3359 +
 26.3360 +}
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/emul/compact/src/main/java/java/io/ObjectInputValidation.java	Tue Feb 05 17:04:22 2013 +0100
    27.3 @@ -0,0 +1,45 @@
    27.4 +/*
    27.5 + * Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved.
    27.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    27.7 + *
    27.8 + * This code is free software; you can redistribute it and/or modify it
    27.9 + * under the terms of the GNU General Public License version 2 only, as
   27.10 + * published by the Free Software Foundation.  Oracle designates this
   27.11 + * particular file as subject to the "Classpath" exception as provided
   27.12 + * by Oracle in the LICENSE file that accompanied this code.
   27.13 + *
   27.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   27.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   27.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   27.17 + * version 2 for more details (a copy is included in the LICENSE file that
   27.18 + * accompanied this code).
   27.19 + *
   27.20 + * You should have received a copy of the GNU General Public License version
   27.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   27.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   27.23 + *
   27.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   27.25 + * or visit www.oracle.com if you need additional information or have any
   27.26 + * questions.
   27.27 + */
   27.28 +
   27.29 +package java.io;
   27.30 +
   27.31 +/**
   27.32 + * Callback interface to allow validation of objects within a graph.
   27.33 + * Allows an object to be called when a complete graph of objects has
   27.34 + * been deserialized.
   27.35 + *
   27.36 + * @author  unascribed
   27.37 + * @see     ObjectInputStream
   27.38 + * @see     ObjectInputStream#registerValidation(java.io.ObjectInputValidation, int)
   27.39 + * @since   JDK1.1
   27.40 + */
   27.41 +public interface ObjectInputValidation {
   27.42 +    /**
   27.43 +     * Validates the object.
   27.44 +     *
   27.45 +     * @exception InvalidObjectException If the object cannot validate itself.
   27.46 +     */
   27.47 +    public void validateObject() throws InvalidObjectException;
   27.48 +}
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/emul/compact/src/main/java/java/io/ObjectOutput.java	Tue Feb 05 17:04:22 2013 +0100
    28.3 @@ -0,0 +1,90 @@
    28.4 +/*
    28.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
    28.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    28.7 + *
    28.8 + * This code is free software; you can redistribute it and/or modify it
    28.9 + * under the terms of the GNU General Public License version 2 only, as
   28.10 + * published by the Free Software Foundation.  Oracle designates this
   28.11 + * particular file as subject to the "Classpath" exception as provided
   28.12 + * by Oracle in the LICENSE file that accompanied this code.
   28.13 + *
   28.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   28.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   28.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   28.17 + * version 2 for more details (a copy is included in the LICENSE file that
   28.18 + * accompanied this code).
   28.19 + *
   28.20 + * You should have received a copy of the GNU General Public License version
   28.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   28.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   28.23 + *
   28.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   28.25 + * or visit www.oracle.com if you need additional information or have any
   28.26 + * questions.
   28.27 + */
   28.28 +
   28.29 +package java.io;
   28.30 +
   28.31 +/**
   28.32 + * ObjectOutput extends the DataOutput interface to include writing of objects.
   28.33 + * DataOutput includes methods for output of primitive types, ObjectOutput
   28.34 + * extends that interface to include objects, arrays, and Strings.
   28.35 + *
   28.36 + * @author  unascribed
   28.37 + * @see java.io.InputStream
   28.38 + * @see java.io.ObjectOutputStream
   28.39 + * @see java.io.ObjectInputStream
   28.40 + * @since   JDK1.1
   28.41 + */
   28.42 +public interface ObjectOutput extends DataOutput, AutoCloseable {
   28.43 +    /**
   28.44 +     * Write an object to the underlying storage or stream.  The
   28.45 +     * class that implements this interface defines how the object is
   28.46 +     * written.
   28.47 +     *
   28.48 +     * @param obj the object to be written
   28.49 +     * @exception IOException Any of the usual Input/Output related exceptions.
   28.50 +     */
   28.51 +    public void writeObject(Object obj)
   28.52 +      throws IOException;
   28.53 +
   28.54 +    /**
   28.55 +     * Writes a byte. This method will block until the byte is actually
   28.56 +     * written.
   28.57 +     * @param b the byte
   28.58 +     * @exception IOException If an I/O error has occurred.
   28.59 +     */
   28.60 +    public void write(int b) throws IOException;
   28.61 +
   28.62 +    /**
   28.63 +     * Writes an array of bytes. This method will block until the bytes
   28.64 +     * are actually written.
   28.65 +     * @param b the data to be written
   28.66 +     * @exception IOException If an I/O error has occurred.
   28.67 +     */
   28.68 +    public void write(byte b[]) throws IOException;
   28.69 +
   28.70 +    /**
   28.71 +     * Writes a sub array of bytes.
   28.72 +     * @param b the data to be written
   28.73 +     * @param off       the start offset in the data
   28.74 +     * @param len       the number of bytes that are written
   28.75 +     * @exception IOException If an I/O error has occurred.
   28.76 +     */
   28.77 +    public void write(byte b[], int off, int len) throws IOException;
   28.78 +
   28.79 +    /**
   28.80 +     * Flushes the stream. This will write any buffered
   28.81 +     * output bytes.
   28.82 +     * @exception IOException If an I/O error has occurred.
   28.83 +     */
   28.84 +    public void flush() throws IOException;
   28.85 +
   28.86 +    /**
   28.87 +     * Closes the stream. This method must be called
   28.88 +     * to release any resources associated with the
   28.89 +     * stream.
   28.90 +     * @exception IOException If an I/O error has occurred.
   28.91 +     */
   28.92 +    public void close() throws IOException;
   28.93 +}
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/emul/compact/src/main/java/java/io/ObjectOutputStream.java	Tue Feb 05 17:04:22 2013 +0100
    29.3 @@ -0,0 +1,2369 @@
    29.4 +/*
    29.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
    29.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    29.7 + *
    29.8 + * This code is free software; you can redistribute it and/or modify it
    29.9 + * under the terms of the GNU General Public License version 2 only, as
   29.10 + * published by the Free Software Foundation.  Oracle designates this
   29.11 + * particular file as subject to the "Classpath" exception as provided
   29.12 + * by Oracle in the LICENSE file that accompanied this code.
   29.13 + *
   29.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   29.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   29.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   29.17 + * version 2 for more details (a copy is included in the LICENSE file that
   29.18 + * accompanied this code).
   29.19 + *
   29.20 + * You should have received a copy of the GNU General Public License version
   29.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   29.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   29.23 + *
   29.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   29.25 + * or visit www.oracle.com if you need additional information or have any
   29.26 + * questions.
   29.27 + */
   29.28 +
   29.29 +package java.io;
   29.30 +
   29.31 +import java.util.ArrayList;
   29.32 +import java.util.Arrays;
   29.33 +import java.util.List;
   29.34 +import org.apidesign.bck2brwsr.emul.lang.System;
   29.35 +
   29.36 +/**
   29.37 + * An ObjectOutputStream writes primitive data types and graphs of Java objects
   29.38 + * to an OutputStream.  The objects can be read (reconstituted) using an
   29.39 + * ObjectInputStream.  Persistent storage of objects can be accomplished by
   29.40 + * using a file for the stream.  If the stream is a network socket stream, the
   29.41 + * objects can be reconstituted on another host or in another process.
   29.42 + *
   29.43 + * <p>Only objects that support the java.io.Serializable interface can be
   29.44 + * written to streams.  The class of each serializable object is encoded
   29.45 + * including the class name and signature of the class, the values of the
   29.46 + * object's fields and arrays, and the closure of any other objects referenced
   29.47 + * from the initial objects.
   29.48 + *
   29.49 + * <p>The method writeObject is used to write an object to the stream.  Any
   29.50 + * object, including Strings and arrays, is written with writeObject. Multiple
   29.51 + * objects or primitives can be written to the stream.  The objects must be
   29.52 + * read back from the corresponding ObjectInputstream with the same types and
   29.53 + * in the same order as they were written.
   29.54 + *
   29.55 + * <p>Primitive data types can also be written to the stream using the
   29.56 + * appropriate methods from DataOutput. Strings can also be written using the
   29.57 + * writeUTF method.
   29.58 + *
   29.59 + * <p>The default serialization mechanism for an object writes the class of the
   29.60 + * object, the class signature, and the values of all non-transient and
   29.61 + * non-static fields.  References to other objects (except in transient or
   29.62 + * static fields) cause those objects to be written also. Multiple references
   29.63 + * to a single object are encoded using a reference sharing mechanism so that
   29.64 + * graphs of objects can be restored to the same shape as when the original was
   29.65 + * written.
   29.66 + *
   29.67 + * <p>For example to write an object that can be read by the example in
   29.68 + * ObjectInputStream:
   29.69 + * <br>
   29.70 + * <pre>
   29.71 + *      FileOutputStream fos = new FileOutputStream("t.tmp");
   29.72 + *      ObjectOutputStream oos = new ObjectOutputStream(fos);
   29.73 + *
   29.74 + *      oos.writeInt(12345);
   29.75 + *      oos.writeObject("Today");
   29.76 + *      oos.writeObject(new Date());
   29.77 + *
   29.78 + *      oos.close();
   29.79 + * </pre>
   29.80 + *
   29.81 + * <p>Classes that require special handling during the serialization and
   29.82 + * deserialization process must implement special methods with these exact
   29.83 + * signatures:
   29.84 + * <br>
   29.85 + * <pre>
   29.86 + * private void readObject(java.io.ObjectInputStream stream)
   29.87 + *     throws IOException, ClassNotFoundException;
   29.88 + * private void writeObject(java.io.ObjectOutputStream stream)
   29.89 + *     throws IOException
   29.90 + * private void readObjectNoData()
   29.91 + *     throws ObjectStreamException;
   29.92 + * </pre>
   29.93 + *
   29.94 + * <p>The writeObject method is responsible for writing the state of the object
   29.95 + * for its particular class so that the corresponding readObject method can
   29.96 + * restore it.  The method does not need to concern itself with the state
   29.97 + * belonging to the object's superclasses or subclasses.  State is saved by
   29.98 + * writing the individual fields to the ObjectOutputStream using the
   29.99 + * writeObject method or by using the methods for primitive data types
  29.100 + * supported by DataOutput.
  29.101 + *
  29.102 + * <p>Serialization does not write out the fields of any object that does not
  29.103 + * implement the java.io.Serializable interface.  Subclasses of Objects that
  29.104 + * are not serializable can be serializable. In this case the non-serializable
  29.105 + * class must have a no-arg constructor to allow its fields to be initialized.
  29.106 + * In this case it is the responsibility of the subclass to save and restore
  29.107 + * the state of the non-serializable class. It is frequently the case that the
  29.108 + * fields of that class are accessible (public, package, or protected) or that
  29.109 + * there are get and set methods that can be used to restore the state.
  29.110 + *
  29.111 + * <p>Serialization of an object can be prevented by implementing writeObject
  29.112 + * and readObject methods that throw the NotSerializableException.  The
  29.113 + * exception will be caught by the ObjectOutputStream and abort the
  29.114 + * serialization process.
  29.115 + *
  29.116 + * <p>Implementing the Externalizable interface allows the object to assume
  29.117 + * complete control over the contents and format of the object's serialized
  29.118 + * form.  The methods of the Externalizable interface, writeExternal and
  29.119 + * readExternal, are called to save and restore the objects state.  When
  29.120 + * implemented by a class they can write and read their own state using all of
  29.121 + * the methods of ObjectOutput and ObjectInput.  It is the responsibility of
  29.122 + * the objects to handle any versioning that occurs.
  29.123 + *
  29.124 + * <p>Enum constants are serialized differently than ordinary serializable or
  29.125 + * externalizable objects.  The serialized form of an enum constant consists
  29.126 + * solely of its name; field values of the constant are not transmitted.  To
  29.127 + * serialize an enum constant, ObjectOutputStream writes the string returned by
  29.128 + * the constant's name method.  Like other serializable or externalizable
  29.129 + * objects, enum constants can function as the targets of back references
  29.130 + * appearing subsequently in the serialization stream.  The process by which
  29.131 + * enum constants are serialized cannot be customized; any class-specific
  29.132 + * writeObject and writeReplace methods defined by enum types are ignored
  29.133 + * during serialization.  Similarly, any serialPersistentFields or
  29.134 + * serialVersionUID field declarations are also ignored--all enum types have a
  29.135 + * fixed serialVersionUID of 0L.
  29.136 + *
  29.137 + * <p>Primitive data, excluding serializable fields and externalizable data, is
  29.138 + * written to the ObjectOutputStream in block-data records. A block data record
  29.139 + * is composed of a header and data. The block data header consists of a marker
  29.140 + * and the number of bytes to follow the header.  Consecutive primitive data
  29.141 + * writes are merged into one block-data record.  The blocking factor used for
  29.142 + * a block-data record will be 1024 bytes.  Each block-data record will be
  29.143 + * filled up to 1024 bytes, or be written whenever there is a termination of
  29.144 + * block-data mode.  Calls to the ObjectOutputStream methods writeObject,
  29.145 + * defaultWriteObject and writeFields initially terminate any existing
  29.146 + * block-data record.
  29.147 + *
  29.148 + * @author      Mike Warres
  29.149 + * @author      Roger Riggs
  29.150 + * @see java.io.DataOutput
  29.151 + * @see java.io.ObjectInputStream
  29.152 + * @see java.io.Serializable
  29.153 + * @see java.io.Externalizable
  29.154 + * @see <a href="../../../platform/serialization/spec/output.html">Object Serialization Specification, Section 2, Object Output Classes</a>
  29.155 + * @since       JDK1.1
  29.156 + */
  29.157 +public class ObjectOutputStream
  29.158 +    extends OutputStream implements ObjectOutput, ObjectStreamConstants
  29.159 +{
  29.160 +    /** filter stream for handling block data conversion */
  29.161 +    private final BlockDataOutputStream bout;
  29.162 +    /** obj -> wire handle map */
  29.163 +    private final HandleTable handles;
  29.164 +    /** obj -> replacement obj map */
  29.165 +    private final ReplaceTable subs;
  29.166 +    /** stream protocol version */
  29.167 +    private int protocol = PROTOCOL_VERSION_2;
  29.168 +    /** recursion depth */
  29.169 +    private int depth;
  29.170 +
  29.171 +    /** buffer for writing primitive field values */
  29.172 +    private byte[] primVals;
  29.173 +
  29.174 +    /** if true, invoke writeObjectOverride() instead of writeObject() */
  29.175 +    private final boolean enableOverride;
  29.176 +    /** if true, invoke replaceObject() */
  29.177 +    private boolean enableReplace;
  29.178 +
  29.179 +    // values below valid only during upcalls to writeObject()/writeExternal()
  29.180 +    /**
  29.181 +     * Context during upcalls to class-defined writeObject methods; holds
  29.182 +     * object currently being serialized and descriptor for current class.
  29.183 +     * Null when not during writeObject upcall.
  29.184 +     */
  29.185 +    private Object curContext;
  29.186 +    /** current PutField object */
  29.187 +    private PutFieldImpl curPut;
  29.188 +
  29.189 +    /** custom storage for debug trace info */
  29.190 +    private final DebugTraceInfoStack debugInfoStack;
  29.191 +
  29.192 +    /**
  29.193 +     * value of "sun.io.serialization.extendedDebugInfo" property,
  29.194 +     * as true or false for extended information about exception's place
  29.195 +     */
  29.196 +    private static final boolean extendedDebugInfo = false;
  29.197 +
  29.198 +    /**
  29.199 +     * Creates an ObjectOutputStream that writes to the specified OutputStream.
  29.200 +     * This constructor writes the serialization stream header to the
  29.201 +     * underlying stream; callers may wish to flush the stream immediately to
  29.202 +     * ensure that constructors for receiving ObjectInputStreams will not block
  29.203 +     * when reading the header.
  29.204 +     *
  29.205 +     * <p>If a security manager is installed, this constructor will check for
  29.206 +     * the "enableSubclassImplementation" SerializablePermission when invoked
  29.207 +     * directly or indirectly by the constructor of a subclass which overrides
  29.208 +     * the ObjectOutputStream.putFields or ObjectOutputStream.writeUnshared
  29.209 +     * methods.
  29.210 +     *
  29.211 +     * @param   out output stream to write to
  29.212 +     * @throws  IOException if an I/O error occurs while writing stream header
  29.213 +     * @throws  SecurityException if untrusted subclass illegally overrides
  29.214 +     *          security-sensitive methods
  29.215 +     * @throws  NullPointerException if <code>out</code> is <code>null</code>
  29.216 +     * @since   1.4
  29.217 +     * @see     ObjectOutputStream#ObjectOutputStream()
  29.218 +     * @see     ObjectOutputStream#putFields()
  29.219 +     * @see     ObjectInputStream#ObjectInputStream(InputStream)
  29.220 +     */
  29.221 +    public ObjectOutputStream(OutputStream out) throws IOException {
  29.222 +        verifySubclass();
  29.223 +        bout = new BlockDataOutputStream(out);
  29.224 +        handles = new HandleTable(10, (float) 3.00);
  29.225 +        subs = new ReplaceTable(10, (float) 3.00);
  29.226 +        enableOverride = false;
  29.227 +        writeStreamHeader();
  29.228 +        bout.setBlockDataMode(true);
  29.229 +        if (extendedDebugInfo) {
  29.230 +            debugInfoStack = new DebugTraceInfoStack();
  29.231 +        } else {
  29.232 +            debugInfoStack = null;
  29.233 +        }
  29.234 +    }
  29.235 +
  29.236 +    /**
  29.237 +     * Provide a way for subclasses that are completely reimplementing
  29.238 +     * ObjectOutputStream to not have to allocate private data just used by
  29.239 +     * this implementation of ObjectOutputStream.
  29.240 +     *
  29.241 +     * <p>If there is a security manager installed, this method first calls the
  29.242 +     * security manager's <code>checkPermission</code> method with a
  29.243 +     * <code>SerializablePermission("enableSubclassImplementation")</code>
  29.244 +     * permission to ensure it's ok to enable subclassing.
  29.245 +     *
  29.246 +     * @throws  SecurityException if a security manager exists and its
  29.247 +     *          <code>checkPermission</code> method denies enabling
  29.248 +     *          subclassing.
  29.249 +     * @see SecurityManager#checkPermission
  29.250 +     * @see java.io.SerializablePermission
  29.251 +     */
  29.252 +    protected ObjectOutputStream() throws IOException, SecurityException {
  29.253 +        throw new SecurityException();
  29.254 +    }
  29.255 +
  29.256 +    /**
  29.257 +     * Specify stream protocol version to use when writing the stream.
  29.258 +     *
  29.259 +     * <p>This routine provides a hook to enable the current version of
  29.260 +     * Serialization to write in a format that is backwards compatible to a
  29.261 +     * previous version of the stream format.
  29.262 +     *
  29.263 +     * <p>Every effort will be made to avoid introducing additional
  29.264 +     * backwards incompatibilities; however, sometimes there is no
  29.265 +     * other alternative.
  29.266 +     *
  29.267 +     * @param   version use ProtocolVersion from java.io.ObjectStreamConstants.
  29.268 +     * @throws  IllegalStateException if called after any objects
  29.269 +     *          have been serialized.
  29.270 +     * @throws  IllegalArgumentException if invalid version is passed in.
  29.271 +     * @throws  IOException if I/O errors occur
  29.272 +     * @see java.io.ObjectStreamConstants#PROTOCOL_VERSION_1
  29.273 +     * @see java.io.ObjectStreamConstants#PROTOCOL_VERSION_2
  29.274 +     * @since   1.2
  29.275 +     */
  29.276 +    public void useProtocolVersion(int version) throws IOException {
  29.277 +        if (handles.size() != 0) {
  29.278 +            // REMIND: implement better check for pristine stream?
  29.279 +            throw new IllegalStateException("stream non-empty");
  29.280 +        }
  29.281 +        switch (version) {
  29.282 +            case PROTOCOL_VERSION_1:
  29.283 +            case PROTOCOL_VERSION_2:
  29.284 +                protocol = version;
  29.285 +                break;
  29.286 +
  29.287 +            default:
  29.288 +                throw new IllegalArgumentException(
  29.289 +                    "unknown version: " + version);
  29.290 +        }
  29.291 +    }
  29.292 +
  29.293 +    /**
  29.294 +     * Write the specified object to the ObjectOutputStream.  The class of the
  29.295 +     * object, the signature of the class, and the values of the non-transient
  29.296 +     * and non-static fields of the class and all of its supertypes are
  29.297 +     * written.  Default serialization for a class can be overridden using the
  29.298 +     * writeObject and the readObject methods.  Objects referenced by this
  29.299 +     * object are written transitively so that a complete equivalent graph of
  29.300 +     * objects can be reconstructed by an ObjectInputStream.
  29.301 +     *
  29.302 +     * <p>Exceptions are thrown for problems with the OutputStream and for
  29.303 +     * classes that should not be serialized.  All exceptions are fatal to the
  29.304 +     * OutputStream, which is left in an indeterminate state, and it is up to
  29.305 +     * the caller to ignore or recover the stream state.
  29.306 +     *
  29.307 +     * @throws  InvalidClassException Something is wrong with a class used by
  29.308 +     *          serialization.
  29.309 +     * @throws  NotSerializableException Some object to be serialized does not
  29.310 +     *          implement the java.io.Serializable interface.
  29.311 +     * @throws  IOException Any exception thrown by the underlying
  29.312 +     *          OutputStream.
  29.313 +     */
  29.314 +    public final void writeObject(Object obj) throws IOException {
  29.315 +        if (enableOverride) {
  29.316 +            writeObjectOverride(obj);
  29.317 +            return;
  29.318 +        }
  29.319 +        try {
  29.320 +            writeObject0(obj, false);
  29.321 +        } catch (IOException ex) {
  29.322 +            if (depth == 0) {
  29.323 +                writeFatalException(ex);
  29.324 +            }
  29.325 +            throw ex;
  29.326 +        }
  29.327 +    }
  29.328 +
  29.329 +    /**
  29.330 +     * Method used by subclasses to override the default writeObject method.
  29.331 +     * This method is called by trusted subclasses of ObjectInputStream that
  29.332 +     * constructed ObjectInputStream using the protected no-arg constructor.
  29.333 +     * The subclass is expected to provide an override method with the modifier
  29.334 +     * "final".
  29.335 +     *
  29.336 +     * @param   obj object to be written to the underlying stream
  29.337 +     * @throws  IOException if there are I/O errors while writing to the
  29.338 +     *          underlying stream
  29.339 +     * @see #ObjectOutputStream()
  29.340 +     * @see #writeObject(Object)
  29.341 +     * @since 1.2
  29.342 +     */
  29.343 +    protected void writeObjectOverride(Object obj) throws IOException {
  29.344 +    }
  29.345 +
  29.346 +    /**
  29.347 +     * Writes an "unshared" object to the ObjectOutputStream.  This method is
  29.348 +     * identical to writeObject, except that it always writes the given object
  29.349 +     * as a new, unique object in the stream (as opposed to a back-reference
  29.350 +     * pointing to a previously serialized instance).  Specifically:
  29.351 +     * <ul>
  29.352 +     *   <li>An object written via writeUnshared is always serialized in the
  29.353 +     *       same manner as a newly appearing object (an object that has not
  29.354 +     *       been written to the stream yet), regardless of whether or not the
  29.355 +     *       object has been written previously.
  29.356 +     *
  29.357 +     *   <li>If writeObject is used to write an object that has been previously
  29.358 +     *       written with writeUnshared, the previous writeUnshared operation
  29.359 +     *       is treated as if it were a write of a separate object.  In other
  29.360 +     *       words, ObjectOutputStream will never generate back-references to
  29.361 +     *       object data written by calls to writeUnshared.
  29.362 +     * </ul>
  29.363 +     * While writing an object via writeUnshared does not in itself guarantee a
  29.364 +     * unique reference to the object when it is deserialized, it allows a
  29.365 +     * single object to be defined multiple times in a stream, so that multiple
  29.366 +     * calls to readUnshared by the receiver will not conflict.  Note that the
  29.367 +     * rules described above only apply to the base-level object written with
  29.368 +     * writeUnshared, and not to any transitively referenced sub-objects in the
  29.369 +     * object graph to be serialized.
  29.370 +     *
  29.371 +     * <p>ObjectOutputStream subclasses which override this method can only be
  29.372 +     * constructed in security contexts possessing the
  29.373 +     * "enableSubclassImplementation" SerializablePermission; any attempt to
  29.374 +     * instantiate such a subclass without this permission will cause a
  29.375 +     * SecurityException to be thrown.
  29.376 +     *
  29.377 +     * @param   obj object to write to stream
  29.378 +     * @throws  NotSerializableException if an object in the graph to be
  29.379 +     *          serialized does not implement the Serializable interface
  29.380 +     * @throws  InvalidClassException if a problem exists with the class of an
  29.381 +     *          object to be serialized
  29.382 +     * @throws  IOException if an I/O error occurs during serialization
  29.383 +     * @since 1.4
  29.384 +     */
  29.385 +    public void writeUnshared(Object obj) throws IOException {
  29.386 +        try {
  29.387 +            writeObject0(obj, true);
  29.388 +        } catch (IOException ex) {
  29.389 +            if (depth == 0) {
  29.390 +                writeFatalException(ex);
  29.391 +            }
  29.392 +            throw ex;
  29.393 +        }
  29.394 +    }
  29.395 +
  29.396 +    /**
  29.397 +     * Write the non-static and non-transient fields of the current class to
  29.398 +     * this stream.  This may only be called from the writeObject method of the
  29.399 +     * class being serialized. It will throw the NotActiveException if it is
  29.400 +     * called otherwise.
  29.401 +     *
  29.402 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.403 +     *          <code>OutputStream</code>
  29.404 +     */
  29.405 +    public void defaultWriteObject() throws IOException {
  29.406 +        if ( curContext == null ) {
  29.407 +            throw new NotActiveException("not in call to writeObject");
  29.408 +        }
  29.409 +        Object curObj = null; // curContext.getObj();
  29.410 +        ObjectStreamClass curDesc = null; // curContext.getDesc();
  29.411 +        bout.setBlockDataMode(false);
  29.412 +        defaultWriteFields(curObj, curDesc);
  29.413 +        bout.setBlockDataMode(true);
  29.414 +    }
  29.415 +
  29.416 +    /**
  29.417 +     * Retrieve the object used to buffer persistent fields to be written to
  29.418 +     * the stream.  The fields will be written to the stream when writeFields
  29.419 +     * method is called.
  29.420 +     *
  29.421 +     * @return  an instance of the class Putfield that holds the serializable
  29.422 +     *          fields
  29.423 +     * @throws  IOException if I/O errors occur
  29.424 +     * @since 1.2
  29.425 +     */
  29.426 +    public ObjectOutputStream.PutField putFields() throws IOException {
  29.427 +        if (curPut == null) {
  29.428 +            if (curContext == null) {
  29.429 +                throw new NotActiveException("not in call to writeObject");
  29.430 +            }
  29.431 +            Object curObj = null; // curContext.getObj();
  29.432 +            ObjectStreamClass curDesc = null; // curContext.getDesc();
  29.433 +            curPut = new PutFieldImpl(curDesc);
  29.434 +        }
  29.435 +        return curPut;
  29.436 +    }
  29.437 +
  29.438 +    /**
  29.439 +     * Write the buffered fields to the stream.
  29.440 +     *
  29.441 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.442 +     *          stream
  29.443 +     * @throws  NotActiveException Called when a classes writeObject method was
  29.444 +     *          not called to write the state of the object.
  29.445 +     * @since 1.2
  29.446 +     */
  29.447 +    public void writeFields() throws IOException {
  29.448 +        if (curPut == null) {
  29.449 +            throw new NotActiveException("no current PutField object");
  29.450 +        }
  29.451 +        bout.setBlockDataMode(false);
  29.452 +        curPut.writeFields();
  29.453 +        bout.setBlockDataMode(true);
  29.454 +    }
  29.455 +
  29.456 +    /**
  29.457 +     * Reset will disregard the state of any objects already written to the
  29.458 +     * stream.  The state is reset to be the same as a new ObjectOutputStream.
  29.459 +     * The current point in the stream is marked as reset so the corresponding
  29.460 +     * ObjectInputStream will be reset at the same point.  Objects previously
  29.461 +     * written to the stream will not be refered to as already being in the
  29.462 +     * stream.  They will be written to the stream again.
  29.463 +     *
  29.464 +     * @throws  IOException if reset() is invoked while serializing an object.
  29.465 +     */
  29.466 +    public void reset() throws IOException {
  29.467 +        if (depth != 0) {
  29.468 +            throw new IOException("stream active");
  29.469 +        }
  29.470 +        bout.setBlockDataMode(false);
  29.471 +        bout.writeByte(TC_RESET);
  29.472 +        clear();
  29.473 +        bout.setBlockDataMode(true);
  29.474 +    }
  29.475 +
  29.476 +    /**
  29.477 +     * Subclasses may implement this method to allow class data to be stored in
  29.478 +     * the stream. By default this method does nothing.  The corresponding
  29.479 +     * method in ObjectInputStream is resolveClass.  This method is called
  29.480 +     * exactly once for each unique class in the stream.  The class name and
  29.481 +     * signature will have already been written to the stream.  This method may
  29.482 +     * make free use of the ObjectOutputStream to save any representation of
  29.483 +     * the class it deems suitable (for example, the bytes of the class file).
  29.484 +     * The resolveClass method in the corresponding subclass of
  29.485 +     * ObjectInputStream must read and use any data or objects written by
  29.486 +     * annotateClass.
  29.487 +     *
  29.488 +     * @param   cl the class to annotate custom data for
  29.489 +     * @throws  IOException Any exception thrown by the underlying
  29.490 +     *          OutputStream.
  29.491 +     */
  29.492 +    protected void annotateClass(Class<?> cl) throws IOException {
  29.493 +    }
  29.494 +
  29.495 +    /**
  29.496 +     * Subclasses may implement this method to store custom data in the stream
  29.497 +     * along with descriptors for dynamic proxy classes.
  29.498 +     *
  29.499 +     * <p>This method is called exactly once for each unique proxy class
  29.500 +     * descriptor in the stream.  The default implementation of this method in
  29.501 +     * <code>ObjectOutputStream</code> does nothing.
  29.502 +     *
  29.503 +     * <p>The corresponding method in <code>ObjectInputStream</code> is
  29.504 +     * <code>resolveProxyClass</code>.  For a given subclass of
  29.505 +     * <code>ObjectOutputStream</code> that overrides this method, the
  29.506 +     * <code>resolveProxyClass</code> method in the corresponding subclass of
  29.507 +     * <code>ObjectInputStream</code> must read any data or objects written by
  29.508 +     * <code>annotateProxyClass</code>.
  29.509 +     *
  29.510 +     * @param   cl the proxy class to annotate custom data for
  29.511 +     * @throws  IOException any exception thrown by the underlying
  29.512 +     *          <code>OutputStream</code>
  29.513 +     * @see ObjectInputStream#resolveProxyClass(String[])
  29.514 +     * @since   1.3
  29.515 +     */
  29.516 +    protected void annotateProxyClass(Class<?> cl) throws IOException {
  29.517 +    }
  29.518 +
  29.519 +    /**
  29.520 +     * This method will allow trusted subclasses of ObjectOutputStream to
  29.521 +     * substitute one object for another during serialization. Replacing
  29.522 +     * objects is disabled until enableReplaceObject is called. The
  29.523 +     * enableReplaceObject method checks that the stream requesting to do
  29.524 +     * replacement can be trusted.  The first occurrence of each object written
  29.525 +     * into the serialization stream is passed to replaceObject.  Subsequent
  29.526 +     * references to the object are replaced by the object returned by the
  29.527 +     * original call to replaceObject.  To ensure that the private state of
  29.528 +     * objects is not unintentionally exposed, only trusted streams may use
  29.529 +     * replaceObject.
  29.530 +     *
  29.531 +     * <p>The ObjectOutputStream.writeObject method takes a parameter of type
  29.532 +     * Object (as opposed to type Serializable) to allow for cases where
  29.533 +     * non-serializable objects are replaced by serializable ones.
  29.534 +     *
  29.535 +     * <p>When a subclass is replacing objects it must insure that either a
  29.536 +     * complementary substitution must be made during deserialization or that
  29.537 +     * the substituted object is compatible with every field where the
  29.538 +     * reference will be stored.  Objects whose type is not a subclass of the
  29.539 +     * type of the field or array element abort the serialization by raising an
  29.540 +     * exception and the object is not be stored.
  29.541 +     *
  29.542 +     * <p>This method is called only once when each object is first
  29.543 +     * encountered.  All subsequent references to the object will be redirected
  29.544 +     * to the new object. This method should return the object to be
  29.545 +     * substituted or the original object.
  29.546 +     *
  29.547 +     * <p>Null can be returned as the object to be substituted, but may cause
  29.548 +     * NullReferenceException in classes that contain references to the
  29.549 +     * original object since they may be expecting an object instead of
  29.550 +     * null.
  29.551 +     *
  29.552 +     * @param   obj the object to be replaced
  29.553 +     * @return  the alternate object that replaced the specified one
  29.554 +     * @throws  IOException Any exception thrown by the underlying
  29.555 +     *          OutputStream.
  29.556 +     */
  29.557 +    protected Object replaceObject(Object obj) throws IOException {
  29.558 +        return obj;
  29.559 +    }
  29.560 +
  29.561 +    /**
  29.562 +     * Enable the stream to do replacement of objects in the stream.  When
  29.563 +     * enabled, the replaceObject method is called for every object being
  29.564 +     * serialized.
  29.565 +     *
  29.566 +     * <p>If <code>enable</code> is true, and there is a security manager
  29.567 +     * installed, this method first calls the security manager's
  29.568 +     * <code>checkPermission</code> method with a
  29.569 +     * <code>SerializablePermission("enableSubstitution")</code> permission to
  29.570 +     * ensure it's ok to enable the stream to do replacement of objects in the
  29.571 +     * stream.
  29.572 +     *
  29.573 +     * @param   enable boolean parameter to enable replacement of objects
  29.574 +     * @return  the previous setting before this method was invoked
  29.575 +     * @throws  SecurityException if a security manager exists and its
  29.576 +     *          <code>checkPermission</code> method denies enabling the stream
  29.577 +     *          to do replacement of objects in the stream.
  29.578 +     * @see SecurityManager#checkPermission
  29.579 +     * @see java.io.SerializablePermission
  29.580 +     */
  29.581 +    protected boolean enableReplaceObject(boolean enable)
  29.582 +        throws SecurityException
  29.583 +    {
  29.584 +        throw new SecurityException();
  29.585 +    }
  29.586 +
  29.587 +    /**
  29.588 +     * The writeStreamHeader method is provided so subclasses can append or
  29.589 +     * prepend their own header to the stream.  It writes the magic number and
  29.590 +     * version to the stream.
  29.591 +     *
  29.592 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.593 +     *          stream
  29.594 +     */
  29.595 +    protected void writeStreamHeader() throws IOException {
  29.596 +        bout.writeShort(STREAM_MAGIC);
  29.597 +        bout.writeShort(STREAM_VERSION);
  29.598 +    }
  29.599 +
  29.600 +    /**
  29.601 +     * Write the specified class descriptor to the ObjectOutputStream.  Class
  29.602 +     * descriptors are used to identify the classes of objects written to the
  29.603 +     * stream.  Subclasses of ObjectOutputStream may override this method to
  29.604 +     * customize the way in which class descriptors are written to the
  29.605 +     * serialization stream.  The corresponding method in ObjectInputStream,
  29.606 +     * <code>readClassDescriptor</code>, should then be overridden to
  29.607 +     * reconstitute the class descriptor from its custom stream representation.
  29.608 +     * By default, this method writes class descriptors according to the format
  29.609 +     * defined in the Object Serialization specification.
  29.610 +     *
  29.611 +     * <p>Note that this method will only be called if the ObjectOutputStream
  29.612 +     * is not using the old serialization stream format (set by calling
  29.613 +     * ObjectOutputStream's <code>useProtocolVersion</code> method).  If this
  29.614 +     * serialization stream is using the old format
  29.615 +     * (<code>PROTOCOL_VERSION_1</code>), the class descriptor will be written
  29.616 +     * internally in a manner that cannot be overridden or customized.
  29.617 +     *
  29.618 +     * @param   desc class descriptor to write to the stream
  29.619 +     * @throws  IOException If an I/O error has occurred.
  29.620 +     * @see java.io.ObjectInputStream#readClassDescriptor()
  29.621 +     * @see #useProtocolVersion(int)
  29.622 +     * @see java.io.ObjectStreamConstants#PROTOCOL_VERSION_1
  29.623 +     * @since 1.3
  29.624 +     */
  29.625 +    protected void writeClassDescriptor(ObjectStreamClass desc)
  29.626 +        throws IOException
  29.627 +    {
  29.628 +        desc.writeNonProxy(this);
  29.629 +    }
  29.630 +
  29.631 +    /**
  29.632 +     * Writes a byte. This method will block until the byte is actually
  29.633 +     * written.
  29.634 +     *
  29.635 +     * @param   val the byte to be written to the stream
  29.636 +     * @throws  IOException If an I/O error has occurred.
  29.637 +     */
  29.638 +    public void write(int val) throws IOException {
  29.639 +        bout.write(val);
  29.640 +    }
  29.641 +
  29.642 +    /**
  29.643 +     * Writes an array of bytes. This method will block until the bytes are
  29.644 +     * actually written.
  29.645 +     *
  29.646 +     * @param   buf the data to be written
  29.647 +     * @throws  IOException If an I/O error has occurred.
  29.648 +     */
  29.649 +    public void write(byte[] buf) throws IOException {
  29.650 +        bout.write(buf, 0, buf.length, false);
  29.651 +    }
  29.652 +
  29.653 +    /**
  29.654 +     * Writes a sub array of bytes.
  29.655 +     *
  29.656 +     * @param   buf the data to be written
  29.657 +     * @param   off the start offset in the data
  29.658 +     * @param   len the number of bytes that are written
  29.659 +     * @throws  IOException If an I/O error has occurred.
  29.660 +     */
  29.661 +    public void write(byte[] buf, int off, int len) throws IOException {
  29.662 +        if (buf == null) {
  29.663 +            throw new NullPointerException();
  29.664 +        }
  29.665 +        int endoff = off + len;
  29.666 +        if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) {
  29.667 +            throw new IndexOutOfBoundsException();
  29.668 +        }
  29.669 +        bout.write(buf, off, len, false);
  29.670 +    }
  29.671 +
  29.672 +    /**
  29.673 +     * Flushes the stream. This will write any buffered output bytes and flush
  29.674 +     * through to the underlying stream.
  29.675 +     *
  29.676 +     * @throws  IOException If an I/O error has occurred.
  29.677 +     */
  29.678 +    public void flush() throws IOException {
  29.679 +        bout.flush();
  29.680 +    }
  29.681 +
  29.682 +    /**
  29.683 +     * Drain any buffered data in ObjectOutputStream.  Similar to flush but
  29.684 +     * does not propagate the flush to the underlying stream.
  29.685 +     *
  29.686 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.687 +     *          stream
  29.688 +     */
  29.689 +    protected void drain() throws IOException {
  29.690 +        bout.drain();
  29.691 +    }
  29.692 +
  29.693 +    /**
  29.694 +     * Closes the stream. This method must be called to release any resources
  29.695 +     * associated with the stream.
  29.696 +     *
  29.697 +     * @throws  IOException If an I/O error has occurred.
  29.698 +     */
  29.699 +    public void close() throws IOException {
  29.700 +        flush();
  29.701 +        clear();
  29.702 +        bout.close();
  29.703 +    }
  29.704 +
  29.705 +    /**
  29.706 +     * Writes a boolean.
  29.707 +     *
  29.708 +     * @param   val the boolean to be written
  29.709 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.710 +     *          stream
  29.711 +     */
  29.712 +    public void writeBoolean(boolean val) throws IOException {
  29.713 +        bout.writeBoolean(val);
  29.714 +    }
  29.715 +
  29.716 +    /**
  29.717 +     * Writes an 8 bit byte.
  29.718 +     *
  29.719 +     * @param   val the byte value to be written
  29.720 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.721 +     *          stream
  29.722 +     */
  29.723 +    public void writeByte(int val) throws IOException  {
  29.724 +        bout.writeByte(val);
  29.725 +    }
  29.726 +
  29.727 +    /**
  29.728 +     * Writes a 16 bit short.
  29.729 +     *
  29.730 +     * @param   val the short value to be written
  29.731 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.732 +     *          stream
  29.733 +     */
  29.734 +    public void writeShort(int val)  throws IOException {
  29.735 +        bout.writeShort(val);
  29.736 +    }
  29.737 +
  29.738 +    /**
  29.739 +     * Writes a 16 bit char.
  29.740 +     *
  29.741 +     * @param   val the char value to be written
  29.742 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.743 +     *          stream
  29.744 +     */
  29.745 +    public void writeChar(int val)  throws IOException {
  29.746 +        bout.writeChar(val);
  29.747 +    }
  29.748 +
  29.749 +    /**
  29.750 +     * Writes a 32 bit int.
  29.751 +     *
  29.752 +     * @param   val the integer value to be written
  29.753 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.754 +     *          stream
  29.755 +     */
  29.756 +    public void writeInt(int val)  throws IOException {
  29.757 +        bout.writeInt(val);
  29.758 +    }
  29.759 +
  29.760 +    /**
  29.761 +     * Writes a 64 bit long.
  29.762 +     *
  29.763 +     * @param   val the long value to be written
  29.764 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.765 +     *          stream
  29.766 +     */
  29.767 +    public void writeLong(long val)  throws IOException {
  29.768 +        bout.writeLong(val);
  29.769 +    }
  29.770 +
  29.771 +    /**
  29.772 +     * Writes a 32 bit float.
  29.773 +     *
  29.774 +     * @param   val the float value to be written
  29.775 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.776 +     *          stream
  29.777 +     */
  29.778 +    public void writeFloat(float val) throws IOException {
  29.779 +        bout.writeFloat(val);
  29.780 +    }
  29.781 +
  29.782 +    /**
  29.783 +     * Writes a 64 bit double.
  29.784 +     *
  29.785 +     * @param   val the double value to be written
  29.786 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.787 +     *          stream
  29.788 +     */
  29.789 +    public void writeDouble(double val) throws IOException {
  29.790 +        bout.writeDouble(val);
  29.791 +    }
  29.792 +
  29.793 +    /**
  29.794 +     * Writes a String as a sequence of bytes.
  29.795 +     *
  29.796 +     * @param   str the String of bytes to be written
  29.797 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.798 +     *          stream
  29.799 +     */
  29.800 +    public void writeBytes(String str) throws IOException {
  29.801 +        bout.writeBytes(str);
  29.802 +    }
  29.803 +
  29.804 +    /**
  29.805 +     * Writes a String as a sequence of chars.
  29.806 +     *
  29.807 +     * @param   str the String of chars to be written
  29.808 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.809 +     *          stream
  29.810 +     */
  29.811 +    public void writeChars(String str) throws IOException {
  29.812 +        bout.writeChars(str);
  29.813 +    }
  29.814 +
  29.815 +    /**
  29.816 +     * Primitive data write of this String in
  29.817 +     * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
  29.818 +     * format.  Note that there is a
  29.819 +     * significant difference between writing a String into the stream as
  29.820 +     * primitive data or as an Object. A String instance written by writeObject
  29.821 +     * is written into the stream as a String initially. Future writeObject()
  29.822 +     * calls write references to the string into the stream.
  29.823 +     *
  29.824 +     * @param   str the String to be written
  29.825 +     * @throws  IOException if I/O errors occur while writing to the underlying
  29.826 +     *          stream
  29.827 +     */
  29.828 +    public void writeUTF(String str) throws IOException {
  29.829 +        bout.writeUTF(str);
  29.830 +    }
  29.831 +
  29.832 +    /**
  29.833 +     * Provide programmatic access to the persistent fields to be written
  29.834 +     * to ObjectOutput.
  29.835 +     *
  29.836 +     * @since 1.2
  29.837 +     */
  29.838 +    public static abstract class PutField {
  29.839 +
  29.840 +        /**
  29.841 +         * Put the value of the named boolean field into the persistent field.
  29.842 +         *
  29.843 +         * @param  name the name of the serializable field
  29.844 +         * @param  val the value to assign to the field
  29.845 +         * @throws IllegalArgumentException if <code>name</code> does not
  29.846 +         * match the name of a serializable field for the class whose fields
  29.847 +         * are being written, or if the type of the named field is not
  29.848 +         * <code>boolean</code>
  29.849 +         */
  29.850 +        public abstract void put(String name, boolean val);
  29.851 +
  29.852 +        /**
  29.853 +         * Put the value of the named byte field into the persistent field.
  29.854 +         *
  29.855 +         * @param  name the name of the serializable field
  29.856 +         * @param  val the value to assign to the field
  29.857 +         * @throws IllegalArgumentException if <code>name</code> does not
  29.858 +         * match the name of a serializable field for the class whose fields
  29.859 +         * are being written, or if the type of the named field is not
  29.860 +         * <code>byte</code>
  29.861 +         */
  29.862 +        public abstract void put(String name, byte val);
  29.863 +
  29.864 +        /**
  29.865 +         * Put the value of the named char field into the persistent field.
  29.866 +         *
  29.867 +         * @param  name the name of the serializable field
  29.868 +         * @param  val the value to assign to the field
  29.869 +         * @throws IllegalArgumentException if <code>name</code> does not
  29.870 +         * match the name of a serializable field for the class whose fields
  29.871 +         * are being written, or if the type of the named field is not
  29.872 +         * <code>char</code>
  29.873 +         */
  29.874 +        public abstract void put(String name, char val);
  29.875 +
  29.876 +        /**
  29.877 +         * Put the value of the named short field into the persistent field.
  29.878 +         *
  29.879 +         * @param  name the name of the serializable field
  29.880 +         * @param  val the value to assign to the field
  29.881 +         * @throws IllegalArgumentException if <code>name</code> does not
  29.882 +         * match the name of a serializable field for the class whose fields
  29.883 +         * are being written, or if the type of the named field is not
  29.884 +         * <code>short</code>
  29.885 +         */
  29.886 +        public abstract void put(String name, short val);
  29.887 +
  29.888 +        /**
  29.889 +         * Put the value of the named int field into the persistent field.
  29.890 +         *
  29.891 +         * @param  name the name of the serializable field
  29.892 +         * @param  val the value to assign to the field
  29.893 +         * @throws IllegalArgumentException if <code>name</code> does not
  29.894 +         * match the name of a serializable field for the class whose fields
  29.895 +         * are being written, or if the type of the named field is not
  29.896 +         * <code>int</code>
  29.897 +         */
  29.898 +        public abstract void put(String name, int val);
  29.899 +
  29.900 +        /**
  29.901 +         * Put the value of the named long field into the persistent field.
  29.902 +         *
  29.903 +         * @param  name the name of the serializable field
  29.904 +         * @param  val the value to assign to the field
  29.905 +         * @throws IllegalArgumentException if <code>name</code> does not
  29.906 +         * match the name of a serializable field for the class whose fields
  29.907 +         * are being written, or if the type of the named field is not
  29.908 +         * <code>long</code>
  29.909 +         */
  29.910 +        public abstract void put(String name, long val);
  29.911 +
  29.912 +        /**
  29.913 +         * Put the value of the named float field into the persistent field.
  29.914 +         *
  29.915 +         * @param  name the name of the serializable field
  29.916 +         * @param  val the value to assign to the field
  29.917 +         * @throws IllegalArgumentException if <code>name</code> does not
  29.918 +         * match the name of a serializable field for the class whose fields
  29.919 +         * are being written, or if the type of the named field is not
  29.920 +         * <code>float</code>
  29.921 +         */
  29.922 +        public abstract void put(String name, float val);
  29.923 +
  29.924 +        /**
  29.925 +         * Put the value of the named double field into the persistent field.
  29.926 +         *
  29.927 +         * @param  name the name of the serializable field
  29.928 +         * @param  val the value to assign to the field
  29.929 +         * @throws IllegalArgumentException if <code>name</code> does not
  29.930 +         * match the name of a serializable field for the class whose fields
  29.931 +         * are being written, or if the type of the named field is not
  29.932 +         * <code>double</code>
  29.933 +         */
  29.934 +        public abstract void put(String name, double val);
  29.935 +
  29.936 +        /**
  29.937 +         * Put the value of the named Object field into the persistent field.
  29.938 +         *
  29.939 +         * @param  name the name of the serializable field
  29.940 +         * @param  val the value to assign to the field
  29.941 +         *         (which may be <code>null</code>)
  29.942 +         * @throws IllegalArgumentException if <code>name</code> does not
  29.943 +         * match the name of a serializable field for the class whose fields
  29.944 +         * are being written, or if the type of the named field is not a
  29.945 +         * reference type
  29.946 +         */
  29.947 +        public abstract void put(String name, Object val);
  29.948 +
  29.949 +        /**
  29.950 +         * Write the data and fields to the specified ObjectOutput stream,
  29.951 +         * which must be the same stream that produced this
  29.952 +         * <code>PutField</code> object.
  29.953 +         *
  29.954 +         * @param  out the stream to write the data and fields to
  29.955 +         * @throws IOException if I/O errors occur while writing to the
  29.956 +         *         underlying stream
  29.957 +         * @throws IllegalArgumentException if the specified stream is not
  29.958 +         *         the same stream that produced this <code>PutField</code>
  29.959 +         *         object
  29.960 +         * @deprecated This method does not write the values contained by this
  29.961 +         *         <code>PutField</code> object in a proper format, and may
  29.962 +         *         result in corruption of the serialization stream.  The
  29.963 +         *         correct way to write <code>PutField</code> data is by
  29.964 +         *         calling the {@link java.io.ObjectOutputStream#writeFields()}
  29.965 +         *         method.
  29.966 +         */
  29.967 +        @Deprecated
  29.968 +        public abstract void write(ObjectOutput out) throws IOException;
  29.969 +    }
  29.970 +
  29.971 +
  29.972 +    /**
  29.973 +     * Returns protocol version in use.
  29.974 +     */
  29.975 +    int getProtocolVersion() {
  29.976 +        return protocol;
  29.977 +    }
  29.978 +
  29.979 +    /**
  29.980 +     * Writes string without allowing it to be replaced in stream.  Used by
  29.981 +     * ObjectStreamClass to write class descriptor type strings.
  29.982 +     */
  29.983 +    void writeTypeString(String str) throws IOException {
  29.984 +        int handle;
  29.985 +        if (str == null) {
  29.986 +            writeNull();
  29.987 +        } else if ((handle = handles.lookup(str)) != -1) {
  29.988 +            writeHandle(handle);
  29.989 +        } else {
  29.990 +            writeString(str, false);
  29.991 +        }
  29.992 +    }
  29.993 +
  29.994 +    /**
  29.995 +     * Verifies that this (possibly subclass) instance can be constructed
  29.996 +     * without violating security constraints: the subclass must not override
  29.997 +     * security-sensitive non-final methods, or else the
  29.998 +     * "enableSubclassImplementation" SerializablePermission is checked.
  29.999 +     */
 29.1000 +    private void verifySubclass() {
 29.1001 +        Class cl = getClass();
 29.1002 +        if (cl == ObjectOutputStream.class) {
 29.1003 +            return;
 29.1004 +        }
 29.1005 +        throw new SecurityException();
 29.1006 +    }
 29.1007 +
 29.1008 +    /**
 29.1009 +     * Clears internal data structures.
 29.1010 +     */
 29.1011 +    private void clear() {
 29.1012 +        subs.clear();
 29.1013 +        handles.clear();
 29.1014 +    }
 29.1015 +
 29.1016 +    /**
 29.1017 +     * Underlying writeObject/writeUnshared implementation.
 29.1018 +     */
 29.1019 +    private void writeObject0(Object obj, boolean unshared)
 29.1020 +        throws IOException
 29.1021 +    {
 29.1022 +        boolean oldMode = bout.setBlockDataMode(false);
 29.1023 +        depth++;
 29.1024 +        try {
 29.1025 +            // handle previously written and non-replaceable objects
 29.1026 +            int h;
 29.1027 +            if ((obj = subs.lookup(obj)) == null) {
 29.1028 +                writeNull();
 29.1029 +                return;
 29.1030 +            } else if (!unshared && (h = handles.lookup(obj)) != -1) {
 29.1031 +                writeHandle(h);
 29.1032 +                return;
 29.1033 +            } else if (obj instanceof Class) {
 29.1034 +                writeClass((Class) obj, unshared);
 29.1035 +                return;
 29.1036 +            } else if (obj instanceof ObjectStreamClass) {
 29.1037 +                writeClassDesc((ObjectStreamClass) obj, unshared);
 29.1038 +                return;
 29.1039 +            }
 29.1040 +
 29.1041 +            // check for replacement object
 29.1042 +            Object orig = obj;
 29.1043 +            Class cl = obj.getClass();
 29.1044 +            ObjectStreamClass desc;
 29.1045 +            for (;;) {
 29.1046 +                // REMIND: skip this check for strings/arrays?
 29.1047 +                Class repCl;
 29.1048 +                desc = ObjectStreamClass.lookup(cl, true);
 29.1049 +                if (!desc.hasWriteReplaceMethod() ||
 29.1050 +                    (obj = desc.invokeWriteReplace(obj)) == null ||
 29.1051 +                    (repCl = obj.getClass()) == cl)
 29.1052 +                {
 29.1053 +                    break;
 29.1054 +                }
 29.1055 +                cl = repCl;
 29.1056 +            }
 29.1057 +            if (enableReplace) {
 29.1058 +                Object rep = replaceObject(obj);
 29.1059 +                if (rep != obj && rep != null) {
 29.1060 +                    cl = rep.getClass();
 29.1061 +                    desc = ObjectStreamClass.lookup(cl, true);
 29.1062 +                }
 29.1063 +                obj = rep;
 29.1064 +            }
 29.1065 +
 29.1066 +            // if object replaced, run through original checks a second time
 29.1067 +            if (obj != orig) {
 29.1068 +                subs.assign(orig, obj);
 29.1069 +                if (obj == null) {
 29.1070 +                    writeNull();
 29.1071 +                    return;
 29.1072 +                } else if (!unshared && (h = handles.lookup(obj)) != -1) {
 29.1073 +                    writeHandle(h);
 29.1074 +                    return;
 29.1075 +                } else if (obj instanceof Class) {
 29.1076 +                    writeClass((Class) obj, unshared);
 29.1077 +                    return;
 29.1078 +                } else if (obj instanceof ObjectStreamClass) {
 29.1079 +                    writeClassDesc((ObjectStreamClass) obj, unshared);
 29.1080 +                    return;
 29.1081 +                }
 29.1082 +            }
 29.1083 +
 29.1084 +            // remaining cases
 29.1085 +            if (obj instanceof String) {
 29.1086 +                writeString((String) obj, unshared);
 29.1087 +            } else if (cl.isArray()) {
 29.1088 +                writeArray(obj, desc, unshared);
 29.1089 +            } else if (obj instanceof Enum) {
 29.1090 +                writeEnum((Enum) obj, desc, unshared);
 29.1091 +            } else if (obj instanceof Serializable) {
 29.1092 +                writeOrdinaryObject(obj, desc, unshared);
 29.1093 +            } else {
 29.1094 +                if (extendedDebugInfo) {
 29.1095 +                    throw new NotSerializableException(
 29.1096 +                        cl.getName() + "\n" + debugInfoStack.toString());
 29.1097 +                } else {
 29.1098 +                    throw new NotSerializableException(cl.getName());
 29.1099 +                }
 29.1100 +            }
 29.1101 +        } finally {
 29.1102 +            depth--;
 29.1103 +            bout.setBlockDataMode(oldMode);
 29.1104 +        }
 29.1105 +    }
 29.1106 +
 29.1107 +    /**
 29.1108 +     * Writes null code to stream.
 29.1109 +     */
 29.1110 +    private void writeNull() throws IOException {
 29.1111 +        bout.writeByte(TC_NULL);
 29.1112 +    }
 29.1113 +
 29.1114 +    /**
 29.1115 +     * Writes given object handle to stream.
 29.1116 +     */
 29.1117 +    private void writeHandle(int handle) throws IOException {
 29.1118 +        bout.writeByte(TC_REFERENCE);
 29.1119 +        bout.writeInt(baseWireHandle + handle);
 29.1120 +    }
 29.1121 +
 29.1122 +    /**
 29.1123 +     * Writes representation of given class to stream.
 29.1124 +     */
 29.1125 +    private void writeClass(Class cl, boolean unshared) throws IOException {
 29.1126 +        bout.writeByte(TC_CLASS);
 29.1127 +        writeClassDesc(ObjectStreamClass.lookup(cl, true), false);
 29.1128 +        handles.assign(unshared ? null : cl);
 29.1129 +    }
 29.1130 +
 29.1131 +    /**
 29.1132 +     * Writes representation of given class descriptor to stream.
 29.1133 +     */
 29.1134 +    private void writeClassDesc(ObjectStreamClass desc, boolean unshared)
 29.1135 +        throws IOException
 29.1136 +    {
 29.1137 +        int handle;
 29.1138 +        if (desc == null) {
 29.1139 +            writeNull();
 29.1140 +        } else if (!unshared && (handle = handles.lookup(desc)) != -1) {
 29.1141 +            writeHandle(handle);
 29.1142 +        } else if (desc.isProxy()) {
 29.1143 +            writeProxyDesc(desc, unshared);
 29.1144 +        } else {
 29.1145 +            writeNonProxyDesc(desc, unshared);
 29.1146 +        }
 29.1147 +    }
 29.1148 +
 29.1149 +    /**
 29.1150 +     * Writes class descriptor representing a dynamic proxy class to stream.
 29.1151 +     */
 29.1152 +    private void writeProxyDesc(ObjectStreamClass desc, boolean unshared)
 29.1153 +        throws IOException
 29.1154 +    {
 29.1155 +        bout.writeByte(TC_PROXYCLASSDESC);
 29.1156 +        handles.assign(unshared ? null : desc);
 29.1157 +
 29.1158 +        Class cl = desc.forClass();
 29.1159 +        Class[] ifaces = cl.getInterfaces();
 29.1160 +        bout.writeInt(ifaces.length);
 29.1161 +        for (int i = 0; i < ifaces.length; i++) {
 29.1162 +            bout.writeUTF(ifaces[i].getName());
 29.1163 +        }
 29.1164 +
 29.1165 +        bout.setBlockDataMode(true);
 29.1166 +        annotateProxyClass(cl);
 29.1167 +        bout.setBlockDataMode(false);
 29.1168 +        bout.writeByte(TC_ENDBLOCKDATA);
 29.1169 +
 29.1170 +        writeClassDesc(desc.getSuperDesc(), false);
 29.1171 +    }
 29.1172 +
 29.1173 +    /**
 29.1174 +     * Writes class descriptor representing a standard (i.e., not a dynamic
 29.1175 +     * proxy) class to stream.
 29.1176 +     */
 29.1177 +    private void writeNonProxyDesc(ObjectStreamClass desc, boolean unshared)
 29.1178 +        throws IOException
 29.1179 +    {
 29.1180 +        bout.writeByte(TC_CLASSDESC);
 29.1181 +        handles.assign(unshared ? null : desc);
 29.1182 +
 29.1183 +        if (protocol == PROTOCOL_VERSION_1) {
 29.1184 +            // do not invoke class descriptor write hook with old protocol
 29.1185 +            desc.writeNonProxy(this);
 29.1186 +        } else {
 29.1187 +            writeClassDescriptor(desc);
 29.1188 +        }
 29.1189 +
 29.1190 +        Class cl = desc.forClass();
 29.1191 +        bout.setBlockDataMode(true);
 29.1192 +        annotateClass(cl);
 29.1193 +        bout.setBlockDataMode(false);
 29.1194 +        bout.writeByte(TC_ENDBLOCKDATA);
 29.1195 +
 29.1196 +        writeClassDesc(desc.getSuperDesc(), false);
 29.1197 +    }
 29.1198 +
 29.1199 +    /**
 29.1200 +     * Writes given string to stream, using standard or long UTF format
 29.1201 +     * depending on string length.
 29.1202 +     */
 29.1203 +    private void writeString(String str, boolean unshared) throws IOException {
 29.1204 +        handles.assign(unshared ? null : str);
 29.1205 +        long utflen = bout.getUTFLength(str);
 29.1206 +        if (utflen <= 0xFFFF) {
 29.1207 +            bout.writeByte(TC_STRING);
 29.1208 +            bout.writeUTF(str, utflen);
 29.1209 +        } else {
 29.1210 +            bout.writeByte(TC_LONGSTRING);
 29.1211 +            bout.writeLongUTF(str, utflen);
 29.1212 +        }
 29.1213 +    }
 29.1214 +
 29.1215 +    /**
 29.1216 +     * Writes given array object to stream.
 29.1217 +     */
 29.1218 +    private void writeArray(Object array,
 29.1219 +                            ObjectStreamClass desc,
 29.1220 +                            boolean unshared)
 29.1221 +        throws IOException
 29.1222 +    {
 29.1223 +        bout.writeByte(TC_ARRAY);
 29.1224 +        writeClassDesc(desc, false);
 29.1225 +        handles.assign(unshared ? null : array);
 29.1226 +
 29.1227 +        Class ccl = desc.forClass().getComponentType();
 29.1228 +        if (ccl.isPrimitive()) {
 29.1229 +            if (ccl == Integer.TYPE) {
 29.1230 +                int[] ia = (int[]) array;
 29.1231 +                bout.writeInt(ia.length);
 29.1232 +                bout.writeInts(ia, 0, ia.length);
 29.1233 +            } else if (ccl == Byte.TYPE) {
 29.1234 +                byte[] ba = (byte[]) array;
 29.1235 +                bout.writeInt(ba.length);
 29.1236 +                bout.write(ba, 0, ba.length, true);
 29.1237 +            } else if (ccl == Long.TYPE) {
 29.1238 +                long[] ja = (long[]) array;
 29.1239 +                bout.writeInt(ja.length);
 29.1240 +                bout.writeLongs(ja, 0, ja.length);
 29.1241 +            } else if (ccl == Float.TYPE) {
 29.1242 +                float[] fa = (float[]) array;
 29.1243 +                bout.writeInt(fa.length);
 29.1244 +                bout.writeFloats(fa, 0, fa.length);
 29.1245 +            } else if (ccl == Double.TYPE) {
 29.1246 +                double[] da = (double[]) array;
 29.1247 +                bout.writeInt(da.length);
 29.1248 +                bout.writeDoubles(da, 0, da.length);
 29.1249 +            } else if (ccl == Short.TYPE) {
 29.1250 +                short[] sa = (short[]) array;
 29.1251 +                bout.writeInt(sa.length);
 29.1252 +                bout.writeShorts(sa, 0, sa.length);
 29.1253 +            } else if (ccl == Character.TYPE) {
 29.1254 +                char[] ca = (char[]) array;
 29.1255 +                bout.writeInt(ca.length);
 29.1256 +                bout.writeChars(ca, 0, ca.length);
 29.1257 +            } else if (ccl == Boolean.TYPE) {
 29.1258 +                boolean[] za = (boolean[]) array;
 29.1259 +                bout.writeInt(za.length);
 29.1260 +                bout.writeBooleans(za, 0, za.length);
 29.1261 +            } else {
 29.1262 +                throw new InternalError();
 29.1263 +            }
 29.1264 +        } else {
 29.1265 +            Object[] objs = (Object[]) array;
 29.1266 +            int len = objs.length;
 29.1267 +            bout.writeInt(len);
 29.1268 +            if (extendedDebugInfo) {
 29.1269 +                debugInfoStack.push(
 29.1270 +                    "array (class \"" + array.getClass().getName() +
 29.1271 +                    "\", size: " + len  + ")");
 29.1272 +            }
 29.1273 +            try {
 29.1274 +                for (int i = 0; i < len; i++) {
 29.1275 +                    if (extendedDebugInfo) {
 29.1276 +                        debugInfoStack.push(
 29.1277 +                            "element of array (index: " + i + ")");
 29.1278 +                    }
 29.1279 +                    try {
 29.1280 +                        writeObject0(objs[i], false);
 29.1281 +                    } finally {
 29.1282 +                        if (extendedDebugInfo) {
 29.1283 +                            debugInfoStack.pop();
 29.1284 +                        }
 29.1285 +                    }
 29.1286 +                }
 29.1287 +            } finally {
 29.1288 +                if (extendedDebugInfo) {
 29.1289 +                    debugInfoStack.pop();
 29.1290 +                }
 29.1291 +            }
 29.1292 +        }
 29.1293 +    }
 29.1294 +
 29.1295 +    /**
 29.1296 +     * Writes given enum constant to stream.
 29.1297 +     */
 29.1298 +    private void writeEnum(Enum en,
 29.1299 +                           ObjectStreamClass desc,
 29.1300 +                           boolean unshared)
 29.1301 +        throws IOException
 29.1302 +    {
 29.1303 +        bout.writeByte(TC_ENUM);
 29.1304 +        ObjectStreamClass sdesc = desc.getSuperDesc();
 29.1305 +        writeClassDesc((sdesc.forClass() == Enum.class) ? desc : sdesc, false);
 29.1306 +        handles.assign(unshared ? null : en);
 29.1307 +        writeString(en.name(), false);
 29.1308 +    }
 29.1309 +
 29.1310 +    /**
 29.1311 +     * Writes representation of a "ordinary" (i.e., not a String, Class,
 29.1312 +     * ObjectStreamClass, array, or enum constant) serializable object to the
 29.1313 +     * stream.
 29.1314 +     */
 29.1315 +    private void writeOrdinaryObject(Object obj,
 29.1316 +                                     ObjectStreamClass desc,
 29.1317 +                                     boolean unshared)
 29.1318 +        throws IOException
 29.1319 +    {
 29.1320 +        if (extendedDebugInfo) {
 29.1321 +            debugInfoStack.push(
 29.1322 +                (depth == 1 ? "root " : "") + "object (class \"" +
 29.1323 +                obj.getClass().getName() + "\", " + obj.toString() + ")");
 29.1324 +        }
 29.1325 +        try {
 29.1326 +            desc.checkSerialize();
 29.1327 +
 29.1328 +            bout.writeByte(TC_OBJECT);
 29.1329 +            writeClassDesc(desc, false);
 29.1330 +            handles.assign(unshared ? null : obj);
 29.1331 +            if (desc.isExternalizable() && !desc.isProxy()) {
 29.1332 +                writeExternalData((Externalizable) obj);
 29.1333 +            } else {
 29.1334 +                writeSerialData(obj, desc);
 29.1335 +            }
 29.1336 +        } finally {
 29.1337 +            if (extendedDebugInfo) {
 29.1338 +                debugInfoStack.pop();
 29.1339 +            }
 29.1340 +        }
 29.1341 +    }
 29.1342 +
 29.1343 +    /**
 29.1344 +     * Writes externalizable data of given object by invoking its
 29.1345 +     * writeExternal() method.
 29.1346 +     */
 29.1347 +    private void writeExternalData(Externalizable obj) throws IOException {
 29.1348 +        PutFieldImpl oldPut = curPut;
 29.1349 +        curPut = null;
 29.1350 +
 29.1351 +        if (extendedDebugInfo) {
 29.1352 +            debugInfoStack.push("writeExternal data");
 29.1353 +        }
 29.1354 +        Object oldContext = curContext;
 29.1355 +        try {
 29.1356 +            curContext = null;
 29.1357 +            if (protocol == PROTOCOL_VERSION_1) {
 29.1358 +                obj.writeExternal(this);
 29.1359 +            } else {
 29.1360 +                bout.setBlockDataMode(true);
 29.1361 +                obj.writeExternal(this);
 29.1362 +                bout.setBlockDataMode(false);
 29.1363 +                bout.writeByte(TC_ENDBLOCKDATA);
 29.1364 +            }
 29.1365 +        } finally {
 29.1366 +            curContext = oldContext;
 29.1367 +            if (extendedDebugInfo) {
 29.1368 +                debugInfoStack.pop();
 29.1369 +            }
 29.1370 +        }
 29.1371 +
 29.1372 +        curPut = oldPut;
 29.1373 +    }
 29.1374 +
 29.1375 +    /**
 29.1376 +     * Writes instance data for each serializable class of given object, from
 29.1377 +     * superclass to subclass.
 29.1378 +     */
 29.1379 +    private void writeSerialData(Object obj, ObjectStreamClass desc)
 29.1380 +        throws IOException
 29.1381 +    {
 29.1382 +        ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
 29.1383 +        for (int i = 0; i < slots.length; i++) {
 29.1384 +            ObjectStreamClass slotDesc = slots[i].desc;
 29.1385 +            if (slotDesc.hasWriteObjectMethod()) {
 29.1386 +                PutFieldImpl oldPut = curPut;
 29.1387 +                curPut = null;
 29.1388 +                Object oldContext = curContext;
 29.1389 +
 29.1390 +                if (extendedDebugInfo) {
 29.1391 +                    debugInfoStack.push(
 29.1392 +                        "custom writeObject data (class \"" +
 29.1393 +                        slotDesc.getName() + "\")");
 29.1394 +                }
 29.1395 +                try {
 29.1396 +                    curContext = new Object(); //new SerialCallbackContext(obj, slotDesc);
 29.1397 +                    bout.setBlockDataMode(true);
 29.1398 +                    slotDesc.invokeWriteObject(obj, this);
 29.1399 +                    bout.setBlockDataMode(false);
 29.1400 +                    bout.writeByte(TC_ENDBLOCKDATA);
 29.1401 +                } finally {
 29.1402 +                    //curContext.setUsed();
 29.1403 +                    curContext = oldContext;
 29.1404 +                    if (extendedDebugInfo) {
 29.1405 +                        debugInfoStack.pop();
 29.1406 +                    }
 29.1407 +                }
 29.1408 +
 29.1409 +                curPut = oldPut;
 29.1410 +            } else {
 29.1411 +                defaultWriteFields(obj, slotDesc);
 29.1412 +            }
 29.1413 +        }
 29.1414 +    }
 29.1415 +
 29.1416 +    /**
 29.1417 +     * Fetches and writes values of serializable fields of given object to
 29.1418 +     * stream.  The given class descriptor specifies which field values to
 29.1419 +     * write, and in which order they should be written.
 29.1420 +     */
 29.1421 +    private void defaultWriteFields(Object obj, ObjectStreamClass desc)
 29.1422 +        throws IOException
 29.1423 +    {
 29.1424 +        // REMIND: perform conservative isInstance check here?
 29.1425 +        desc.checkDefaultSerialize();
 29.1426 +
 29.1427 +        int primDataSize = desc.getPrimDataSize();
 29.1428 +        if (primVals == null || primVals.length < primDataSize) {
 29.1429 +            primVals = new byte[primDataSize];
 29.1430 +        }
 29.1431 +        desc.getPrimFieldValues(obj, primVals);
 29.1432 +        bout.write(primVals, 0, primDataSize, false);
 29.1433 +
 29.1434 +        ObjectStreamField[] fields = desc.getFields(false);
 29.1435 +        Object[] objVals = new Object[desc.getNumObjFields()];
 29.1436 +        int numPrimFields = fields.length - objVals.length;
 29.1437 +        desc.getObjFieldValues(obj, objVals);
 29.1438 +        for (int i = 0; i < objVals.length; i++) {
 29.1439 +            if (extendedDebugInfo) {
 29.1440 +                debugInfoStack.push(
 29.1441 +                    "field (class \"" + desc.getName() + "\", name: \"" +
 29.1442 +                    fields[numPrimFields + i].getName() + "\", type: \"" +
 29.1443 +                    fields[numPrimFields + i].getType() + "\")");
 29.1444 +            }
 29.1445 +            try {
 29.1446 +                writeObject0(objVals[i],
 29.1447 +                             fields[numPrimFields + i].isUnshared());
 29.1448 +            } finally {
 29.1449 +                if (extendedDebugInfo) {
 29.1450 +                    debugInfoStack.pop();
 29.1451 +                }
 29.1452 +            }
 29.1453 +        }
 29.1454 +    }
 29.1455 +
 29.1456 +    /**
 29.1457 +     * Attempts to write to stream fatal IOException that has caused
 29.1458 +     * serialization to abort.
 29.1459 +     */
 29.1460 +    private void writeFatalException(IOException ex) throws IOException {
 29.1461 +        /*
 29.1462 +         * Note: the serialization specification states that if a second
 29.1463 +         * IOException occurs while attempting to serialize the original fatal
 29.1464 +         * exception to the stream, then a StreamCorruptedException should be
 29.1465 +         * thrown (section 2.1).  However, due to a bug in previous
 29.1466 +         * implementations of serialization, StreamCorruptedExceptions were
 29.1467 +         * rarely (if ever) actually thrown--the "root" exceptions from
 29.1468 +         * underlying streams were thrown instead.  This historical behavior is
 29.1469 +         * followed here for consistency.
 29.1470 +         */
 29.1471 +        clear();
 29.1472 +        boolean oldMode = bout.setBlockDataMode(false);
 29.1473 +        try {
 29.1474 +            bout.writeByte(TC_EXCEPTION);
 29.1475 +            writeObject0(ex, false);
 29.1476 +            clear();
 29.1477 +        } finally {
 29.1478 +            bout.setBlockDataMode(oldMode);
 29.1479 +        }
 29.1480 +    }
 29.1481 +
 29.1482 +    /**
 29.1483 +     * Converts specified span of float values into byte values.
 29.1484 +     */
 29.1485 +    // REMIND: remove once hotspot inlines Float.floatToIntBits
 29.1486 +    private static native void floatsToBytes(float[] src, int srcpos,
 29.1487 +                                             byte[] dst, int dstpos,
 29.1488 +                                             int nfloats);
 29.1489 +
 29.1490 +    /**
 29.1491 +     * Converts specified span of double values into byte values.
 29.1492 +     */
 29.1493 +    // REMIND: remove once hotspot inlines Double.doubleToLongBits
 29.1494 +    private static native void doublesToBytes(double[] src, int srcpos,
 29.1495 +                                              byte[] dst, int dstpos,
 29.1496 +                                              int ndoubles);
 29.1497 +
 29.1498 +    /**
 29.1499 +     * Default PutField implementation.
 29.1500 +     */
 29.1501 +    private class PutFieldImpl extends PutField {
 29.1502 +
 29.1503 +        /** class descriptor describing serializable fields */
 29.1504 +        private final ObjectStreamClass desc;
 29.1505 +        /** primitive field values */
 29.1506 +        private final byte[] primVals;
 29.1507 +        /** object field values */
 29.1508 +        private final Object[] objVals;
 29.1509 +
 29.1510 +        /**
 29.1511 +         * Creates PutFieldImpl object for writing fields defined in given
 29.1512 +         * class descriptor.
 29.1513 +         */
 29.1514 +        PutFieldImpl(ObjectStreamClass desc) {
 29.1515 +            this.desc = desc;
 29.1516 +            primVals = new byte[desc.getPrimDataSize()];
 29.1517 +            objVals = new Object[desc.getNumObjFields()];
 29.1518 +        }
 29.1519 +
 29.1520 +        public void put(String name, boolean val) {
 29.1521 +            Bits.putBoolean(primVals, getFieldOffset(name, Boolean.TYPE), val);
 29.1522 +        }
 29.1523 +
 29.1524 +        public void put(String name, byte val) {
 29.1525 +            primVals[getFieldOffset(name, Byte.TYPE)] = val;
 29.1526 +        }
 29.1527 +
 29.1528 +        public void put(String name, char val) {
 29.1529 +            Bits.putChar(primVals, getFieldOffset(name, Character.TYPE), val);
 29.1530 +        }
 29.1531 +
 29.1532 +        public void put(String name, short val) {
 29.1533 +            Bits.putShort(primVals, getFieldOffset(name, Short.TYPE), val);
 29.1534 +        }
 29.1535 +
 29.1536 +        public void put(String name, int val) {
 29.1537 +            Bits.putInt(primVals, getFieldOffset(name, Integer.TYPE), val);
 29.1538 +        }
 29.1539 +
 29.1540 +        public void put(String name, float val) {
 29.1541 +            Bits.putFloat(primVals, getFieldOffset(name, Float.TYPE), val);
 29.1542 +        }
 29.1543 +
 29.1544 +        public void put(String name, long val) {
 29.1545 +            Bits.putLong(primVals, getFieldOffset(name, Long.TYPE), val);
 29.1546 +        }
 29.1547 +
 29.1548 +        public void put(String name, double val) {
 29.1549 +            Bits.putDouble(primVals, getFieldOffset(name, Double.TYPE), val);
 29.1550 +        }
 29.1551 +
 29.1552 +        public void put(String name, Object val) {
 29.1553 +            objVals[getFieldOffset(name, Object.class)] = val;
 29.1554 +        }
 29.1555 +
 29.1556 +        // deprecated in ObjectOutputStream.PutField
 29.1557 +        public void write(ObjectOutput out) throws IOException {
 29.1558 +            /*
 29.1559 +             * Applications should *not* use this method to write PutField
 29.1560 +             * data, as it will lead to stream corruption if the PutField
 29.1561 +             * object writes any primitive data (since block data mode is not
 29.1562 +             * unset/set properly, as is done in OOS.writeFields()).  This
 29.1563 +             * broken implementation is being retained solely for behavioral
 29.1564 +             * compatibility, in order to support applications which use
 29.1565 +             * OOS.PutField.write() for writing only non-primitive data.
 29.1566 +             *
 29.1567 +             * Serialization of unshared objects is not implemented here since
 29.1568 +             * it is not necessary for backwards compatibility; also, unshared
 29.1569 +             * semantics may not be supported by the given ObjectOutput
 29.1570 +             * instance.  Applications which write unshared objects using the
 29.1571 +             * PutField API must use OOS.writeFields().
 29.1572 +             */
 29.1573 +            if (ObjectOutputStream.this != out) {
 29.1574 +                throw new IllegalArgumentException("wrong stream");
 29.1575 +            }
 29.1576 +            out.write(primVals, 0, primVals.length);
 29.1577 +
 29.1578 +            ObjectStreamField[] fields = desc.getFields(false);
 29.1579 +            int numPrimFields = fields.length - objVals.length;
 29.1580 +            // REMIND: warn if numPrimFields > 0?
 29.1581 +            for (int i = 0; i < objVals.length; i++) {
 29.1582 +                if (fields[numPrimFields + i].isUnshared()) {
 29.1583 +                    throw new IOException("cannot write unshared object");
 29.1584 +                }
 29.1585 +                out.writeObject(objVals[i]);
 29.1586 +            }
 29.1587 +        }
 29.1588 +
 29.1589 +        /**
 29.1590 +         * Writes buffered primitive data and object fields to stream.
 29.1591 +         */
 29.1592 +        void writeFields() throws IOException {
 29.1593 +            bout.write(primVals, 0, primVals.length, false);
 29.1594 +
 29.1595 +            ObjectStreamField[] fields = desc.getFields(false);
 29.1596 +            int numPrimFields = fields.length - objVals.length;
 29.1597 +            for (int i = 0; i < objVals.length; i++) {
 29.1598 +                if (extendedDebugInfo) {
 29.1599 +                    debugInfoStack.push(
 29.1600 +                        "field (class \"" + desc.getName() + "\", name: \"" +
 29.1601 +                        fields[numPrimFields + i].getName() + "\", type: \"" +
 29.1602 +                        fields[numPrimFields + i].getType() + "\")");
 29.1603 +                }
 29.1604 +                try {
 29.1605 +                    writeObject0(objVals[i],
 29.1606 +                                 fields[numPrimFields + i].isUnshared());
 29.1607 +                } finally {
 29.1608 +                    if (extendedDebugInfo) {
 29.1609 +                        debugInfoStack.pop();
 29.1610 +                    }
 29.1611 +                }
 29.1612 +            }
 29.1613 +        }
 29.1614 +
 29.1615 +        /**
 29.1616 +         * Returns offset of field with given name and type.  A specified type
 29.1617 +         * of null matches all types, Object.class matches all non-primitive
 29.1618 +         * types, and any other non-null type matches assignable types only.
 29.1619 +         * Throws IllegalArgumentException if no matching field found.
 29.1620 +         */
 29.1621 +        private int getFieldOffset(String name, Class type) {
 29.1622 +            ObjectStreamField field = desc.getField(name, type);
 29.1623 +            if (field == null) {
 29.1624 +                throw new IllegalArgumentException("no such field " + name +
 29.1625 +                                                   " with type " + type);
 29.1626 +            }
 29.1627 +            return field.getOffset();
 29.1628 +        }
 29.1629 +    }
 29.1630 +
 29.1631 +    /**
 29.1632 +     * Buffered output stream with two modes: in default mode, outputs data in
 29.1633 +     * same format as DataOutputStream; in "block data" mode, outputs data
 29.1634 +     * bracketed by block data markers (see object serialization specification
 29.1635 +     * for details).
 29.1636 +     */
 29.1637 +    private static class BlockDataOutputStream
 29.1638 +        extends OutputStream implements DataOutput
 29.1639 +    {
 29.1640 +        /** maximum data block length */
 29.1641 +        private static final int MAX_BLOCK_SIZE = 1024;
 29.1642 +        /** maximum data block header length */
 29.1643 +        private static final int MAX_HEADER_SIZE = 5;
 29.1644 +        /** (tunable) length of char buffer (for writing strings) */
 29.1645 +        private static final int CHAR_BUF_SIZE = 256;
 29.1646 +
 29.1647 +        /** buffer for writing general/block data */
 29.1648 +        private final byte[] buf = new byte[MAX_BLOCK_SIZE];
 29.1649 +        /** buffer for writing block data headers */
 29.1650 +        private final byte[] hbuf = new byte[MAX_HEADER_SIZE];
 29.1651 +        /** char buffer for fast string writes */
 29.1652 +        private final char[] cbuf = new char[CHAR_BUF_SIZE];
 29.1653 +
 29.1654 +        /** block data mode */
 29.1655 +        private boolean blkmode = false;
 29.1656 +        /** current offset into buf */
 29.1657 +        private int pos = 0;
 29.1658 +
 29.1659 +        /** underlying output stream */
 29.1660 +        private final OutputStream out;
 29.1661 +        /** loopback stream (for data writes that span data blocks) */
 29.1662 +        private final DataOutputStream dout;
 29.1663 +
 29.1664 +        /**
 29.1665 +         * Creates new BlockDataOutputStream on top of given underlying stream.
 29.1666 +         * Block data mode is turned off by default.
 29.1667 +         */
 29.1668 +        BlockDataOutputStream(OutputStream out) {
 29.1669 +            this.out = out;
 29.1670 +            dout = new DataOutputStream(this);
 29.1671 +        }
 29.1672 +
 29.1673 +        /**
 29.1674 +         * Sets block data mode to the given mode (true == on, false == off)
 29.1675 +         * and returns the previous mode value.  If the new mode is the same as
 29.1676 +         * the old mode, no action is taken.  If the new mode differs from the
 29.1677 +         * old mode, any buffered data is flushed before switching to the new
 29.1678 +         * mode.
 29.1679 +         */
 29.1680 +        boolean setBlockDataMode(boolean mode) throws IOException {
 29.1681 +            if (blkmode == mode) {
 29.1682 +                return blkmode;
 29.1683 +            }
 29.1684 +            drain();
 29.1685 +            blkmode = mode;
 29.1686 +            return !blkmode;
 29.1687 +        }
 29.1688 +
 29.1689 +        /**
 29.1690 +         * Returns true if the stream is currently in block data mode, false
 29.1691 +         * otherwise.
 29.1692 +         */
 29.1693 +        boolean getBlockDataMode() {
 29.1694 +            return blkmode;
 29.1695 +        }
 29.1696 +
 29.1697 +        /* ----------------- generic output stream methods ----------------- */
 29.1698 +        /*
 29.1699 +         * The following methods are equivalent to their counterparts in
 29.1700 +         * OutputStream, except that they partition written data into data
 29.1701 +         * blocks when in block data mode.
 29.1702 +         */
 29.1703 +
 29.1704 +        public void write(int b) throws IOException {
 29.1705 +            if (pos >= MAX_BLOCK_SIZE) {
 29.1706 +                drain();
 29.1707 +            }
 29.1708 +            buf[pos++] = (byte) b;
 29.1709 +        }
 29.1710 +
 29.1711 +        public void write(byte[] b) throws IOException {
 29.1712 +            write(b, 0, b.length, false);
 29.1713 +        }
 29.1714 +
 29.1715 +        public void write(byte[] b, int off, int len) throws IOException {
 29.1716 +            write(b, off, len, false);
 29.1717 +        }
 29.1718 +
 29.1719 +        public void flush() throws IOException {
 29.1720 +            drain();
 29.1721 +            out.flush();
 29.1722 +        }
 29.1723 +
 29.1724 +        public void close() throws IOException {
 29.1725 +            flush();
 29.1726 +            out.close();
 29.1727 +        }
 29.1728 +
 29.1729 +        /**
 29.1730 +         * Writes specified span of byte values from given array.  If copy is
 29.1731 +         * true, copies the values to an intermediate buffer before writing
 29.1732 +         * them to underlying stream (to avoid exposing a reference to the
 29.1733 +         * original byte array).
 29.1734 +         */
 29.1735 +        void write(byte[] b, int off, int len, boolean copy)
 29.1736 +            throws IOException
 29.1737 +        {
 29.1738 +            if (!(copy || blkmode)) {           // write directly
 29.1739 +                drain();
 29.1740 +                out.write(b, off, len);
 29.1741 +                return;
 29.1742 +            }
 29.1743 +
 29.1744 +            while (len > 0) {
 29.1745 +                if (pos >= MAX_BLOCK_SIZE) {
 29.1746 +                    drain();
 29.1747 +                }
 29.1748 +                if (len >= MAX_BLOCK_SIZE && !copy && pos == 0) {
 29.1749 +                    // avoid unnecessary copy
 29.1750 +                    writeBlockHeader(MAX_BLOCK_SIZE);
 29.1751 +                    out.write(b, off, MAX_BLOCK_SIZE);
 29.1752 +                    off += MAX_BLOCK_SIZE;
 29.1753 +                    len -= MAX_BLOCK_SIZE;
 29.1754 +                } else {
 29.1755 +                    int wlen = Math.min(len, MAX_BLOCK_SIZE - pos);
 29.1756 +                    System.arraycopy(b, off, buf, pos, wlen);
 29.1757 +                    pos += wlen;
 29.1758 +                    off += wlen;
 29.1759 +                    len -= wlen;
 29.1760 +                }
 29.1761 +            }
 29.1762 +        }
 29.1763 +
 29.1764 +        /**
 29.1765 +         * Writes all buffered data from this stream to the underlying stream,
 29.1766 +         * but does not flush underlying stream.
 29.1767 +         */
 29.1768 +        void drain() throws IOException {
 29.1769 +            if (pos == 0) {
 29.1770 +                return;
 29.1771 +            }
 29.1772 +            if (blkmode) {
 29.1773 +                writeBlockHeader(pos);
 29.1774 +            }
 29.1775 +            out.write(buf, 0, pos);
 29.1776 +            pos = 0;
 29.1777 +        }
 29.1778 +
 29.1779 +        /**
 29.1780 +         * Writes block data header.  Data blocks shorter than 256 bytes are
 29.1781 +         * prefixed with a 2-byte header; all others start with a 5-byte
 29.1782 +         * header.
 29.1783 +         */
 29.1784 +        private void writeBlockHeader(int len) throws IOException {
 29.1785 +            if (len <= 0xFF) {
 29.1786 +                hbuf[0] = TC_BLOCKDATA;
 29.1787 +                hbuf[1] = (byte) len;
 29.1788 +                out.write(hbuf, 0, 2);
 29.1789 +            } else {
 29.1790 +                hbuf[0] = TC_BLOCKDATALONG;
 29.1791 +                Bits.putInt(hbuf, 1, len);
 29.1792 +                out.write(hbuf, 0, 5);
 29.1793 +            }
 29.1794 +        }
 29.1795 +
 29.1796 +
 29.1797 +        /* ----------------- primitive data output methods ----------------- */
 29.1798 +        /*
 29.1799 +         * The following methods are equivalent to their counterparts in
 29.1800 +         * DataOutputStream, except that they partition written data into data
 29.1801 +         * blocks when in block data mode.
 29.1802 +         */
 29.1803 +
 29.1804 +        public void writeBoolean(boolean v) throws IOException {
 29.1805 +            if (pos >= MAX_BLOCK_SIZE) {
 29.1806 +                drain();
 29.1807 +            }
 29.1808 +            Bits.putBoolean(buf, pos++, v);
 29.1809 +        }
 29.1810 +
 29.1811 +        public void writeByte(int v) throws IOException {
 29.1812 +            if (pos >= MAX_BLOCK_SIZE) {
 29.1813 +                drain();
 29.1814 +            }
 29.1815 +            buf[pos++] = (byte) v;
 29.1816 +        }
 29.1817 +
 29.1818 +        public void writeChar(int v) throws IOException {
 29.1819 +            if (pos + 2 <= MAX_BLOCK_SIZE) {
 29.1820 +                Bits.putChar(buf, pos, (char) v);
 29.1821 +                pos += 2;
 29.1822 +            } else {
 29.1823 +                dout.writeChar(v);
 29.1824 +            }
 29.1825 +        }
 29.1826 +
 29.1827 +        public void writeShort(int v) throws IOException {
 29.1828 +            if (pos + 2 <= MAX_BLOCK_SIZE) {
 29.1829 +                Bits.putShort(buf, pos, (short) v);
 29.1830 +                pos += 2;
 29.1831 +            } else {
 29.1832 +                dout.writeShort(v);
 29.1833 +            }
 29.1834 +        }
 29.1835 +
 29.1836 +        public void writeInt(int v) throws IOException {
 29.1837 +            if (pos + 4 <= MAX_BLOCK_SIZE) {
 29.1838 +                Bits.putInt(buf, pos, v);
 29.1839 +                pos += 4;
 29.1840 +            } else {
 29.1841 +                dout.writeInt(v);
 29.1842 +            }
 29.1843 +        }
 29.1844 +
 29.1845 +        public void writeFloat(float v) throws IOException {
 29.1846 +            if (pos + 4 <= MAX_BLOCK_SIZE) {
 29.1847 +                Bits.putFloat(buf, pos, v);
 29.1848 +                pos += 4;
 29.1849 +            } else {
 29.1850 +                dout.writeFloat(v);
 29.1851 +            }
 29.1852 +        }
 29.1853 +
 29.1854 +        public void writeLong(long v) throws IOException {
 29.1855 +            if (pos + 8 <= MAX_BLOCK_SIZE) {
 29.1856 +                Bits.putLong(buf, pos, v);
 29.1857 +                pos += 8;
 29.1858 +            } else {
 29.1859 +                dout.writeLong(v);
 29.1860 +            }
 29.1861 +        }
 29.1862 +
 29.1863 +        public void writeDouble(double v) throws IOException {
 29.1864 +            if (pos + 8 <= MAX_BLOCK_SIZE) {
 29.1865 +                Bits.putDouble(buf, pos, v);
 29.1866 +                pos += 8;
 29.1867 +            } else {
 29.1868 +                dout.writeDouble(v);
 29.1869 +            }
 29.1870 +        }
 29.1871 +
 29.1872 +        public void writeBytes(String s) throws IOException {
 29.1873 +            int endoff = s.length();
 29.1874 +            int cpos = 0;
 29.1875 +            int csize = 0;
 29.1876 +            for (int off = 0; off < endoff; ) {
 29.1877 +                if (cpos >= csize) {
 29.1878 +                    cpos = 0;
 29.1879 +                    csize = Math.min(endoff - off, CHAR_BUF_SIZE);
 29.1880 +                    s.getChars(off, off + csize, cbuf, 0);
 29.1881 +                }
 29.1882 +                if (pos >= MAX_BLOCK_SIZE) {
 29.1883 +                    drain();
 29.1884 +                }
 29.1885 +                int n = Math.min(csize - cpos, MAX_BLOCK_SIZE - pos);
 29.1886 +                int stop = pos + n;
 29.1887 +                while (pos < stop) {
 29.1888 +                    buf[pos++] = (byte) cbuf[cpos++];
 29.1889 +                }
 29.1890 +                off += n;
 29.1891 +            }
 29.1892 +        }
 29.1893 +
 29.1894 +        public void writeChars(String s) throws IOException {
 29.1895 +            int endoff = s.length();
 29.1896 +            for (int off = 0; off < endoff; ) {
 29.1897 +                int csize = Math.min(endoff - off, CHAR_BUF_SIZE);
 29.1898 +                s.getChars(off, off + csize, cbuf, 0);
 29.1899 +                writeChars(cbuf, 0, csize);
 29.1900 +                off += csize;
 29.1901 +            }
 29.1902 +        }
 29.1903 +
 29.1904 +        public void writeUTF(String s) throws IOException {
 29.1905 +            writeUTF(s, getUTFLength(s));
 29.1906 +        }
 29.1907 +
 29.1908 +
 29.1909 +        /* -------------- primitive data array output methods -------------- */
 29.1910 +        /*
 29.1911 +         * The following methods write out spans of primitive data values.
 29.1912 +         * Though equivalent to calling the corresponding primitive write
 29.1913 +         * methods repeatedly, these methods are optimized for writing groups
 29.1914 +         * of primitive data values more efficiently.
 29.1915 +         */
 29.1916 +
 29.1917 +        void writeBooleans(boolean[] v, int off, int len) throws IOException {
 29.1918 +            int endoff = off + len;
 29.1919 +            while (off < endoff) {
 29.1920 +                if (pos >= MAX_BLOCK_SIZE) {
 29.1921 +                    drain();
 29.1922 +                }
 29.1923 +                int stop = Math.min(endoff, off + (MAX_BLOCK_SIZE - pos));
 29.1924 +                while (off < stop) {
 29.1925 +                    Bits.putBoolean(buf, pos++, v[off++]);
 29.1926 +                }
 29.1927 +            }
 29.1928 +        }
 29.1929 +
 29.1930 +        void writeChars(char[] v, int off, int len) throws IOException {
 29.1931 +            int limit = MAX_BLOCK_SIZE - 2;
 29.1932 +            int endoff = off + len;
 29.1933 +            while (off < endoff) {
 29.1934 +                if (pos <= limit) {
 29.1935 +                    int avail = (MAX_BLOCK_SIZE - pos) >> 1;
 29.1936 +                    int stop = Math.min(endoff, off + avail);
 29.1937 +                    while (off < stop) {
 29.1938 +                        Bits.putChar(buf, pos, v[off++]);
 29.1939 +                        pos += 2;
 29.1940 +                    }
 29.1941 +                } else {
 29.1942 +                    dout.writeChar(v[off++]);
 29.1943 +                }
 29.1944 +            }
 29.1945 +        }
 29.1946 +
 29.1947 +        void writeShorts(short[] v, int off, int len) throws IOException {
 29.1948 +            int limit = MAX_BLOCK_SIZE - 2;
 29.1949 +            int endoff = off + len;
 29.1950 +            while (off < endoff) {
 29.1951 +                if (pos <= limit) {
 29.1952 +                    int avail = (MAX_BLOCK_SIZE - pos) >> 1;
 29.1953 +                    int stop = Math.min(endoff, off + avail);
 29.1954 +                    while (off < stop) {
 29.1955 +                        Bits.putShort(buf, pos, v[off++]);
 29.1956 +                        pos += 2;
 29.1957 +                    }
 29.1958 +                } else {
 29.1959 +                    dout.writeShort(v[off++]);
 29.1960 +                }
 29.1961 +            }
 29.1962 +        }
 29.1963 +
 29.1964 +        void writeInts(int[] v, int off, int len) throws IOException {
 29.1965 +            int limit = MAX_BLOCK_SIZE - 4;
 29.1966 +            int endoff = off + len;
 29.1967 +            while (off < endoff) {
 29.1968 +                if (pos <= limit) {
 29.1969 +                    int avail = (MAX_BLOCK_SIZE - pos) >> 2;
 29.1970 +                    int stop = Math.min(endoff, off + avail);
 29.1971 +                    while (off < stop) {
 29.1972 +                        Bits.putInt(buf, pos, v[off++]);
 29.1973 +                        pos += 4;
 29.1974 +                    }
 29.1975 +                } else {
 29.1976 +                    dout.writeInt(v[off++]);
 29.1977 +                }
 29.1978 +            }
 29.1979 +        }
 29.1980 +
 29.1981 +        void writeFloats(float[] v, int off, int len) throws IOException {
 29.1982 +            int limit = MAX_BLOCK_SIZE - 4;
 29.1983 +            int endoff = off + len;
 29.1984 +            while (off < endoff) {
 29.1985 +                if (pos <= limit) {
 29.1986 +                    int avail = (MAX_BLOCK_SIZE - pos) >> 2;
 29.1987 +                    int chunklen = Math.min(endoff - off, avail);
 29.1988 +                    floatsToBytes(v, off, buf, pos, chunklen);
 29.1989 +                    off += chunklen;
 29.1990 +                    pos += chunklen << 2;
 29.1991 +                } else {
 29.1992 +                    dout.writeFloat(v[off++]);
 29.1993 +                }
 29.1994 +            }
 29.1995 +        }
 29.1996 +
 29.1997 +        void writeLongs(long[] v, int off, int len) throws IOException {
 29.1998 +            int limit = MAX_BLOCK_SIZE - 8;
 29.1999 +            int endoff = off + len;
 29.2000 +            while (off < endoff) {
 29.2001 +                if (pos <= limit) {
 29.2002 +                    int avail = (MAX_BLOCK_SIZE - pos) >> 3;
 29.2003 +                    int stop = Math.min(endoff, off + avail);
 29.2004 +                    while (off < stop) {
 29.2005 +                        Bits.putLong(buf, pos, v[off++]);
 29.2006 +                        pos += 8;
 29.2007 +                    }
 29.2008 +                } else {
 29.2009 +                    dout.writeLong(v[off++]);
 29.2010 +                }
 29.2011 +            }
 29.2012 +        }
 29.2013 +
 29.2014 +        void writeDoubles(double[] v, int off, int len) throws IOException {
 29.2015 +            int limit = MAX_BLOCK_SIZE - 8;
 29.2016 +            int endoff = off + len;
 29.2017 +            while (off < endoff) {
 29.2018 +                if (pos <= limit) {
 29.2019 +                    int avail = (MAX_BLOCK_SIZE - pos) >> 3;
 29.2020 +                    int chunklen = Math.min(endoff - off, avail);
 29.2021 +                    doublesToBytes(v, off, buf, pos, chunklen);
 29.2022 +                    off += chunklen;
 29.2023 +                    pos += chunklen << 3;
 29.2024 +                } else {
 29.2025 +                    dout.writeDouble(v[off++]);
 29.2026 +                }
 29.2027 +            }
 29.2028 +        }
 29.2029 +
 29.2030 +        /**
 29.2031 +         * Returns the length in bytes of the UTF encoding of the given string.
 29.2032 +         */
 29.2033 +        long getUTFLength(String s) {
 29.2034 +            int len = s.length();
 29.2035 +            long utflen = 0;
 29.2036 +            for (int off = 0; off < len; ) {
 29.2037 +                int csize = Math.min(len - off, CHAR_BUF_SIZE);
 29.2038 +                s.getChars(off, off + csize, cbuf, 0);
 29.2039 +                for (int cpos = 0; cpos < csize; cpos++) {
 29.2040 +                    char c = cbuf[cpos];
 29.2041 +                    if (c >= 0x0001 && c <= 0x007F) {
 29.2042 +                        utflen++;
 29.2043 +                    } else if (c > 0x07FF) {
 29.2044 +                        utflen += 3;
 29.2045 +                    } else {
 29.2046 +                        utflen += 2;
 29.2047 +                    }
 29.2048 +                }
 29.2049 +                off += csize;
 29.2050 +            }
 29.2051 +            return utflen;
 29.2052 +        }
 29.2053 +
 29.2054 +        /**
 29.2055 +         * Writes the given string in UTF format.  This method is used in
 29.2056 +         * situations where the UTF encoding length of the string is already
 29.2057 +         * known; specifying it explicitly avoids a prescan of the string to
 29.2058 +         * determine its UTF length.
 29.2059 +         */
 29.2060 +        void writeUTF(String s, long utflen) throws IOException {
 29.2061 +            if (utflen > 0xFFFFL) {
 29.2062 +                throw new UTFDataFormatException();
 29.2063 +            }
 29.2064 +            writeShort((int) utflen);
 29.2065 +            if (utflen == (long) s.length()) {
 29.2066 +                writeBytes(s);
 29.2067 +            } else {
 29.2068 +                writeUTFBody(s);
 29.2069 +            }
 29.2070 +        }
 29.2071 +
 29.2072 +        /**
 29.2073 +         * Writes given string in "long" UTF format.  "Long" UTF format is
 29.2074 +         * identical to standard UTF, except that it uses an 8 byte header
 29.2075 +         * (instead of the standard 2 bytes) to convey the UTF encoding length.
 29.2076 +         */
 29.2077 +        void writeLongUTF(String s) throws IOException {
 29.2078 +            writeLongUTF(s, getUTFLength(s));
 29.2079 +        }
 29.2080 +
 29.2081 +        /**
 29.2082 +         * Writes given string in "long" UTF format, where the UTF encoding
 29.2083 +         * length of the string is already known.
 29.2084 +         */
 29.2085 +        void writeLongUTF(String s, long utflen) throws IOException {
 29.2086 +            writeLong(utflen);
 29.2087 +            if (utflen == (long) s.length()) {
 29.2088 +                writeBytes(s);
 29.2089 +            } else {
 29.2090 +                writeUTFBody(s);
 29.2091 +            }
 29.2092 +        }
 29.2093 +
 29.2094 +        /**
 29.2095 +         * Writes the "body" (i.e., the UTF representation minus the 2-byte or
 29.2096 +         * 8-byte length header) of the UTF encoding for the given string.
 29.2097 +         */
 29.2098 +        private void writeUTFBody(String s) throws IOException {
 29.2099 +            int limit = MAX_BLOCK_SIZE - 3;
 29.2100 +            int len = s.length();
 29.2101 +            for (int off = 0; off < len; ) {
 29.2102 +                int csize = Math.min(len - off, CHAR_BUF_SIZE);
 29.2103 +                s.getChars(off, off + csize, cbuf, 0);
 29.2104 +                for (int cpos = 0; cpos < csize; cpos++) {
 29.2105 +                    char c = cbuf[cpos];
 29.2106 +                    if (pos <= limit) {
 29.2107 +                        if (c <= 0x007F && c != 0) {
 29.2108 +                            buf[pos++] = (byte) c;
 29.2109 +                        } else if (c > 0x07FF) {
 29.2110 +                            buf[pos + 2] = (byte) (0x80 | ((c >> 0) & 0x3F));
 29.2111 +                            buf[pos + 1] = (byte) (0x80 | ((c >> 6) & 0x3F));
 29.2112 +                            buf[pos + 0] = (byte) (0xE0 | ((c >> 12) & 0x0F));
 29.2113 +                            pos += 3;
 29.2114 +                        } else {
 29.2115 +                            buf[pos + 1] = (byte) (0x80 | ((c >> 0) & 0x3F));
 29.2116 +                            buf[pos + 0] = (byte) (0xC0 | ((c >> 6) & 0x1F));
 29.2117 +                            pos += 2;
 29.2118 +                        }
 29.2119 +                    } else {    // write one byte at a time to normalize block
 29.2120 +                        if (c <= 0x007F && c != 0) {
 29.2121 +                            write(c);
 29.2122 +                        } else if (c > 0x07FF) {
 29.2123 +                            write(0xE0 | ((c >> 12) & 0x0F));
 29.2124 +                            write(0x80 | ((c >> 6) & 0x3F));
 29.2125 +                            write(0x80 | ((c >> 0) & 0x3F));
 29.2126 +                        } else {
 29.2127 +                            write(0xC0 | ((c >> 6) & 0x1F));
 29.2128 +                            write(0x80 | ((c >> 0) & 0x3F));
 29.2129 +                        }
 29.2130 +                    }
 29.2131 +                }
 29.2132 +                off += csize;
 29.2133 +            }
 29.2134 +        }
 29.2135 +    }
 29.2136 +
 29.2137 +    /**
 29.2138 +     * Lightweight identity hash table which maps objects to integer handles,
 29.2139 +     * assigned in ascending order.
 29.2140 +     */
 29.2141 +    private static class HandleTable {
 29.2142 +
 29.2143 +        /* number of mappings in table/next available handle */
 29.2144 +        private int size;
 29.2145 +        /* size threshold determining when to expand hash spine */
 29.2146 +        private int threshold;
 29.2147 +        /* factor for computing size threshold */
 29.2148 +        private final float loadFactor;
 29.2149 +        /* maps hash value -> candidate handle value */
 29.2150 +        private int[] spine;
 29.2151 +        /* maps handle value -> next candidate handle value */
 29.2152 +        private int[] next;
 29.2153 +        /* maps handle value -> associated object */
 29.2154 +        private Object[] objs;
 29.2155 +
 29.2156 +        /**
 29.2157 +         * Creates new HandleTable with given capacity and load factor.
 29.2158 +         */
 29.2159 +        HandleTable(int initialCapacity, float loadFactor) {
 29.2160 +            this.loadFactor = loadFactor;
 29.2161 +            spine = new int[initialCapacity];
 29.2162 +            next = new int[initialCapacity];
 29.2163 +            objs = new Object[initialCapacity];
 29.2164 +            threshold = (int) (initialCapacity * loadFactor);
 29.2165 +            clear();
 29.2166 +        }
 29.2167 +
 29.2168 +        /**
 29.2169 +         * Assigns next available handle to given object, and returns handle
 29.2170 +         * value.  Handles are assigned in ascending order starting at 0.
 29.2171 +         */
 29.2172 +        int assign(Object obj) {
 29.2173 +            if (size >= next.length) {
 29.2174 +                growEntries();
 29.2175 +            }
 29.2176 +            if (size >= threshold) {
 29.2177 +                growSpine();
 29.2178 +            }
 29.2179 +            insert(obj, size);
 29.2180 +            return size++;
 29.2181 +        }
 29.2182 +
 29.2183 +        /**
 29.2184 +         * Looks up and returns handle associated with given object, or -1 if
 29.2185 +         * no mapping found.
 29.2186 +         */
 29.2187 +        int lookup(Object obj) {
 29.2188 +            if (size == 0) {
 29.2189 +                return -1;
 29.2190 +            }
 29.2191 +            int index = hash(obj) % spine.length;
 29.2192 +            for (int i = spine[index]; i >= 0; i = next[i]) {
 29.2193 +                if (objs[i] == obj) {
 29.2194 +                    return i;
 29.2195 +                }
 29.2196 +            }
 29.2197 +            return -1;
 29.2198 +        }
 29.2199 +
 29.2200 +        /**
 29.2201 +         * Resets table to its initial (empty) state.
 29.2202 +         */
 29.2203 +        void clear() {
 29.2204 +            Arrays.fill(spine, -1);
 29.2205 +            Arrays.fill(objs, 0, size, null);
 29.2206 +            size = 0;
 29.2207 +        }
 29.2208 +
 29.2209 +        /**
 29.2210 +         * Returns the number of mappings currently in table.
 29.2211 +         */
 29.2212 +        int size() {
 29.2213 +            return size;
 29.2214 +        }
 29.2215 +
 29.2216 +        /**
 29.2217 +         * Inserts mapping object -> handle mapping into table.  Assumes table
 29.2218 +         * is large enough to accommodate new mapping.
 29.2219 +         */
 29.2220 +        private void insert(Object obj, int handle) {
 29.2221 +            int index = hash(obj) % spine.length;
 29.2222 +            objs[handle] = obj;
 29.2223 +            next[handle] = spine[index];
 29.2224 +            spine[index] = handle;
 29.2225 +        }
 29.2226 +
 29.2227 +        /**
 29.2228 +         * Expands the hash "spine" -- equivalent to increasing the number of
 29.2229 +         * buckets in a conventional hash table.
 29.2230 +         */
 29.2231 +        private void growSpine() {
 29.2232 +            spine = new int[(spine.length << 1) + 1];
 29.2233 +            threshold = (int) (spine.length * loadFactor);
 29.2234 +            Arrays.fill(spine, -1);
 29.2235 +            for (int i = 0; i < size; i++) {
 29.2236 +                insert(objs[i], i);
 29.2237 +            }
 29.2238 +        }
 29.2239 +
 29.2240 +        /**
 29.2241 +         * Increases hash table capacity by lengthening entry arrays.
 29.2242 +         */
 29.2243 +        private void growEntries() {
 29.2244 +            int newLength = (next.length << 1) + 1;
 29.2245 +            int[] newNext = new int[newLength];
 29.2246 +            System.arraycopy(next, 0, newNext, 0, size);
 29.2247 +            next = newNext;
 29.2248 +
 29.2249 +            Object[] newObjs = new Object[newLength];
 29.2250 +            System.arraycopy(objs, 0, newObjs, 0, size);
 29.2251 +            objs = newObjs;
 29.2252 +        }
 29.2253 +
 29.2254 +        /**
 29.2255 +         * Returns hash value for given object.
 29.2256 +         */
 29.2257 +        private int hash(Object obj) {
 29.2258 +            return System.identityHashCode(obj) & 0x7FFFFFFF;
 29.2259 +        }
 29.2260 +    }
 29.2261 +
 29.2262 +    /**
 29.2263 +     * Lightweight identity hash table which maps objects to replacement
 29.2264 +     * objects.
 29.2265 +     */
 29.2266 +    private static class ReplaceTable {
 29.2267 +
 29.2268 +        /* maps object -> index */
 29.2269 +        private final HandleTable htab;
 29.2270 +        /* maps index -> replacement object */
 29.2271 +        private Object[] reps;
 29.2272 +
 29.2273 +        /**
 29.2274 +         * Creates new ReplaceTable with given capacity and load factor.
 29.2275 +         */
 29.2276 +        ReplaceTable(int initialCapacity, float loadFactor) {
 29.2277 +            htab = new HandleTable(initialCapacity, loadFactor);
 29.2278 +            reps = new Object[initialCapacity];
 29.2279 +        }
 29.2280 +
 29.2281 +        /**
 29.2282 +         * Enters mapping from object to replacement object.
 29.2283 +         */
 29.2284 +        void assign(Object obj, Object rep) {
 29.2285 +            int index = htab.assign(obj);
 29.2286 +            while (index >= reps.length) {
 29.2287 +                grow();
 29.2288 +            }
 29.2289 +            reps[index] = rep;
 29.2290 +        }
 29.2291 +
 29.2292 +        /**
 29.2293 +         * Looks up and returns replacement for given object.  If no
 29.2294 +         * replacement is found, returns the lookup object itself.
 29.2295 +         */
 29.2296 +        Object lookup(Object obj) {
 29.2297 +            int index = htab.lookup(obj);
 29.2298 +            return (index >= 0) ? reps[index] : obj;
 29.2299 +        }
 29.2300 +
 29.2301 +        /**
 29.2302 +         * Resets table to its initial (empty) state.
 29.2303 +         */
 29.2304 +        void clear() {
 29.2305 +            Arrays.fill(reps, 0, htab.size(), null);
 29.2306 +            htab.clear();
 29.2307 +        }
 29.2308 +
 29.2309 +        /**
 29.2310 +         * Returns the number of mappings currently in table.
 29.2311 +         */
 29.2312 +        int size() {
 29.2313 +            return htab.size();
 29.2314 +        }
 29.2315 +
 29.2316 +        /**
 29.2317 +         * Increases table capacity.
 29.2318 +         */
 29.2319 +        private void grow() {
 29.2320 +            Object[] newReps = new Object[(reps.length << 1) + 1];
 29.2321 +            System.arraycopy(reps, 0, newReps, 0, reps.length);
 29.2322 +            reps = newReps;
 29.2323 +        }
 29.2324 +    }
 29.2325 +
 29.2326 +    /**
 29.2327 +     * Stack to keep debug information about the state of the
 29.2328 +     * serialization process, for embedding in exception messages.
 29.2329 +     */
 29.2330 +    private static class DebugTraceInfoStack {
 29.2331 +        private final List<String> stack;
 29.2332 +
 29.2333 +        DebugTraceInfoStack() {
 29.2334 +            stack = new ArrayList<>();
 29.2335 +        }
 29.2336 +
 29.2337 +        /**
 29.2338 +         * Removes all of the elements from enclosed list.
 29.2339 +         */
 29.2340 +        void clear() {
 29.2341 +            stack.clear();
 29.2342 +        }
 29.2343 +
 29.2344 +        /**
 29.2345 +         * Removes the object at the top of enclosed list.
 29.2346 +         */
 29.2347 +        void pop() {
 29.2348 +            stack.remove(stack.size()-1);
 29.2349 +        }
 29.2350 +
 29.2351 +        /**
 29.2352 +         * Pushes a String onto the top of enclosed list.
 29.2353 +         */
 29.2354 +        void push(String entry) {
 29.2355 +            stack.add("\t- " + entry);
 29.2356 +        }
 29.2357 +
 29.2358 +        /**
 29.2359 +         * Returns a string representation of this object
 29.2360 +         */
 29.2361 +        public String toString() {
 29.2362 +            StringBuilder buffer = new StringBuilder();
 29.2363 +            if (!stack.isEmpty()) {
 29.2364 +                for(int i = stack.size(); i > 0; i-- ) {
 29.2365 +                    buffer.append(stack.get(i-1) + ((i != 1) ? "\n" : ""));
 29.2366 +                }
 29.2367 +            }
 29.2368 +            return buffer.toString();
 29.2369 +        }
 29.2370 +    }
 29.2371 +
 29.2372 +}
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/emul/compact/src/main/java/java/io/ObjectStreamClass.java	Tue Feb 05 17:04:22 2013 +0100
    30.3 @@ -0,0 +1,1396 @@
    30.4 +/*
    30.5 + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
    30.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    30.7 + *
    30.8 + * This code is free software; you can redistribute it and/or modify it
    30.9 + * under the terms of the GNU General Public License version 2 only, as
   30.10 + * published by the Free Software Foundation.  Oracle designates this
   30.11 + * particular file as subject to the "Classpath" exception as provided
   30.12 + * by Oracle in the LICENSE file that accompanied this code.
   30.13 + *
   30.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   30.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   30.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   30.17 + * version 2 for more details (a copy is included in the LICENSE file that
   30.18 + * accompanied this code).
   30.19 + *
   30.20 + * You should have received a copy of the GNU General Public License version
   30.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   30.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   30.23 + *
   30.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   30.25 + * or visit www.oracle.com if you need additional information or have any
   30.26 + * questions.
   30.27 + */
   30.28 +
   30.29 +package java.io;
   30.30 +
   30.31 +import java.lang.ref.Reference;
   30.32 +import java.lang.ref.ReferenceQueue;
   30.33 +import java.lang.ref.SoftReference;
   30.34 +import java.lang.ref.WeakReference;
   30.35 +import java.lang.reflect.Constructor;
   30.36 +import java.lang.reflect.Field;
   30.37 +import java.lang.reflect.InvocationTargetException;
   30.38 +import java.lang.reflect.Member;
   30.39 +import java.lang.reflect.Method;
   30.40 +import java.lang.reflect.Modifier;
   30.41 +import java.lang.reflect.Proxy;
   30.42 +import java.util.ArrayList;
   30.43 +import java.util.Arrays;
   30.44 +import java.util.Collections;
   30.45 +import java.util.Comparator;
   30.46 +import java.util.HashSet;
   30.47 +import java.util.Set;
   30.48 +
   30.49 +/**
   30.50 + * Serialization's descriptor for classes.  It contains the name and
   30.51 + * serialVersionUID of the class.  The ObjectStreamClass for a specific class
   30.52 + * loaded in this Java VM can be found/created using the lookup method.
   30.53 + *
   30.54 + * <p>The algorithm to compute the SerialVersionUID is described in
   30.55 + * <a href="../../../platform/serialization/spec/class.html#4100">Object
   30.56 + * Serialization Specification, Section 4.6, Stream Unique Identifiers</a>.
   30.57 + *
   30.58 + * @author      Mike Warres
   30.59 + * @author      Roger Riggs
   30.60 + * @see ObjectStreamField
   30.61 + * @see <a href="../../../platform/serialization/spec/class.html">Object Serialization Specification, Section 4, Class Descriptors</a>
   30.62 + * @since   JDK1.1
   30.63 + */
   30.64 +public class ObjectStreamClass implements Serializable {
   30.65 +
   30.66 +    /** serialPersistentFields value indicating no serializable fields */
   30.67 +    public static final ObjectStreamField[] NO_FIELDS =
   30.68 +        new ObjectStreamField[0];
   30.69 +
   30.70 +    private static final long serialVersionUID = -6120832682080437368L;
   30.71 +    private static final ObjectStreamField[] serialPersistentFields =
   30.72 +        NO_FIELDS;
   30.73 +
   30.74 +
   30.75 +    /** class associated with this descriptor (if any) */
   30.76 +    private Class<?> cl;
   30.77 +    /** name of class represented by this descriptor */
   30.78 +    private String name;
   30.79 +    /** serialVersionUID of represented class (null if not computed yet) */
   30.80 +    private volatile Long suid;
   30.81 +
   30.82 +    /** true if represents dynamic proxy class */
   30.83 +    private boolean isProxy;
   30.84 +    /** true if represents enum type */
   30.85 +    private boolean isEnum;
   30.86 +    /** true if represented class implements Serializable */
   30.87 +    private boolean serializable;
   30.88 +    /** true if represented class implements Externalizable */
   30.89 +    private boolean externalizable;
   30.90 +    /** true if desc has data written by class-defined writeObject method */
   30.91 +    private boolean hasWriteObjectData;
   30.92 +    /**
   30.93 +     * true if desc has externalizable data written in block data format; this
   30.94 +     * must be true by default to accommodate ObjectInputStream subclasses which
   30.95 +     * override readClassDescriptor() to return class descriptors obtained from
   30.96 +     * ObjectStreamClass.lookup() (see 4461737)
   30.97 +     */
   30.98 +    private boolean hasBlockExternalData = true;
   30.99 +
  30.100 +    /** exception (if any) thrown while attempting to resolve class */
  30.101 +    private ClassNotFoundException resolveEx;
  30.102 +    /** exception (if any) to throw if non-enum deserialization attempted */
  30.103 +    private InvalidClassException deserializeEx;
  30.104 +    /** exception (if any) to throw if non-enum serialization attempted */
  30.105 +    private InvalidClassException serializeEx;
  30.106 +    /** exception (if any) to throw if default serialization attempted */
  30.107 +    private InvalidClassException defaultSerializeEx;
  30.108 +
  30.109 +    /** serializable fields */
  30.110 +    private ObjectStreamField[] fields;
  30.111 +    /** aggregate marshalled size of primitive fields */
  30.112 +    private int primDataSize;
  30.113 +    /** number of non-primitive fields */
  30.114 +    private int numObjFields;
  30.115 +    /** reflector for setting/getting serializable field values */
  30.116 +//    private FieldReflector fieldRefl;
  30.117 +    /** data layout of serialized objects described by this class desc */
  30.118 +    private volatile ClassDataSlot[] dataLayout;
  30.119 +
  30.120 +    /** serialization-appropriate constructor, or null if none */
  30.121 +    private Constructor cons;
  30.122 +    /** class-defined writeObject method, or null if none */
  30.123 +    private Method writeObjectMethod;
  30.124 +    /** class-defined readObject method, or null if none */
  30.125 +    private Method readObjectMethod;
  30.126 +    /** class-defined readObjectNoData method, or null if none */
  30.127 +    private Method readObjectNoDataMethod;
  30.128 +    /** class-defined writeReplace method, or null if none */
  30.129 +    private Method writeReplaceMethod;
  30.130 +    /** class-defined readResolve method, or null if none */
  30.131 +    private Method readResolveMethod;
  30.132 +
  30.133 +    /** local class descriptor for represented class (may point to self) */
  30.134 +    private ObjectStreamClass localDesc;
  30.135 +    /** superclass descriptor appearing in stream */
  30.136 +    private ObjectStreamClass superDesc;
  30.137 +
  30.138 +    /**
  30.139 +     * Initializes native code.
  30.140 +     */
  30.141 +    private static native void initNative();
  30.142 +    static {
  30.143 +        initNative();
  30.144 +    }
  30.145 +
  30.146 +    /**
  30.147 +     * Find the descriptor for a class that can be serialized.  Creates an
  30.148 +     * ObjectStreamClass instance if one does not exist yet for class. Null is
  30.149 +     * returned if the specified class does not implement java.io.Serializable
  30.150 +     * or java.io.Externalizable.
  30.151 +     *
  30.152 +     * @param   cl class for which to get the descriptor
  30.153 +     * @return  the class descriptor for the specified class
  30.154 +     */
  30.155 +    public static ObjectStreamClass lookup(Class<?> cl) {
  30.156 +        return lookup(cl, false);
  30.157 +    }
  30.158 +
  30.159 +    /**
  30.160 +     * Returns the descriptor for any class, regardless of whether it
  30.161 +     * implements {@link Serializable}.
  30.162 +     *
  30.163 +     * @param        cl class for which to get the descriptor
  30.164 +     * @return       the class descriptor for the specified class
  30.165 +     * @since 1.6
  30.166 +     */
  30.167 +    public static ObjectStreamClass lookupAny(Class<?> cl) {
  30.168 +        return lookup(cl, true);
  30.169 +    }
  30.170 +
  30.171 +    /**
  30.172 +     * Returns the name of the class described by this descriptor.
  30.173 +     * This method returns the name of the class in the format that
  30.174 +     * is used by the {@link Class#getName} method.
  30.175 +     *
  30.176 +     * @return a string representing the name of the class
  30.177 +     */
  30.178 +    public String getName() {
  30.179 +        return name;
  30.180 +    }
  30.181 +
  30.182 +    /**
  30.183 +     * Return the serialVersionUID for this class.  The serialVersionUID
  30.184 +     * defines a set of classes all with the same name that have evolved from a
  30.185 +     * common root class and agree to be serialized and deserialized using a
  30.186 +     * common format.  NonSerializable classes have a serialVersionUID of 0L.
  30.187 +     *
  30.188 +     * @return  the SUID of the class described by this descriptor
  30.189 +     */
  30.190 +    public long getSerialVersionUID() {
  30.191 +        // REMIND: synchronize instead of relying on volatile?
  30.192 +        if (suid == null) {
  30.193 +            return computeDefaultSUID(cl);
  30.194 +        }
  30.195 +        return suid.longValue();
  30.196 +    }
  30.197 +
  30.198 +    /**
  30.199 +     * Return the class in the local VM that this version is mapped to.  Null
  30.200 +     * is returned if there is no corresponding local class.
  30.201 +     *
  30.202 +     * @return  the <code>Class</code> instance that this descriptor represents
  30.203 +     */
  30.204 +    public Class<?> forClass() {
  30.205 +        return cl;
  30.206 +    }
  30.207 +
  30.208 +    /**
  30.209 +     * Return an array of the fields of this serializable class.
  30.210 +     *
  30.211 +     * @return  an array containing an element for each persistent field of
  30.212 +     *          this class. Returns an array of length zero if there are no
  30.213 +     *          fields.
  30.214 +     * @since 1.2
  30.215 +     */
  30.216 +    public ObjectStreamField[] getFields() {
  30.217 +        return getFields(true);
  30.218 +    }
  30.219 +
  30.220 +    /**
  30.221 +     * Get the field of this class by name.
  30.222 +     *
  30.223 +     * @param   name the name of the data field to look for
  30.224 +     * @return  The ObjectStreamField object of the named field or null if
  30.225 +     *          there is no such named field.
  30.226 +     */
  30.227 +    public ObjectStreamField getField(String name) {
  30.228 +        return getField(name, null);
  30.229 +    }
  30.230 +
  30.231 +    /**
  30.232 +     * Return a string describing this ObjectStreamClass.
  30.233 +     */
  30.234 +    public String toString() {
  30.235 +        return name + ": static final long serialVersionUID = " +
  30.236 +            getSerialVersionUID() + "L;";
  30.237 +    }
  30.238 +
  30.239 +    /**
  30.240 +     * Looks up and returns class descriptor for given class, or null if class
  30.241 +     * is non-serializable and "all" is set to false.
  30.242 +     *
  30.243 +     * @param   cl class to look up
  30.244 +     * @param   all if true, return descriptors for all classes; if false, only
  30.245 +     *          return descriptors for serializable classes
  30.246 +     */
  30.247 +    static ObjectStreamClass lookup(Class<?> cl, boolean all) {
  30.248 +        if (!(all || Serializable.class.isAssignableFrom(cl))) {
  30.249 +            return null;
  30.250 +        }
  30.251 +        Object entry = null;
  30.252 +        EntryFuture future = null;
  30.253 +        if (entry == null) {
  30.254 +            EntryFuture newEntry = new EntryFuture();
  30.255 +            Reference<?> newRef = new SoftReference<>(newEntry);
  30.256 +            if (entry == null) {
  30.257 +                future = newEntry;
  30.258 +            }
  30.259 +        }
  30.260 +
  30.261 +        if (entry instanceof ObjectStreamClass) {  // check common case first
  30.262 +            return (ObjectStreamClass) entry;
  30.263 +        }
  30.264 +        if (entry instanceof EntryFuture) {
  30.265 +            future = (EntryFuture) entry;
  30.266 +            if (true) {
  30.267 +                /*
  30.268 +                 * Handle nested call situation described by 4803747: waiting
  30.269 +                 * for future value to be set by a lookup() call further up the
  30.270 +                 * stack will result in deadlock, so calculate and set the
  30.271 +                 * future value here instead.
  30.272 +                 */
  30.273 +                entry = null;
  30.274 +            } else {
  30.275 +                entry = future.get();
  30.276 +            }
  30.277 +        }
  30.278 +        if (entry == null) {
  30.279 +            try {
  30.280 +                entry = new ObjectStreamClass(cl);
  30.281 +            } catch (Throwable th) {
  30.282 +                entry = th;
  30.283 +            }
  30.284 +            // nested lookup call already set future
  30.285 +            entry = future.get();
  30.286 +        }
  30.287 +
  30.288 +        if (entry instanceof ObjectStreamClass) {
  30.289 +            return (ObjectStreamClass) entry;
  30.290 +        } else if (entry instanceof RuntimeException) {
  30.291 +            throw (RuntimeException) entry;
  30.292 +        } else if (entry instanceof Error) {
  30.293 +            throw (Error) entry;
  30.294 +        } else {
  30.295 +            throw new InternalError("unexpected entry: " + entry);
  30.296 +        }
  30.297 +    }
  30.298 +
  30.299 +    /**
  30.300 +     * Placeholder used in class descriptor and field reflector lookup tables
  30.301 +     * for an entry in the process of being initialized.  (Internal) callers
  30.302 +     * which receive an EntryFuture belonging to another thread as the result
  30.303 +     * of a lookup should call the get() method of the EntryFuture; this will
  30.304 +     * return the actual entry once it is ready for use and has been set().  To
  30.305 +     * conserve objects, EntryFutures synchronize on themselves.
  30.306 +     */
  30.307 +    private static class EntryFuture {
  30.308 +
  30.309 +        private static final Object unset = new Object();
  30.310 +        private Object entry = unset;
  30.311 +
  30.312 +        /**
  30.313 +         * Attempts to set the value contained by this EntryFuture.  If the
  30.314 +         * EntryFuture's value has not been set already, then the value is
  30.315 +         * saved, any callers blocked in the get() method are notified, and
  30.316 +         * true is returned.  If the value has already been set, then no saving
  30.317 +         * or notification occurs, and false is returned.
  30.318 +         */
  30.319 +        synchronized boolean set(Object entry) {
  30.320 +            if (this.entry != unset) {
  30.321 +                return false;
  30.322 +            }
  30.323 +            this.entry = entry;
  30.324 +            notifyAll();
  30.325 +            return true;
  30.326 +        }
  30.327 +
  30.328 +        /**
  30.329 +         * Returns the value contained by this EntryFuture, blocking if
  30.330 +         * necessary until a value is set.
  30.331 +         */
  30.332 +        synchronized Object get() {
  30.333 +            boolean interrupted = false;
  30.334 +            while (entry == unset) {
  30.335 +                try {
  30.336 +                    wait();
  30.337 +                } catch (InterruptedException ex) {
  30.338 +                    interrupted = true;
  30.339 +                }
  30.340 +            }
  30.341 +            return entry;
  30.342 +        }
  30.343 +    }
  30.344 +
  30.345 +    /**
  30.346 +     * Creates local class descriptor representing given class.
  30.347 +     */
  30.348 +    private ObjectStreamClass(final Class<?> cl) {
  30.349 +        this.cl = cl;
  30.350 +        name = cl.getName();
  30.351 +        isProxy = Proxy.isProxyClass(cl);
  30.352 +        isEnum = Enum.class.isAssignableFrom(cl);
  30.353 +        serializable = Serializable.class.isAssignableFrom(cl);
  30.354 +        externalizable = Externalizable.class.isAssignableFrom(cl);
  30.355 +
  30.356 +        Class<?> superCl = cl.getSuperclass();
  30.357 +        superDesc = (superCl != null) ? lookup(superCl, false) : null;
  30.358 +        localDesc = this;
  30.359 +
  30.360 +        suid = Long.valueOf(0);
  30.361 +        fields = NO_FIELDS;
  30.362 +
  30.363 +
  30.364 +        if (deserializeEx == null) {
  30.365 +            if (isEnum) {
  30.366 +                deserializeEx = new InvalidClassException(name, "enum type");
  30.367 +            } else if (cons == null) {
  30.368 +                deserializeEx = new InvalidClassException(
  30.369 +                    name, "no valid constructor");
  30.370 +            }
  30.371 +        }
  30.372 +        for (int i = 0; i < fields.length; i++) {
  30.373 +            if (fields[i].getField() == null) {
  30.374 +                defaultSerializeEx = new InvalidClassException(
  30.375 +                    name, "unmatched serializable field(s) declared");
  30.376 +            }
  30.377 +        }
  30.378 +    }
  30.379 +
  30.380 +    /**
  30.381 +     * Creates blank class descriptor which should be initialized via a
  30.382 +     * subsequent call to initProxy(), initNonProxy() or readNonProxy().
  30.383 +     */
  30.384 +    ObjectStreamClass() {
  30.385 +    }
  30.386 +
  30.387 +    /**
  30.388 +     * Initializes class descriptor representing a proxy class.
  30.389 +     */
  30.390 +    void initProxy(Class<?> cl,
  30.391 +                   ClassNotFoundException resolveEx,
  30.392 +                   ObjectStreamClass superDesc)
  30.393 +        throws InvalidClassException
  30.394 +    {
  30.395 +        this.cl = cl;
  30.396 +        this.resolveEx = resolveEx;
  30.397 +        this.superDesc = superDesc;
  30.398 +        isProxy = true;
  30.399 +        serializable = true;
  30.400 +        suid = Long.valueOf(0);
  30.401 +        fields = NO_FIELDS;
  30.402 +
  30.403 +        if (cl != null) {
  30.404 +            localDesc = lookup(cl, true);
  30.405 +            if (!localDesc.isProxy) {
  30.406 +                throw new InvalidClassException(
  30.407 +                    "cannot bind proxy descriptor to a non-proxy class");
  30.408 +            }
  30.409 +            name = localDesc.name;
  30.410 +            externalizable = localDesc.externalizable;
  30.411 +            cons = localDesc.cons;
  30.412 +            writeReplaceMethod = localDesc.writeReplaceMethod;
  30.413 +            readResolveMethod = localDesc.readResolveMethod;
  30.414 +            deserializeEx = localDesc.deserializeEx;
  30.415 +        }
  30.416 +    }
  30.417 +
  30.418 +    /**
  30.419 +     * Initializes class descriptor representing a non-proxy class.
  30.420 +     */
  30.421 +    void initNonProxy(ObjectStreamClass model,
  30.422 +                      Class<?> cl,
  30.423 +                      ClassNotFoundException resolveEx,
  30.424 +                      ObjectStreamClass superDesc)
  30.425 +        throws InvalidClassException
  30.426 +    {
  30.427 +        this.cl = cl;
  30.428 +        this.resolveEx = resolveEx;
  30.429 +        this.superDesc = superDesc;
  30.430 +        name = model.name;
  30.431 +        suid = Long.valueOf(model.getSerialVersionUID());
  30.432 +        isProxy = false;
  30.433 +        isEnum = model.isEnum;
  30.434 +        serializable = model.serializable;
  30.435 +        externalizable = model.externalizable;
  30.436 +        hasBlockExternalData = model.hasBlockExternalData;
  30.437 +        hasWriteObjectData = model.hasWriteObjectData;
  30.438 +        fields = model.fields;
  30.439 +        primDataSize = model.primDataSize;
  30.440 +        numObjFields = model.numObjFields;
  30.441 +
  30.442 +        if (cl != null) {
  30.443 +            localDesc = lookup(cl, true);
  30.444 +            if (localDesc.isProxy) {
  30.445 +                throw new InvalidClassException(
  30.446 +                    "cannot bind non-proxy descriptor to a proxy class");
  30.447 +            }
  30.448 +            if (isEnum != localDesc.isEnum) {
  30.449 +                throw new InvalidClassException(isEnum ?
  30.450 +                    "cannot bind enum descriptor to a non-enum class" :
  30.451 +                    "cannot bind non-enum descriptor to an enum class");
  30.452 +            }
  30.453 +
  30.454 +            if (serializable == localDesc.serializable &&
  30.455 +                !cl.isArray() &&
  30.456 +                suid.longValue() != localDesc.getSerialVersionUID())
  30.457 +            {
  30.458 +                throw new InvalidClassException(localDesc.name,
  30.459 +                    "local class incompatible: " +
  30.460 +                    "stream classdesc serialVersionUID = " + suid +
  30.461 +                    ", local class serialVersionUID = " +
  30.462 +                    localDesc.getSerialVersionUID());
  30.463 +            }
  30.464 +
  30.465 +            if (!classNamesEqual(name, localDesc.name)) {
  30.466 +                throw new InvalidClassException(localDesc.name,
  30.467 +                    "local class name incompatible with stream class " +
  30.468 +                    "name \"" + name + "\"");
  30.469 +            }
  30.470 +
  30.471 +            if (!isEnum) {
  30.472 +                if ((serializable == localDesc.serializable) &&
  30.473 +                    (externalizable != localDesc.externalizable))
  30.474 +                {
  30.475 +                    throw new InvalidClassException(localDesc.name,
  30.476 +                        "Serializable incompatible with Externalizable");
  30.477 +                }
  30.478 +
  30.479 +                if ((serializable != localDesc.serializable) ||
  30.480 +                    (externalizable != localDesc.externalizable) ||
  30.481 +                    !(serializable || externalizable))
  30.482 +                {
  30.483 +                    deserializeEx = new InvalidClassException(localDesc.name,
  30.484 +                        "class invalid for deserialization");
  30.485 +                }
  30.486 +            }
  30.487 +
  30.488 +            cons = localDesc.cons;
  30.489 +            writeObjectMethod = localDesc.writeObjectMethod;
  30.490 +            readObjectMethod = localDesc.readObjectMethod;
  30.491 +            readObjectNoDataMethod = localDesc.readObjectNoDataMethod;
  30.492 +            writeReplaceMethod = localDesc.writeReplaceMethod;
  30.493 +            readResolveMethod = localDesc.readResolveMethod;
  30.494 +            if (deserializeEx == null) {
  30.495 +                deserializeEx = localDesc.deserializeEx;
  30.496 +            }
  30.497 +        }
  30.498 +        // reassign to matched fields so as to reflect local unshared settings
  30.499 +        fields = null;
  30.500 +    }
  30.501 +
  30.502 +    /**
  30.503 +     * Reads non-proxy class descriptor information from given input stream.
  30.504 +     * The resulting class descriptor is not fully functional; it can only be
  30.505 +     * used as input to the ObjectInputStream.resolveClass() and
  30.506 +     * ObjectStreamClass.initNonProxy() methods.
  30.507 +     */
  30.508 +    void readNonProxy(ObjectInputStream in)
  30.509 +        throws IOException, ClassNotFoundException
  30.510 +    {
  30.511 +        name = in.readUTF();
  30.512 +        suid = Long.valueOf(in.readLong());
  30.513 +        isProxy = false;
  30.514 +
  30.515 +        byte flags = in.readByte();
  30.516 +        hasWriteObjectData =
  30.517 +            ((flags & ObjectStreamConstants.SC_WRITE_METHOD) != 0);
  30.518 +        hasBlockExternalData =
  30.519 +            ((flags & ObjectStreamConstants.SC_BLOCK_DATA) != 0);
  30.520 +        externalizable =
  30.521 +            ((flags & ObjectStreamConstants.SC_EXTERNALIZABLE) != 0);
  30.522 +        boolean sflag =
  30.523 +            ((flags & ObjectStreamConstants.SC_SERIALIZABLE) != 0);
  30.524 +        if (externalizable && sflag) {
  30.525 +            throw new InvalidClassException(
  30.526 +                name, "serializable and externalizable flags conflict");
  30.527 +        }
  30.528 +        serializable = externalizable || sflag;
  30.529 +        isEnum = ((flags & ObjectStreamConstants.SC_ENUM) != 0);
  30.530 +        if (isEnum && suid.longValue() != 0L) {
  30.531 +            throw new InvalidClassException(name,
  30.532 +                "enum descriptor has non-zero serialVersionUID: " + suid);
  30.533 +        }
  30.534 +
  30.535 +        int numFields = in.readShort();
  30.536 +        if (isEnum && numFields != 0) {
  30.537 +            throw new InvalidClassException(name,
  30.538 +                "enum descriptor has non-zero field count: " + numFields);
  30.539 +        }
  30.540 +        fields = (numFields > 0) ?
  30.541 +            new ObjectStreamField[numFields] : NO_FIELDS;
  30.542 +        for (int i = 0; i < numFields; i++) {
  30.543 +            char tcode = (char) in.readByte();
  30.544 +            String fname = in.readUTF();
  30.545 +            String signature = ((tcode == 'L') || (tcode == '[')) ?
  30.546 +                in.readTypeString() : new String(new char[] { tcode });
  30.547 +            try {
  30.548 +                fields[i] = new ObjectStreamField(fname, signature, false);
  30.549 +            } catch (RuntimeException e) {
  30.550 +                throw (IOException) new InvalidClassException(name,
  30.551 +                    "invalid descriptor for field " + fname).initCause(e);
  30.552 +            }
  30.553 +        }
  30.554 +        computeFieldOffsets();
  30.555 +    }
  30.556 +
  30.557 +    /**
  30.558 +     * Writes non-proxy class descriptor information to given output stream.
  30.559 +     */
  30.560 +    void writeNonProxy(ObjectOutputStream out) throws IOException {
  30.561 +        out.writeUTF(name);
  30.562 +        out.writeLong(getSerialVersionUID());
  30.563 +
  30.564 +        byte flags = 0;
  30.565 +        if (externalizable) {
  30.566 +            flags |= ObjectStreamConstants.SC_EXTERNALIZABLE;
  30.567 +            int protocol = out.getProtocolVersion();
  30.568 +            if (protocol != ObjectStreamConstants.PROTOCOL_VERSION_1) {
  30.569 +                flags |= ObjectStreamConstants.SC_BLOCK_DATA;
  30.570 +            }
  30.571 +        } else if (serializable) {
  30.572 +            flags |= ObjectStreamConstants.SC_SERIALIZABLE;
  30.573 +        }
  30.574 +        if (hasWriteObjectData) {
  30.575 +            flags |= ObjectStreamConstants.SC_WRITE_METHOD;
  30.576 +        }
  30.577 +        if (isEnum) {
  30.578 +            flags |= ObjectStreamConstants.SC_ENUM;
  30.579 +        }
  30.580 +        out.writeByte(flags);
  30.581 +
  30.582 +        out.writeShort(fields.length);
  30.583 +        for (int i = 0; i < fields.length; i++) {
  30.584 +            ObjectStreamField f = fields[i];
  30.585 +            out.writeByte(f.getTypeCode());
  30.586 +            out.writeUTF(f.getName());
  30.587 +            if (!f.isPrimitive()) {
  30.588 +                out.writeTypeString(f.getTypeString());
  30.589 +            }
  30.590 +        }
  30.591 +    }
  30.592 +
  30.593 +    /**
  30.594 +     * Returns ClassNotFoundException (if any) thrown while attempting to
  30.595 +     * resolve local class corresponding to this class descriptor.
  30.596 +     */
  30.597 +    ClassNotFoundException getResolveException() {
  30.598 +        return resolveEx;
  30.599 +    }
  30.600 +
  30.601 +    /**
  30.602 +     * Throws an InvalidClassException if object instances referencing this
  30.603 +     * class descriptor should not be allowed to deserialize.  This method does
  30.604 +     * not apply to deserialization of enum constants.
  30.605 +     */
  30.606 +    void checkDeserialize() throws InvalidClassException {
  30.607 +        if (deserializeEx != null) {
  30.608 +            InvalidClassException ice =
  30.609 +                new InvalidClassException(deserializeEx.classname,
  30.610 +                                          deserializeEx.getMessage());
  30.611 +            ice.initCause(deserializeEx);
  30.612 +            throw ice;
  30.613 +        }
  30.614 +    }
  30.615 +
  30.616 +    /**
  30.617 +     * Throws an InvalidClassException if objects whose class is represented by
  30.618 +     * this descriptor should not be allowed to serialize.  This method does
  30.619 +     * not apply to serialization of enum constants.
  30.620 +     */
  30.621 +    void checkSerialize() throws InvalidClassException {
  30.622 +        if (serializeEx != null) {
  30.623 +            InvalidClassException ice =
  30.624 +                new InvalidClassException(serializeEx.classname,
  30.625 +                                          serializeEx.getMessage());
  30.626 +            ice.initCause(serializeEx);
  30.627 +            throw ice;
  30.628 +        }
  30.629 +    }
  30.630 +
  30.631 +    /**
  30.632 +     * Throws an InvalidClassException if objects whose class is represented by
  30.633 +     * this descriptor should not be permitted to use default serialization
  30.634 +     * (e.g., if the class declares serializable fields that do not correspond
  30.635 +     * to actual fields, and hence must use the GetField API).  This method
  30.636 +     * does not apply to deserialization of enum constants.
  30.637 +     */
  30.638 +    void checkDefaultSerialize() throws InvalidClassException {
  30.639 +        if (defaultSerializeEx != null) {
  30.640 +            InvalidClassException ice =
  30.641 +                new InvalidClassException(defaultSerializeEx.classname,
  30.642 +                                          defaultSerializeEx.getMessage());
  30.643 +            ice.initCause(defaultSerializeEx);
  30.644 +            throw ice;
  30.645 +        }
  30.646 +    }
  30.647 +
  30.648 +    /**
  30.649 +     * Returns superclass descriptor.  Note that on the receiving side, the
  30.650 +     * superclass descriptor may be bound to a class that is not a superclass
  30.651 +     * of the subclass descriptor's bound class.
  30.652 +     */
  30.653 +    ObjectStreamClass getSuperDesc() {
  30.654 +        return superDesc;
  30.655 +    }
  30.656 +
  30.657 +    /**
  30.658 +     * Returns the "local" class descriptor for the class associated with this
  30.659 +     * class descriptor (i.e., the result of
  30.660 +     * ObjectStreamClass.lookup(this.forClass())) or null if there is no class
  30.661 +     * associated with this descriptor.
  30.662 +     */
  30.663 +    ObjectStreamClass getLocalDesc() {
  30.664 +        return localDesc;
  30.665 +    }
  30.666 +
  30.667 +    /**
  30.668 +     * Returns arrays of ObjectStreamFields representing the serializable
  30.669 +     * fields of the represented class.  If copy is true, a clone of this class
  30.670 +     * descriptor's field array is returned, otherwise the array itself is
  30.671 +     * returned.
  30.672 +     */
  30.673 +    ObjectStreamField[] getFields(boolean copy) {
  30.674 +        return copy ? fields.clone() : fields;
  30.675 +    }
  30.676 +
  30.677 +    /**
  30.678 +     * Looks up a serializable field of the represented class by name and type.
  30.679 +     * A specified type of null matches all types, Object.class matches all
  30.680 +     * non-primitive types, and any other non-null type matches assignable
  30.681 +     * types only.  Returns matching field, or null if no match found.
  30.682 +     */
  30.683 +    ObjectStreamField getField(String name, Class<?> type) {
  30.684 +        for (int i = 0; i < fields.length; i++) {
  30.685 +            ObjectStreamField f = fields[i];
  30.686 +            if (f.getName().equals(name)) {
  30.687 +                if (type == null ||
  30.688 +                    (type == Object.class && !f.isPrimitive()))
  30.689 +                {
  30.690 +                    return f;
  30.691 +                }
  30.692 +                Class<?> ftype = f.getType();
  30.693 +                if (ftype != null && type.isAssignableFrom(ftype)) {
  30.694 +                    return f;
  30.695 +                }
  30.696 +            }
  30.697 +        }
  30.698 +        return null;
  30.699 +    }
  30.700 +
  30.701 +    /**
  30.702 +     * Returns true if class descriptor represents a dynamic proxy class, false
  30.703 +     * otherwise.
  30.704 +     */
  30.705 +    boolean isProxy() {
  30.706 +        return isProxy;
  30.707 +    }
  30.708 +
  30.709 +    /**
  30.710 +     * Returns true if class descriptor represents an enum type, false
  30.711 +     * otherwise.
  30.712 +     */
  30.713 +    boolean isEnum() {
  30.714 +        return isEnum;
  30.715 +    }
  30.716 +
  30.717 +    /**
  30.718 +     * Returns true if represented class implements Externalizable, false
  30.719 +     * otherwise.
  30.720 +     */
  30.721 +    boolean isExternalizable() {
  30.722 +        return externalizable;
  30.723 +    }
  30.724 +
  30.725 +    /**
  30.726 +     * Returns true if represented class implements Serializable, false
  30.727 +     * otherwise.
  30.728 +     */
  30.729 +    boolean isSerializable() {
  30.730 +        return serializable;
  30.731 +    }
  30.732 +
  30.733 +    /**
  30.734 +     * Returns true if class descriptor represents externalizable class that
  30.735 +     * has written its data in 1.2 (block data) format, false otherwise.
  30.736 +     */
  30.737 +    boolean hasBlockExternalData() {
  30.738 +        return hasBlockExternalData;
  30.739 +    }
  30.740 +
  30.741 +    /**
  30.742 +     * Returns true if class descriptor represents serializable (but not
  30.743 +     * externalizable) class which has written its data via a custom
  30.744 +     * writeObject() method, false otherwise.
  30.745 +     */
  30.746 +    boolean hasWriteObjectData() {
  30.747 +        return hasWriteObjectData;
  30.748 +    }
  30.749 +
  30.750 +    /**
  30.751 +     * Returns true if represented class is serializable/externalizable and can
  30.752 +     * be instantiated by the serialization runtime--i.e., if it is
  30.753 +     * externalizable and defines a public no-arg constructor, or if it is
  30.754 +     * non-externalizable and its first non-serializable superclass defines an
  30.755 +     * accessible no-arg constructor.  Otherwise, returns false.
  30.756 +     */
  30.757 +    boolean isInstantiable() {
  30.758 +        return (cons != null);
  30.759 +    }
  30.760 +
  30.761 +    /**
  30.762 +     * Returns true if represented class is serializable (but not
  30.763 +     * externalizable) and defines a conformant writeObject method.  Otherwise,
  30.764 +     * returns false.
  30.765 +     */
  30.766 +    boolean hasWriteObjectMethod() {
  30.767 +        return (writeObjectMethod != null);
  30.768 +    }
  30.769 +
  30.770 +    /**
  30.771 +     * Returns true if represented class is serializable (but not
  30.772 +     * externalizable) and defines a conformant readObject method.  Otherwise,
  30.773 +     * returns false.
  30.774 +     */
  30.775 +    boolean hasReadObjectMethod() {
  30.776 +        return (readObjectMethod != null);
  30.777 +    }
  30.778 +
  30.779 +    /**
  30.780 +     * Returns true if represented class is serializable (but not
  30.781 +     * externalizable) and defines a conformant readObjectNoData method.
  30.782 +     * Otherwise, returns false.
  30.783 +     */
  30.784 +    boolean hasReadObjectNoDataMethod() {
  30.785 +        return (readObjectNoDataMethod != null);
  30.786 +    }
  30.787 +
  30.788 +    /**
  30.789 +     * Returns true if represented class is serializable or externalizable and
  30.790 +     * defines a conformant writeReplace method.  Otherwise, returns false.
  30.791 +     */
  30.792 +    boolean hasWriteReplaceMethod() {
  30.793 +        return (writeReplaceMethod != null);
  30.794 +    }
  30.795 +
  30.796 +    /**
  30.797 +     * Returns true if represented class is serializable or externalizable and
  30.798 +     * defines a conformant readResolve method.  Otherwise, returns false.
  30.799 +     */
  30.800 +    boolean hasReadResolveMethod() {
  30.801 +        return (readResolveMethod != null);
  30.802 +    }
  30.803 +
  30.804 +    /**
  30.805 +     * Creates a new instance of the represented class.  If the class is
  30.806 +     * externalizable, invokes its public no-arg constructor; otherwise, if the
  30.807 +     * class is serializable, invokes the no-arg constructor of the first
  30.808 +     * non-serializable superclass.  Throws UnsupportedOperationException if
  30.809 +     * this class descriptor is not associated with a class, if the associated
  30.810 +     * class is non-serializable or if the appropriate no-arg constructor is
  30.811 +     * inaccessible/unavailable.
  30.812 +     */
  30.813 +    Object newInstance()
  30.814 +        throws InstantiationException, InvocationTargetException,
  30.815 +               UnsupportedOperationException
  30.816 +    {
  30.817 +        if (cons != null) {
  30.818 +            try {
  30.819 +                return cons.newInstance();
  30.820 +            } catch (IllegalAccessException ex) {
  30.821 +                // should not occur, as access checks have been suppressed
  30.822 +                throw new InternalError();
  30.823 +            }
  30.824 +        } else {
  30.825 +            throw new UnsupportedOperationException();
  30.826 +        }
  30.827 +    }
  30.828 +
  30.829 +    /**
  30.830 +     * Invokes the writeObject method of the represented serializable class.
  30.831 +     * Throws UnsupportedOperationException if this class descriptor is not
  30.832 +     * associated with a class, or if the class is externalizable,
  30.833 +     * non-serializable or does not define writeObject.
  30.834 +     */
  30.835 +    void invokeWriteObject(Object obj, ObjectOutputStream out)
  30.836 +        throws IOException, UnsupportedOperationException
  30.837 +    {
  30.838 +        if (writeObjectMethod != null) {
  30.839 +            try {
  30.840 +                writeObjectMethod.invoke(obj, new Object[]{ out });
  30.841 +            } catch (InvocationTargetException ex) {
  30.842 +                Throwable th = ex.getTargetException();
  30.843 +                if (th instanceof IOException) {
  30.844 +                    throw (IOException) th;
  30.845 +                } else {
  30.846 +                    throwMiscException(th);
  30.847 +                }
  30.848 +            } catch (IllegalAccessException ex) {
  30.849 +                // should not occur, as access checks have been suppressed
  30.850 +                throw new InternalError();
  30.851 +            }
  30.852 +        } else {
  30.853 +            throw new UnsupportedOperationException();
  30.854 +        }
  30.855 +    }
  30.856 +
  30.857 +    /**
  30.858 +     * Invokes the readObject method of the represented serializable class.
  30.859 +     * Throws UnsupportedOperationException if this class descriptor is not
  30.860 +     * associated with a class, or if the class is externalizable,
  30.861 +     * non-serializable or does not define readObject.
  30.862 +     */
  30.863 +    void invokeReadObject(Object obj, ObjectInputStream in)
  30.864 +        throws ClassNotFoundException, IOException,
  30.865 +               UnsupportedOperationException
  30.866 +    {
  30.867 +        if (readObjectMethod != null) {
  30.868 +            try {
  30.869 +                readObjectMethod.invoke(obj, new Object[]{ in });
  30.870 +            } catch (InvocationTargetException ex) {
  30.871 +                Throwable th = ex.getTargetException();
  30.872 +                if (th instanceof ClassNotFoundException) {
  30.873 +                    throw (ClassNotFoundException) th;
  30.874 +                } else if (th instanceof IOException) {
  30.875 +                    throw (IOException) th;
  30.876 +                } else {
  30.877 +                    throwMiscException(th);
  30.878 +                }
  30.879 +            } catch (IllegalAccessException ex) {
  30.880 +                // should not occur, as access checks have been suppressed
  30.881 +                throw new InternalError();
  30.882 +            }
  30.883 +        } else {
  30.884 +            throw new UnsupportedOperationException();
  30.885 +        }
  30.886 +    }
  30.887 +
  30.888 +    /**
  30.889 +     * Invokes the readObjectNoData method of the represented serializable
  30.890 +     * class.  Throws UnsupportedOperationException if this class descriptor is
  30.891 +     * not associated with a class, or if the class is externalizable,
  30.892 +     * non-serializable or does not define readObjectNoData.
  30.893 +     */
  30.894 +    void invokeReadObjectNoData(Object obj)
  30.895 +        throws IOException, UnsupportedOperationException
  30.896 +    {
  30.897 +        if (readObjectNoDataMethod != null) {
  30.898 +            try {
  30.899 +                readObjectNoDataMethod.invoke(obj, (Object[]) null);
  30.900 +            } catch (InvocationTargetException ex) {
  30.901 +                Throwable th = ex.getTargetException();
  30.902 +                if (th instanceof ObjectStreamException) {
  30.903 +                    throw (ObjectStreamException) th;
  30.904 +                } else {
  30.905 +                    throwMiscException(th);
  30.906 +                }
  30.907 +            } catch (IllegalAccessException ex) {
  30.908 +                // should not occur, as access checks have been suppressed
  30.909 +                throw new InternalError();
  30.910 +            }
  30.911 +        } else {
  30.912 +            throw new UnsupportedOperationException();
  30.913 +        }
  30.914 +    }
  30.915 +
  30.916 +    /**
  30.917 +     * Invokes the writeReplace method of the represented serializable class and
  30.918 +     * returns the result.  Throws UnsupportedOperationException if this class
  30.919 +     * descriptor is not associated with a class, or if the class is
  30.920 +     * non-serializable or does not define writeReplace.
  30.921 +     */
  30.922 +    Object invokeWriteReplace(Object obj)
  30.923 +        throws IOException, UnsupportedOperationException
  30.924 +    {
  30.925 +        if (writeReplaceMethod != null) {
  30.926 +            try {
  30.927 +                return writeReplaceMethod.invoke(obj, (Object[]) null);
  30.928 +            } catch (InvocationTargetException ex) {
  30.929 +                Throwable th = ex.getTargetException();
  30.930 +                if (th instanceof ObjectStreamException) {
  30.931 +                    throw (ObjectStreamException) th;
  30.932 +                } else {
  30.933 +                    throwMiscException(th);
  30.934 +                    throw new InternalError();  // never reached
  30.935 +                }
  30.936 +            } catch (IllegalAccessException ex) {
  30.937 +                // should not occur, as access checks have been suppressed
  30.938 +                throw new InternalError();
  30.939 +            }
  30.940 +        } else {
  30.941 +            throw new UnsupportedOperationException();
  30.942 +        }
  30.943 +    }
  30.944 +
  30.945 +    /**
  30.946 +     * Invokes the readResolve method of the represented serializable class and
  30.947 +     * returns the result.  Throws UnsupportedOperationException if this class
  30.948 +     * descriptor is not associated with a class, or if the class is
  30.949 +     * non-serializable or does not define readResolve.
  30.950 +     */
  30.951 +    Object invokeReadResolve(Object obj)
  30.952 +        throws IOException, UnsupportedOperationException
  30.953 +    {
  30.954 +        if (readResolveMethod != null) {
  30.955 +            try {
  30.956 +                return readResolveMethod.invoke(obj, (Object[]) null);
  30.957 +            } catch (InvocationTargetException ex) {
  30.958 +                Throwable th = ex.getTargetException();
  30.959 +                if (th instanceof ObjectStreamException) {
  30.960 +                    throw (ObjectStreamException) th;
  30.961 +                } else {
  30.962 +                    throwMiscException(th);
  30.963 +                    throw new InternalError();  // never reached
  30.964 +                }
  30.965 +            } catch (IllegalAccessException ex) {
  30.966 +                // should not occur, as access checks have been suppressed
  30.967 +                throw new InternalError();
  30.968 +            }
  30.969 +        } else {
  30.970 +            throw new UnsupportedOperationException();
  30.971 +        }
  30.972 +    }
  30.973 +
  30.974 +    /**
  30.975 +     * Class representing the portion of an object's serialized form allotted
  30.976 +     * to data described by a given class descriptor.  If "hasData" is false,
  30.977 +     * the object's serialized form does not contain data associated with the
  30.978 +     * class descriptor.
  30.979 +     */
  30.980 +    static class ClassDataSlot {
  30.981 +
  30.982 +        /** class descriptor "occupying" this slot */
  30.983 +        final ObjectStreamClass desc;
  30.984 +        /** true if serialized form includes data for this slot's descriptor */
  30.985 +        final boolean hasData;
  30.986 +
  30.987 +        ClassDataSlot(ObjectStreamClass desc, boolean hasData) {
  30.988 +            this.desc = desc;
  30.989 +            this.hasData = hasData;
  30.990 +        }
  30.991 +    }
  30.992 +
  30.993 +    /**
  30.994 +     * Returns array of ClassDataSlot instances representing the data layout
  30.995 +     * (including superclass data) for serialized objects described by this
  30.996 +     * class descriptor.  ClassDataSlots are ordered by inheritance with those
  30.997 +     * containing "higher" superclasses appearing first.  The final
  30.998 +     * ClassDataSlot contains a reference to this descriptor.
  30.999 +     */
 30.1000 +    ClassDataSlot[] getClassDataLayout() throws InvalidClassException {
 30.1001 +        // REMIND: synchronize instead of relying on volatile?
 30.1002 +        if (dataLayout == null) {
 30.1003 +            dataLayout = getClassDataLayout0();
 30.1004 +        }
 30.1005 +        return dataLayout;
 30.1006 +    }
 30.1007 +
 30.1008 +    private ClassDataSlot[] getClassDataLayout0()
 30.1009 +        throws InvalidClassException
 30.1010 +    {
 30.1011 +        ArrayList<ClassDataSlot> slots = new ArrayList<>();
 30.1012 +        Class<?> start = cl, end = cl;
 30.1013 +
 30.1014 +        // locate closest non-serializable superclass
 30.1015 +        while (end != null && Serializable.class.isAssignableFrom(end)) {
 30.1016 +            end = end.getSuperclass();
 30.1017 +        }
 30.1018 +
 30.1019 +        for (ObjectStreamClass d = this; d != null; d = d.superDesc) {
 30.1020 +
 30.1021 +            // search up inheritance hierarchy for class with matching name
 30.1022 +            String searchName = (d.cl != null) ? d.cl.getName() : d.name;
 30.1023 +            Class<?> match = null;
 30.1024 +            for (Class<?> c = start; c != end; c = c.getSuperclass()) {
 30.1025 +                if (searchName.equals(c.getName())) {
 30.1026 +                    match = c;
 30.1027 +                    break;
 30.1028 +                }
 30.1029 +            }
 30.1030 +
 30.1031 +            // add "no data" slot for each unmatched class below match
 30.1032 +            if (match != null) {
 30.1033 +                for (Class<?> c = start; c != match; c = c.getSuperclass()) {
 30.1034 +                    slots.add(new ClassDataSlot(
 30.1035 +                        ObjectStreamClass.lookup(c, true), false));
 30.1036 +                }
 30.1037 +                start = match.getSuperclass();
 30.1038 +            }
 30.1039 +
 30.1040 +            // record descriptor/class pairing
 30.1041 +            slots.add(new ClassDataSlot(d.getVariantFor(match), true));
 30.1042 +        }
 30.1043 +
 30.1044 +        // add "no data" slot for any leftover unmatched classes
 30.1045 +        for (Class<?> c = start; c != end; c = c.getSuperclass()) {
 30.1046 +            slots.add(new ClassDataSlot(
 30.1047 +                ObjectStreamClass.lookup(c, true), false));
 30.1048 +        }
 30.1049 +
 30.1050 +        // order slots from superclass -> subclass
 30.1051 +        Collections.reverse(slots);
 30.1052 +        return slots.toArray(new ClassDataSlot[slots.size()]);
 30.1053 +    }
 30.1054 +
 30.1055 +    /**
 30.1056 +     * Returns aggregate size (in bytes) of marshalled primitive field values
 30.1057 +     * for represented class.
 30.1058 +     */
 30.1059 +    int getPrimDataSize() {
 30.1060 +        return primDataSize;
 30.1061 +    }
 30.1062 +
 30.1063 +    /**
 30.1064 +     * Returns number of non-primitive serializable fields of represented
 30.1065 +     * class.
 30.1066 +     */
 30.1067 +    int getNumObjFields() {
 30.1068 +        return numObjFields;
 30.1069 +    }
 30.1070 +
 30.1071 +    /**
 30.1072 +     * Fetches the serializable primitive field values of object obj and
 30.1073 +     * marshals them into byte array buf starting at offset 0.  It is the
 30.1074 +     * responsibility of the caller to ensure that obj is of the proper type if
 30.1075 +     * non-null.
 30.1076 +     */
 30.1077 +    void getPrimFieldValues(Object obj, byte[] buf) {
 30.1078 +    }
 30.1079 +
 30.1080 +    /**
 30.1081 +     * Sets the serializable primitive fields of object obj using values
 30.1082 +     * unmarshalled from byte array buf starting at offset 0.  It is the
 30.1083 +     * responsibility of the caller to ensure that obj is of the proper type if
 30.1084 +     * non-null.
 30.1085 +     */
 30.1086 +    void setPrimFieldValues(Object obj, byte[] buf) {
 30.1087 +    }
 30.1088 +
 30.1089 +    /**
 30.1090 +     * Fetches the serializable object field values of object obj and stores
 30.1091 +     * them in array vals starting at offset 0.  It is the responsibility of
 30.1092 +     * the caller to ensure that obj is of the proper type if non-null.
 30.1093 +     */
 30.1094 +    void getObjFieldValues(Object obj, Object[] vals) {
 30.1095 +    }
 30.1096 +
 30.1097 +    /**
 30.1098 +     * Sets the serializable object fields of object obj using values from
 30.1099 +     * array vals starting at offset 0.  It is the responsibility of the caller
 30.1100 +     * to ensure that obj is of the proper type if non-null.
 30.1101 +     */
 30.1102 +    void setObjFieldValues(Object obj, Object[] vals) {
 30.1103 +    }
 30.1104 +
 30.1105 +    /**
 30.1106 +     * Calculates and sets serializable field offsets, as well as primitive
 30.1107 +     * data size and object field count totals.  Throws InvalidClassException
 30.1108 +     * if fields are illegally ordered.
 30.1109 +     */
 30.1110 +    private void computeFieldOffsets() throws InvalidClassException {
 30.1111 +        primDataSize = 0;
 30.1112 +        numObjFields = 0;
 30.1113 +        int firstObjIndex = -1;
 30.1114 +
 30.1115 +        for (int i = 0; i < fields.length; i++) {
 30.1116 +            ObjectStreamField f = fields[i];
 30.1117 +            switch (f.getTypeCode()) {
 30.1118 +                case 'Z':
 30.1119 +                case 'B':
 30.1120 +                    f.setOffset(primDataSize++);
 30.1121 +                    break;
 30.1122 +
 30.1123 +                case 'C':
 30.1124 +                case 'S':
 30.1125 +                    f.setOffset(primDataSize);
 30.1126 +                    primDataSize += 2;
 30.1127 +                    break;
 30.1128 +
 30.1129 +                case 'I':
 30.1130 +                case 'F':
 30.1131 +                    f.setOffset(primDataSize);
 30.1132 +                    primDataSize += 4;
 30.1133 +                    break;
 30.1134 +
 30.1135 +                case 'J':
 30.1136 +                case 'D':
 30.1137 +                    f.setOffset(primDataSize);
 30.1138 +                    primDataSize += 8;
 30.1139 +                    break;
 30.1140 +
 30.1141 +                case '[':
 30.1142 +                case 'L':
 30.1143 +                    f.setOffset(numObjFields++);
 30.1144 +                    if (firstObjIndex == -1) {
 30.1145 +                        firstObjIndex = i;
 30.1146 +                    }
 30.1147 +                    break;
 30.1148 +
 30.1149 +                default:
 30.1150 +                    throw new InternalError();
 30.1151 +            }
 30.1152 +        }
 30.1153 +        if (firstObjIndex != -1 &&
 30.1154 +            firstObjIndex + numObjFields != fields.length)
 30.1155 +        {
 30.1156 +            throw new InvalidClassException(name, "illegal field order");
 30.1157 +        }
 30.1158 +    }
 30.1159 +
 30.1160 +    /**
 30.1161 +     * If given class is the same as the class associated with this class
 30.1162 +     * descriptor, returns reference to this class descriptor.  Otherwise,
 30.1163 +     * returns variant of this class descriptor bound to given class.
 30.1164 +     */
 30.1165 +    private ObjectStreamClass getVariantFor(Class<?> cl)
 30.1166 +        throws InvalidClassException
 30.1167 +    {
 30.1168 +        if (this.cl == cl) {
 30.1169 +            return this;
 30.1170 +        }
 30.1171 +        ObjectStreamClass desc = new ObjectStreamClass();
 30.1172 +        if (isProxy) {
 30.1173 +            desc.initProxy(cl, null, superDesc);
 30.1174 +        } else {
 30.1175 +            desc.initNonProxy(this, cl, null, superDesc);
 30.1176 +        }
 30.1177 +        return desc;
 30.1178 +    }
 30.1179 +
 30.1180 +    /**
 30.1181 +     * Returns public no-arg constructor of given class, or null if none found.
 30.1182 +     * Access checks are disabled on the returned constructor (if any), since
 30.1183 +     * the defining class may still be non-public.
 30.1184 +     */
 30.1185 +    private static Constructor getExternalizableConstructor(Class<?> cl) {
 30.1186 +        throw new SecurityException();
 30.1187 +    }
 30.1188 +
 30.1189 +    /**
 30.1190 +     * Returns subclass-accessible no-arg constructor of first non-serializable
 30.1191 +     * superclass, or null if none found.  Access checks are disabled on the
 30.1192 +     * returned constructor (if any).
 30.1193 +     */
 30.1194 +    private static Constructor getSerializableConstructor(Class<?> cl) {
 30.1195 +        Class<?> initCl = cl;
 30.1196 +        while (Serializable.class.isAssignableFrom(initCl)) {
 30.1197 +            if ((initCl = initCl.getSuperclass()) == null) {
 30.1198 +                return null;
 30.1199 +            }
 30.1200 +        }
 30.1201 +        throw new SecurityException();
 30.1202 +    }
 30.1203 +
 30.1204 +    /**
 30.1205 +     * Returns non-static, non-abstract method with given signature provided it
 30.1206 +     * is defined by or accessible (via inheritance) by the given class, or
 30.1207 +     * null if no match found.  Access checks are disabled on the returned
 30.1208 +     * method (if any).
 30.1209 +     */
 30.1210 +    private static Method getInheritableMethod(Class<?> cl, String name,
 30.1211 +                                               Class<?>[] argTypes,
 30.1212 +                                               Class<?> returnType)
 30.1213 +    {
 30.1214 +        throw new SecurityException();
 30.1215 +    }
 30.1216 +
 30.1217 +    /**
 30.1218 +     * Returns non-static private method with given signature defined by given
 30.1219 +     * class, or null if none found.  Access checks are disabled on the
 30.1220 +     * returned method (if any).
 30.1221 +     */
 30.1222 +    private static Method getPrivateMethod(Class<?> cl, String name,
 30.1223 +                                           Class<?>[] argTypes,
 30.1224 +                                           Class<?> returnType)
 30.1225 +    {
 30.1226 +        throw new SecurityException();
 30.1227 +    }
 30.1228 +
 30.1229 +    /**
 30.1230 +     * Returns true if classes are defined in the same runtime package, false
 30.1231 +     * otherwise.
 30.1232 +     */
 30.1233 +    private static boolean packageEquals(Class<?> cl1, Class<?> cl2) {
 30.1234 +        return (cl1.getClassLoader() == cl2.getClassLoader() &&
 30.1235 +                getPackageName(cl1).equals(getPackageName(cl2)));
 30.1236 +    }
 30.1237 +
 30.1238 +    /**
 30.1239 +     * Returns package name of given class.
 30.1240 +     */
 30.1241 +    private static String getPackageName(Class<?> cl) {
 30.1242 +        String s = cl.getName();
 30.1243 +        int i = s.lastIndexOf('[');
 30.1244 +        if (i >= 0) {
 30.1245 +            s = s.substring(i + 2);
 30.1246 +        }
 30.1247 +        i = s.lastIndexOf('.');
 30.1248 +        return (i >= 0) ? s.substring(0, i) : "";
 30.1249 +    }
 30.1250 +
 30.1251 +    /**
 30.1252 +     * Compares class names for equality, ignoring package names.  Returns true
 30.1253 +     * if class names equal, false otherwise.
 30.1254 +     */
 30.1255 +    private static boolean classNamesEqual(String name1, String name2) {
 30.1256 +        name1 = name1.substring(name1.lastIndexOf('.') + 1);
 30.1257 +        name2 = name2.substring(name2.lastIndexOf('.') + 1);
 30.1258 +        return name1.equals(name2);
 30.1259 +    }
 30.1260 +
 30.1261 +    /**
 30.1262 +     * Returns JVM type signature for given class.
 30.1263 +     */
 30.1264 +    private static String getClassSignature(Class<?> cl) {
 30.1265 +        StringBuilder sbuf = new StringBuilder();
 30.1266 +        while (cl.isArray()) {
 30.1267 +            sbuf.append('[');
 30.1268 +            cl = cl.getComponentType();
 30.1269 +        }
 30.1270 +        if (cl.isPrimitive()) {
 30.1271 +            if (cl == Integer.TYPE) {
 30.1272 +                sbuf.append('I');
 30.1273 +            } else if (cl == Byte.TYPE) {
 30.1274 +                sbuf.append('B');
 30.1275 +            } else if (cl == Long.TYPE) {
 30.1276 +                sbuf.append('J');
 30.1277 +            } else if (cl == Float.TYPE) {
 30.1278 +                sbuf.append('F');
 30.1279 +            } else if (cl == Double.TYPE) {
 30.1280 +                sbuf.append('D');
 30.1281 +            } else if (cl == Short.TYPE) {
 30.1282 +                sbuf.append('S');
 30.1283 +            } else if (cl == Character.TYPE) {
 30.1284 +                sbuf.append('C');
 30.1285 +            } else if (cl == Boolean.TYPE) {
 30.1286 +                sbuf.append('Z');
 30.1287 +            } else if (cl == Void.TYPE) {
 30.1288 +                sbuf.append('V');
 30.1289 +            } else {
 30.1290 +                throw new InternalError();
 30.1291 +            }
 30.1292 +        } else {
 30.1293 +            sbuf.append('L' + cl.getName().replace('.', '/') + ';');
 30.1294 +        }
 30.1295 +        return sbuf.toString();
 30.1296 +    }
 30.1297 +
 30.1298 +    /**
 30.1299 +     * Returns JVM type signature for given list of parameters and return type.
 30.1300 +     */
 30.1301 +    private static String getMethodSignature(Class<?>[] paramTypes,
 30.1302 +                                             Class<?> retType)
 30.1303 +    {
 30.1304 +        StringBuilder sbuf = new StringBuilder();
 30.1305 +        sbuf.append('(');
 30.1306 +        for (int i = 0; i < paramTypes.length; i++) {
 30.1307 +            sbuf.append(getClassSignature(paramTypes[i]));
 30.1308 +        }
 30.1309 +        sbuf.append(')');
 30.1310 +        sbuf.append(getClassSignature(retType));
 30.1311 +        return sbuf.toString();
 30.1312 +    }
 30.1313 +
 30.1314 +    /**
 30.1315 +     * Convenience method for throwing an exception that is either a
 30.1316 +     * RuntimeException, Error, or of some unexpected type (in which case it is
 30.1317 +     * wrapped inside an IOException).
 30.1318 +     */
 30.1319 +    private static void throwMiscException(Throwable th) throws IOException {
 30.1320 +        if (th instanceof RuntimeException) {
 30.1321 +            throw (RuntimeException) th;
 30.1322 +        } else if (th instanceof Error) {
 30.1323 +            throw (Error) th;
 30.1324 +        } else {
 30.1325 +            IOException ex = new IOException("unexpected exception type");
 30.1326 +            ex.initCause(th);
 30.1327 +            throw ex;
 30.1328 +        }
 30.1329 +    }
 30.1330 +
 30.1331 +    /**
 30.1332 +     * Returns ObjectStreamField array describing the serializable fields of
 30.1333 +     * the given class.  Serializable fields backed by an actual field of the
 30.1334 +     * class are represented by ObjectStreamFields with corresponding non-null
 30.1335 +     * Field objects.  Throws InvalidClassException if the (explicitly
 30.1336 +     * declared) serializable fields are invalid.
 30.1337 +     */
 30.1338 +    private static ObjectStreamField[] getSerialFields(Class<?> cl)
 30.1339 +        throws InvalidClassException
 30.1340 +    {
 30.1341 +        ObjectStreamField[] fields;
 30.1342 +        if (Serializable.class.isAssignableFrom(cl) &&
 30.1343 +            !Externalizable.class.isAssignableFrom(cl) &&
 30.1344 +            !Proxy.isProxyClass(cl) &&
 30.1345 +            !cl.isInterface())
 30.1346 +        {
 30.1347 +            if ((fields = getDeclaredSerialFields(cl)) == null) {
 30.1348 +                fields = getDefaultSerialFields(cl);
 30.1349 +            }
 30.1350 +            Arrays.sort(fields);
 30.1351 +        } else {
 30.1352 +            fields = NO_FIELDS;
 30.1353 +        }
 30.1354 +        return fields;
 30.1355 +    }
 30.1356 +
 30.1357 +    /**
 30.1358 +     * Returns serializable fields of given class as defined explicitly by a
 30.1359 +     * "serialPersistentFields" field, or null if no appropriate
 30.1360 +     * "serialPersistentFields" field is defined.  Serializable fields backed
 30.1361 +     * by an actual field of the class are represented by ObjectStreamFields
 30.1362 +     * with corresponding non-null Field objects.  For compatibility with past
 30.1363 +     * releases, a "serialPersistentFields" field with a null value is
 30.1364 +     * considered equivalent to not declaring "serialPersistentFields".  Throws
 30.1365 +     * InvalidClassException if the declared serializable fields are
 30.1366 +     * invalid--e.g., if multiple fields share the same name.
 30.1367 +     */
 30.1368 +    private static ObjectStreamField[] getDeclaredSerialFields(Class<?> cl)
 30.1369 +        throws InvalidClassException
 30.1370 +    {
 30.1371 +        throw new SecurityException();
 30.1372 +    }
 30.1373 +
 30.1374 +    /**
 30.1375 +     * Returns array of ObjectStreamFields corresponding to all non-static
 30.1376 +     * non-transient fields declared by given class.  Each ObjectStreamField
 30.1377 +     * contains a Field object for the field it represents.  If no default
 30.1378 +     * serializable fields exist, NO_FIELDS is returned.
 30.1379 +     */
 30.1380 +    private static ObjectStreamField[] getDefaultSerialFields(Class<?> cl) {
 30.1381 +        throw new SecurityException();
 30.1382 +    }
 30.1383 +
 30.1384 +    /**
 30.1385 +     * Returns explicit serial version UID value declared by given class, or
 30.1386 +     * null if none.
 30.1387 +     */
 30.1388 +    private static Long getDeclaredSUID(Class<?> cl) {
 30.1389 +        return null;
 30.1390 +    }
 30.1391 +
 30.1392 +    /**
 30.1393 +     * Computes the default serial version UID value for the given class.
 30.1394 +     */
 30.1395 +    private static long computeDefaultSUID(Class<?> cl) {
 30.1396 +        throw new SecurityException();
 30.1397 +    }
 30.1398 +
 30.1399 +}
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/emul/compact/src/main/java/java/io/ObjectStreamConstants.java	Tue Feb 05 17:04:22 2013 +0100
    31.3 @@ -0,0 +1,215 @@
    31.4 +/*
    31.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
    31.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    31.7 + *
    31.8 + * This code is free software; you can redistribute it and/or modify it
    31.9 + * under the terms of the GNU General Public License version 2 only, as
   31.10 + * published by the Free Software Foundation.  Oracle designates this
   31.11 + * particular file as subject to the "Classpath" exception as provided
   31.12 + * by Oracle in the LICENSE file that accompanied this code.
   31.13 + *
   31.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   31.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   31.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   31.17 + * version 2 for more details (a copy is included in the LICENSE file that
   31.18 + * accompanied this code).
   31.19 + *
   31.20 + * You should have received a copy of the GNU General Public License version
   31.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   31.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   31.23 + *
   31.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   31.25 + * or visit www.oracle.com if you need additional information or have any
   31.26 + * questions.
   31.27 + */
   31.28 +
   31.29 +package java.io;
   31.30 +
   31.31 +/**
   31.32 + * Constants written into the Object Serialization Stream.
   31.33 + *
   31.34 + * @author  unascribed
   31.35 + * @since JDK 1.1
   31.36 + */
   31.37 +public interface ObjectStreamConstants {
   31.38 +
   31.39 +    /**
   31.40 +     * Magic number that is written to the stream header.
   31.41 +     */
   31.42 +    final static short STREAM_MAGIC = (short)0xaced;
   31.43 +
   31.44 +    /**
   31.45 +     * Version number that is written to the stream header.
   31.46 +     */
   31.47 +    final static short STREAM_VERSION = 5;
   31.48 +
   31.49 +    /* Each item in the stream is preceded by a tag
   31.50 +     */
   31.51 +
   31.52 +    /**
   31.53 +     * First tag value.
   31.54 +     */
   31.55 +    final static byte TC_BASE = 0x70;
   31.56 +
   31.57 +    /**
   31.58 +     * Null object reference.
   31.59 +     */
   31.60 +    final static byte TC_NULL =         (byte)0x70;
   31.61 +
   31.62 +    /**
   31.63 +     * Reference to an object already written into the stream.
   31.64 +     */
   31.65 +    final static byte TC_REFERENCE =    (byte)0x71;
   31.66 +
   31.67 +    /**
   31.68 +     * new Class Descriptor.
   31.69 +     */
   31.70 +    final static byte TC_CLASSDESC =    (byte)0x72;
   31.71 +
   31.72 +    /**
   31.73 +     * new Object.
   31.74 +     */
   31.75 +    final static byte TC_OBJECT =       (byte)0x73;
   31.76 +
   31.77 +    /**
   31.78 +     * new String.
   31.79 +     */
   31.80 +    final static byte TC_STRING =       (byte)0x74;
   31.81 +
   31.82 +    /**
   31.83 +     * new Array.
   31.84 +     */
   31.85 +    final static byte TC_ARRAY =        (byte)0x75;
   31.86 +
   31.87 +    /**
   31.88 +     * Reference to Class.
   31.89 +     */
   31.90 +    final static byte TC_CLASS =        (byte)0x76;
   31.91 +
   31.92 +    /**
   31.93 +     * Block of optional data. Byte following tag indicates number
   31.94 +     * of bytes in this block data.
   31.95 +     */
   31.96 +    final static byte TC_BLOCKDATA =    (byte)0x77;
   31.97 +
   31.98 +    /**
   31.99 +     * End of optional block data blocks for an object.
  31.100 +     */
  31.101 +    final static byte TC_ENDBLOCKDATA = (byte)0x78;
  31.102 +
  31.103 +    /**
  31.104 +     * Reset stream context. All handles written into stream are reset.
  31.105 +     */
  31.106 +    final static byte TC_RESET =        (byte)0x79;
  31.107 +
  31.108 +    /**
  31.109 +     * long Block data. The long following the tag indicates the
  31.110 +     * number of bytes in this block data.
  31.111 +     */
  31.112 +    final static byte TC_BLOCKDATALONG= (byte)0x7A;
  31.113 +
  31.114 +    /**
  31.115 +     * Exception during write.
  31.116 +     */
  31.117 +    final static byte TC_EXCEPTION =    (byte)0x7B;
  31.118 +
  31.119 +    /**
  31.120 +     * Long string.
  31.121 +     */
  31.122 +    final static byte TC_LONGSTRING =   (byte)0x7C;
  31.123 +
  31.124 +    /**
  31.125 +     * new Proxy Class Descriptor.
  31.126 +     */
  31.127 +    final static byte TC_PROXYCLASSDESC =       (byte)0x7D;
  31.128 +
  31.129 +    /**
  31.130 +     * new Enum constant.
  31.131 +     * @since 1.5
  31.132 +     */
  31.133 +    final static byte TC_ENUM =         (byte)0x7E;
  31.134 +
  31.135 +    /**
  31.136 +     * Last tag value.
  31.137 +     */
  31.138 +    final static byte TC_MAX =          (byte)0x7E;
  31.139 +
  31.140 +    /**
  31.141 +     * First wire handle to be assigned.
  31.142 +     */
  31.143 +    final static int baseWireHandle = 0x7e0000;
  31.144 +
  31.145 +
  31.146 +    /******************************************************/
  31.147 +    /* Bit masks for ObjectStreamClass flag.*/
  31.148 +
  31.149 +    /**
  31.150 +     * Bit mask for ObjectStreamClass flag. Indicates a Serializable class
  31.151 +     * defines its own writeObject method.
  31.152 +     */
  31.153 +    final static byte SC_WRITE_METHOD = 0x01;
  31.154 +
  31.155 +    /**
  31.156 +     * Bit mask for ObjectStreamClass flag. Indicates Externalizable data
  31.157 +     * written in Block Data mode.
  31.158 +     * Added for PROTOCOL_VERSION_2.
  31.159 +     *
  31.160 +     * @see #PROTOCOL_VERSION_2
  31.161 +     * @since 1.2
  31.162 +     */
  31.163 +    final static byte SC_BLOCK_DATA = 0x08;
  31.164 +
  31.165 +    /**
  31.166 +     * Bit mask for ObjectStreamClass flag. Indicates class is Serializable.
  31.167 +     */
  31.168 +    final static byte SC_SERIALIZABLE = 0x02;
  31.169 +
  31.170 +    /**
  31.171 +     * Bit mask for ObjectStreamClass flag. Indicates class is Externalizable.
  31.172 +     */
  31.173 +    final static byte SC_EXTERNALIZABLE = 0x04;
  31.174 +
  31.175 +    /**
  31.176 +     * Bit mask for ObjectStreamClass flag. Indicates class is an enum type.
  31.177 +     * @since 1.5
  31.178 +     */
  31.179 +    final static byte SC_ENUM = 0x10;
  31.180 +
  31.181 +
  31.182 +    /* *******************************************************************/
  31.183 +    /* Security permissions */
  31.184 +
  31.185 +   /**
  31.186 +    * A Stream Protocol Version. <p>
  31.187 +    *
  31.188 +    * All externalizable data is written in JDK 1.1 external data
  31.189 +    * format after calling this method. This version is needed to write
  31.190 +    * streams containing Externalizable data that can be read by
  31.191 +    * pre-JDK 1.1.6 JVMs.
  31.192 +    *
  31.193 +    * @see java.io.ObjectOutputStream#useProtocolVersion(int)
  31.194 +    * @since 1.2
  31.195 +    */
  31.196 +    public final static int PROTOCOL_VERSION_1 = 1;
  31.197 +
  31.198 +
  31.199 +   /**
  31.200 +    * A Stream Protocol Version. <p>
  31.201 +    *
  31.202 +    * This protocol is written by JVM 1.2.
  31.203 +    *
  31.204 +    * Externalizable data is written in block data mode and is
  31.205 +    * terminated with TC_ENDBLOCKDATA. Externalizable classdescriptor
  31.206 +    * flags has SC_BLOCK_DATA enabled. JVM 1.1.6 and greater can
  31.207 +    * read this format change.
  31.208 +    *
  31.209 +    * Enables writing a nonSerializable class descriptor into the
  31.210 +    * stream. The serialVersionUID of a nonSerializable class is
  31.211 +    * set to 0L.
  31.212 +    *
  31.213 +    * @see java.io.ObjectOutputStream#useProtocolVersion(int)
  31.214 +    * @see #SC_BLOCK_DATA
  31.215 +    * @since 1.2
  31.216 +    */
  31.217 +    public final static int PROTOCOL_VERSION_2 = 2;
  31.218 +}
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/emul/compact/src/main/java/java/io/ObjectStreamException.java	Tue Feb 05 17:04:22 2013 +0100
    32.3 @@ -0,0 +1,53 @@
    32.4 +/*
    32.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
    32.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    32.7 + *
    32.8 + * This code is free software; you can redistribute it and/or modify it
    32.9 + * under the terms of the GNU General Public License version 2 only, as
   32.10 + * published by the Free Software Foundation.  Oracle designates this
   32.11 + * particular file as subject to the "Classpath" exception as provided
   32.12 + * by Oracle in the LICENSE file that accompanied this code.
   32.13 + *
   32.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   32.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   32.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   32.17 + * version 2 for more details (a copy is included in the LICENSE file that
   32.18 + * accompanied this code).
   32.19 + *
   32.20 + * You should have received a copy of the GNU General Public License version
   32.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   32.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   32.23 + *
   32.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   32.25 + * or visit www.oracle.com if you need additional information or have any
   32.26 + * questions.
   32.27 + */
   32.28 +
   32.29 +package java.io;
   32.30 +
   32.31 +/**
   32.32 + * Superclass of all exceptions specific to Object Stream classes.
   32.33 + *
   32.34 + * @author  unascribed
   32.35 + * @since   JDK1.1
   32.36 + */
   32.37 +public abstract class ObjectStreamException extends IOException {
   32.38 +
   32.39 +    private static final long serialVersionUID = 7260898174833392607L;
   32.40 +
   32.41 +    /**
   32.42 +     * Create an ObjectStreamException with the specified argument.
   32.43 +     *
   32.44 +     * @param classname the detailed message for the exception
   32.45 +     */
   32.46 +    protected ObjectStreamException(String classname) {
   32.47 +        super(classname);
   32.48 +    }
   32.49 +
   32.50 +    /**
   32.51 +     * Create an ObjectStreamException.
   32.52 +     */
   32.53 +    protected ObjectStreamException() {
   32.54 +        super();
   32.55 +    }
   32.56 +}
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/emul/compact/src/main/java/java/io/ObjectStreamField.java	Tue Feb 05 17:04:22 2013 +0100
    33.3 @@ -0,0 +1,314 @@
    33.4 +/*
    33.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
    33.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    33.7 + *
    33.8 + * This code is free software; you can redistribute it and/or modify it
    33.9 + * under the terms of the GNU General Public License version 2 only, as
   33.10 + * published by the Free Software Foundation.  Oracle designates this
   33.11 + * particular file as subject to the "Classpath" exception as provided
   33.12 + * by Oracle in the LICENSE file that accompanied this code.
   33.13 + *
   33.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   33.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   33.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   33.17 + * version 2 for more details (a copy is included in the LICENSE file that
   33.18 + * accompanied this code).
   33.19 + *
   33.20 + * You should have received a copy of the GNU General Public License version
   33.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   33.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   33.23 + *
   33.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   33.25 + * or visit www.oracle.com if you need additional information or have any
   33.26 + * questions.
   33.27 + */
   33.28 +
   33.29 +package java.io;
   33.30 +
   33.31 +import java.lang.reflect.Field;
   33.32 +
   33.33 +/**
   33.34 + * A description of a Serializable field from a Serializable class.  An array
   33.35 + * of ObjectStreamFields is used to declare the Serializable fields of a class.
   33.36 + *
   33.37 + * @author      Mike Warres
   33.38 + * @author      Roger Riggs
   33.39 + * @see ObjectStreamClass
   33.40 + * @since 1.2
   33.41 + */
   33.42 +public class ObjectStreamField
   33.43 +    implements Comparable<Object>
   33.44 +{
   33.45 +
   33.46 +    /** field name */
   33.47 +    private final String name;
   33.48 +    /** canonical JVM signature of field type */
   33.49 +    private final String signature;
   33.50 +    /** field type (Object.class if unknown non-primitive type) */
   33.51 +    private final Class<?> type;
   33.52 +    /** whether or not to (de)serialize field values as unshared */
   33.53 +    private final boolean unshared;
   33.54 +    /** corresponding reflective field object, if any */
   33.55 +    private final Field field;
   33.56 +    /** offset of field value in enclosing field group */
   33.57 +    private int offset = 0;
   33.58 +
   33.59 +    /**
   33.60 +     * Create a Serializable field with the specified type.  This field should
   33.61 +     * be documented with a <code>serialField</code> tag.
   33.62 +     *
   33.63 +     * @param   name the name of the serializable field
   33.64 +     * @param   type the <code>Class</code> object of the serializable field
   33.65 +     */
   33.66 +    public ObjectStreamField(String name, Class<?> type) {
   33.67 +        this(name, type, false);
   33.68 +    }
   33.69 +
   33.70 +    /**
   33.71 +     * Creates an ObjectStreamField representing a serializable field with the
   33.72 +     * given name and type.  If unshared is false, values of the represented
   33.73 +     * field are serialized and deserialized in the default manner--if the
   33.74 +     * field is non-primitive, object values are serialized and deserialized as
   33.75 +     * if they had been written and read by calls to writeObject and
   33.76 +     * readObject.  If unshared is true, values of the represented field are
   33.77 +     * serialized and deserialized as if they had been written and read by
   33.78 +     * calls to writeUnshared and readUnshared.
   33.79 +     *
   33.80 +     * @param   name field name
   33.81 +     * @param   type field type
   33.82 +     * @param   unshared if false, write/read field values in the same manner
   33.83 +     *          as writeObject/readObject; if true, write/read in the same
   33.84 +     *          manner as writeUnshared/readUnshared
   33.85 +     * @since   1.4
   33.86 +     */
   33.87 +    public ObjectStreamField(String name, Class<?> type, boolean unshared) {
   33.88 +        if (name == null) {
   33.89 +            throw new NullPointerException();
   33.90 +        }
   33.91 +        this.name = name;
   33.92 +        this.type = type;
   33.93 +        this.unshared = unshared;
   33.94 +        signature = getClassSignature(type).intern();
   33.95 +        field = null;
   33.96 +    }
   33.97 +
   33.98 +    /**
   33.99 +     * Creates an ObjectStreamField representing a field with the given name,
  33.100 +     * signature and unshared setting.
  33.101 +     */
  33.102 +    ObjectStreamField(String name, String signature, boolean unshared) {
  33.103 +        if (name == null) {
  33.104 +            throw new NullPointerException();
  33.105 +        }
  33.106 +        this.name = name;
  33.107 +        this.signature = signature.intern();
  33.108 +        this.unshared = unshared;
  33.109 +        field = null;
  33.110 +
  33.111 +        switch (signature.charAt(0)) {
  33.112 +            case 'Z': type = Boolean.TYPE; break;
  33.113 +            case 'B': type = Byte.TYPE; break;
  33.114 +            case 'C': type = Character.TYPE; break;
  33.115 +            case 'S': type = Short.TYPE; break;
  33.116 +            case 'I': type = Integer.TYPE; break;
  33.117 +            case 'J': type = Long.TYPE; break;
  33.118 +            case 'F': type = Float.TYPE; break;
  33.119 +            case 'D': type = Double.TYPE; break;
  33.120 +            case 'L':
  33.121 +            case '[': type = Object.class; break;
  33.122 +            default: throw new IllegalArgumentException("illegal signature");
  33.123 +        }
  33.124 +    }
  33.125 +
  33.126 +    /**
  33.127 +     * Creates an ObjectStreamField representing the given field with the
  33.128 +     * specified unshared setting.  For compatibility with the behavior of
  33.129 +     * earlier serialization implementations, a "showType" parameter is
  33.130 +     * necessary to govern whether or not a getType() call on this
  33.131 +     * ObjectStreamField (if non-primitive) will return Object.class (as
  33.132 +     * opposed to a more specific reference type).
  33.133 +     */
  33.134 +    ObjectStreamField(Field field, boolean unshared, boolean showType) {
  33.135 +        this.field = field;
  33.136 +        this.unshared = unshared;
  33.137 +        name = field.getName();
  33.138 +        Class<?> ftype = field.getType();
  33.139 +        type = (showType || ftype.isPrimitive()) ? ftype : Object.class;
  33.140 +        signature = getClassSignature(ftype).intern();
  33.141 +    }
  33.142 +
  33.143 +    /**
  33.144 +     * Get the name of this field.
  33.145 +     *
  33.146 +     * @return  a <code>String</code> representing the name of the serializable
  33.147 +     *          field
  33.148 +     */
  33.149 +    public String getName() {
  33.150 +        return name;
  33.151 +    }
  33.152 +
  33.153 +    /**
  33.154 +     * Get the type of the field.  If the type is non-primitive and this
  33.155 +     * <code>ObjectStreamField</code> was obtained from a deserialized {@link
  33.156 +     * ObjectStreamClass} instance, then <code>Object.class</code> is returned.
  33.157 +     * Otherwise, the <code>Class</code> object for the type of the field is
  33.158 +     * returned.
  33.159 +     *
  33.160 +     * @return  a <code>Class</code> object representing the type of the
  33.161 +     *          serializable field
  33.162 +     */
  33.163 +    public Class<?> getType() {
  33.164 +        return type;
  33.165 +    }
  33.166 +
  33.167 +    /**
  33.168 +     * Returns character encoding of field type.  The encoding is as follows:
  33.169 +     * <blockquote><pre>
  33.170 +     * B            byte
  33.171 +     * C            char
  33.172 +     * D            double
  33.173 +     * F            float
  33.174 +     * I            int
  33.175 +     * J            long
  33.176 +     * L            class or interface
  33.177 +     * S            short
  33.178 +     * Z            boolean
  33.179 +     * [            array
  33.180 +     * </pre></blockquote>
  33.181 +     *
  33.182 +     * @return  the typecode of the serializable field
  33.183 +     */
  33.184 +    // REMIND: deprecate?
  33.185 +    public char getTypeCode() {
  33.186 +        return signature.charAt(0);
  33.187 +    }
  33.188 +
  33.189 +    /**
  33.190 +     * Return the JVM type signature.
  33.191 +     *
  33.192 +     * @return  null if this field has a primitive type.
  33.193 +     */
  33.194 +    // REMIND: deprecate?
  33.195 +    public String getTypeString() {
  33.196 +        return isPrimitive() ? null : signature;
  33.197 +    }
  33.198 +
  33.199 +    /**
  33.200 +     * Offset of field within instance data.
  33.201 +     *
  33.202 +     * @return  the offset of this field
  33.203 +     * @see #setOffset
  33.204 +     */
  33.205 +    // REMIND: deprecate?
  33.206 +    public int getOffset() {
  33.207 +        return offset;
  33.208 +    }
  33.209 +
  33.210 +    /**
  33.211 +     * Offset within instance data.
  33.212 +     *
  33.213 +     * @param   offset the offset of the field
  33.214 +     * @see #getOffset
  33.215 +     */
  33.216 +    // REMIND: deprecate?
  33.217 +    protected void setOffset(int offset) {
  33.218 +        this.offset = offset;
  33.219 +    }
  33.220 +
  33.221 +    /**
  33.222 +     * Return true if this field has a primitive type.
  33.223 +     *
  33.224 +     * @return  true if and only if this field corresponds to a primitive type
  33.225 +     */
  33.226 +    // REMIND: deprecate?
  33.227 +    public boolean isPrimitive() {
  33.228 +        char tcode = signature.charAt(0);
  33.229 +        return ((tcode != 'L') && (tcode != '['));
  33.230 +    }
  33.231 +
  33.232 +    /**
  33.233 +     * Returns boolean value indicating whether or not the serializable field
  33.234 +     * represented by this ObjectStreamField instance is unshared.
  33.235 +     *
  33.236 +     * @since 1.4
  33.237 +     */
  33.238 +    public boolean isUnshared() {
  33.239 +        return unshared;
  33.240 +    }
  33.241 +
  33.242 +    /**
  33.243 +     * Compare this field with another <code>ObjectStreamField</code>.  Return
  33.244 +     * -1 if this is smaller, 0 if equal, 1 if greater.  Types that are
  33.245 +     * primitives are "smaller" than object types.  If equal, the field names
  33.246 +     * are compared.
  33.247 +     */
  33.248 +    // REMIND: deprecate?
  33.249 +    public int compareTo(Object obj) {
  33.250 +        ObjectStreamField other = (ObjectStreamField) obj;
  33.251 +        boolean isPrim = isPrimitive();
  33.252 +        if (isPrim != other.isPrimitive()) {
  33.253 +            return isPrim ? -1 : 1;
  33.254 +        }
  33.255 +        return name.compareTo(other.name);
  33.256 +    }
  33.257 +
  33.258 +    /**
  33.259 +     * Return a string that describes this field.
  33.260 +     */
  33.261 +    public String toString() {
  33.262 +        return signature + ' ' + name;
  33.263 +    }
  33.264 +
  33.265 +    /**
  33.266 +     * Returns field represented by this ObjectStreamField, or null if
  33.267 +     * ObjectStreamField is not associated with an actual field.
  33.268 +     */
  33.269 +    Field getField() {
  33.270 +        return field;
  33.271 +    }
  33.272 +
  33.273 +    /**
  33.274 +     * Returns JVM type signature of field (similar to getTypeString, except
  33.275 +     * that signature strings are returned for primitive fields as well).
  33.276 +     */
  33.277 +    String getSignature() {
  33.278 +        return signature;
  33.279 +    }
  33.280 +
  33.281 +    /**
  33.282 +     * Returns JVM type signature for given class.
  33.283 +     */
  33.284 +    private static String getClassSignature(Class<?> cl) {
  33.285 +        StringBuilder sbuf = new StringBuilder();
  33.286 +        while (cl.isArray()) {
  33.287 +            sbuf.append('[');
  33.288 +            cl = cl.getComponentType();
  33.289 +        }
  33.290 +        if (cl.isPrimitive()) {
  33.291 +            if (cl == Integer.TYPE) {
  33.292 +                sbuf.append('I');
  33.293 +            } else if (cl == Byte.TYPE) {
  33.294 +                sbuf.append('B');
  33.295 +            } else if (cl == Long.TYPE) {
  33.296 +                sbuf.append('J');
  33.297 +            } else if (cl == Float.TYPE) {
  33.298 +                sbuf.append('F');
  33.299 +            } else if (cl == Double.TYPE) {
  33.300 +                sbuf.append('D');
  33.301 +            } else if (cl == Short.TYPE) {
  33.302 +                sbuf.append('S');
  33.303 +            } else if (cl == Character.TYPE) {
  33.304 +                sbuf.append('C');
  33.305 +            } else if (cl == Boolean.TYPE) {
  33.306 +                sbuf.append('Z');
  33.307 +            } else if (cl == Void.TYPE) {
  33.308 +                sbuf.append('V');
  33.309 +            } else {
  33.310 +                throw new InternalError();
  33.311 +            }
  33.312 +        } else {
  33.313 +            sbuf.append('L' + cl.getName().replace('.', '/') + ';');
  33.314 +        }
  33.315 +        return sbuf.toString();
  33.316 +    }
  33.317 +}
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/emul/compact/src/main/java/java/io/OptionalDataException.java	Tue Feb 05 17:04:22 2013 +0100
    34.3 @@ -0,0 +1,83 @@
    34.4 +/*
    34.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
    34.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    34.7 + *
    34.8 + * This code is free software; you can redistribute it and/or modify it
    34.9 + * under the terms of the GNU General Public License version 2 only, as
   34.10 + * published by the Free Software Foundation.  Oracle designates this
   34.11 + * particular file as subject to the "Classpath" exception as provided
   34.12 + * by Oracle in the LICENSE file that accompanied this code.
   34.13 + *
   34.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   34.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   34.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   34.17 + * version 2 for more details (a copy is included in the LICENSE file that
   34.18 + * accompanied this code).
   34.19 + *
   34.20 + * You should have received a copy of the GNU General Public License version
   34.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   34.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   34.23 + *
   34.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   34.25 + * or visit www.oracle.com if you need additional information or have any
   34.26 + * questions.
   34.27 + */
   34.28 +package java.io;
   34.29 +
   34.30 +/**
   34.31 + * Exception indicating the failure of an object read operation due to
   34.32 + * unread primitive data, or the end of data belonging to a serialized
   34.33 + * object in the stream.  This exception may be thrown in two cases:
   34.34 + *
   34.35 + * <ul>
   34.36 + *   <li>An attempt was made to read an object when the next element in the
   34.37 + *       stream is primitive data.  In this case, the OptionalDataException's
   34.38 + *       length field is set to the number of bytes of primitive data
   34.39 + *       immediately readable from the stream, and the eof field is set to
   34.40 + *       false.
   34.41 + *
   34.42 + *   <li>An attempt was made to read past the end of data consumable by a
   34.43 + *       class-defined readObject or readExternal method.  In this case, the
   34.44 + *       OptionalDataException's eof field is set to true, and the length field
   34.45 + *       is set to 0.
   34.46 + * </ul>
   34.47 + *
   34.48 + * @author  unascribed
   34.49 + * @since   JDK1.1
   34.50 + */
   34.51 +public class OptionalDataException extends ObjectStreamException {
   34.52 +
   34.53 +    private static final long serialVersionUID = -8011121865681257820L;
   34.54 +
   34.55 +    /*
   34.56 +     * Create an <code>OptionalDataException</code> with a length.
   34.57 +     */
   34.58 +    OptionalDataException(int len) {
   34.59 +        eof = false;
   34.60 +        length = len;
   34.61 +    }
   34.62 +
   34.63 +    /*
   34.64 +     * Create an <code>OptionalDataException</code> signifying no
   34.65 +     * more primitive data is available.
   34.66 +     */
   34.67 +    OptionalDataException(boolean end) {
   34.68 +        length = 0;
   34.69 +        eof = end;
   34.70 +    }
   34.71 +
   34.72 +    /**
   34.73 +     * The number of bytes of primitive data available to be read
   34.74 +     * in the current buffer.
   34.75 +     *
   34.76 +     * @serial
   34.77 +     */
   34.78 +    public int length;
   34.79 +
   34.80 +    /**
   34.81 +     * True if there is no more data in the buffered part of the stream.
   34.82 +     *
   34.83 +     * @serial
   34.84 +     */
   34.85 +    public boolean eof;
   34.86 +}
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/emul/compact/src/main/java/java/io/OutputStream.java	Tue Feb 05 17:04:22 2013 +0100
    35.3 @@ -0,0 +1,154 @@
    35.4 +/*
    35.5 + * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
    35.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    35.7 + *
    35.8 + * This code is free software; you can redistribute it and/or modify it
    35.9 + * under the terms of the GNU General Public License version 2 only, as
   35.10 + * published by the Free Software Foundation.  Oracle designates this
   35.11 + * particular file as subject to the "Classpath" exception as provided
   35.12 + * by Oracle in the LICENSE file that accompanied this code.
   35.13 + *
   35.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   35.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   35.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   35.17 + * version 2 for more details (a copy is included in the LICENSE file that
   35.18 + * accompanied this code).
   35.19 + *
   35.20 + * You should have received a copy of the GNU General Public License version
   35.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   35.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   35.23 + *
   35.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   35.25 + * or visit www.oracle.com if you need additional information or have any
   35.26 + * questions.
   35.27 + */
   35.28 +
   35.29 +package java.io;
   35.30 +
   35.31 +/**
   35.32 + * This abstract class is the superclass of all classes representing
   35.33 + * an output stream of bytes. An output stream accepts output bytes
   35.34 + * and sends them to some sink.
   35.35 + * <p>
   35.36 + * Applications that need to define a subclass of
   35.37 + * <code>OutputStream</code> must always provide at least a method
   35.38 + * that writes one byte of output.
   35.39 + *
   35.40 + * @author  Arthur van Hoff
   35.41 + * @see     java.io.BufferedOutputStream
   35.42 + * @see     java.io.ByteArrayOutputStream
   35.43 + * @see     java.io.DataOutputStream
   35.44 + * @see     java.io.FilterOutputStream
   35.45 + * @see     java.io.InputStream
   35.46 + * @see     java.io.OutputStream#write(int)
   35.47 + * @since   JDK1.0
   35.48 + */
   35.49 +public abstract class OutputStream implements Closeable, Flushable {
   35.50 +    /**
   35.51 +     * Writes the specified byte to this output stream. The general
   35.52 +     * contract for <code>write</code> is that one byte is written
   35.53 +     * to the output stream. The byte to be written is the eight
   35.54 +     * low-order bits of the argument <code>b</code>. The 24
   35.55 +     * high-order bits of <code>b</code> are ignored.
   35.56 +     * <p>
   35.57 +     * Subclasses of <code>OutputStream</code> must provide an
   35.58 +     * implementation for this method.
   35.59 +     *
   35.60 +     * @param      b   the <code>byte</code>.
   35.61 +     * @exception  IOException  if an I/O error occurs. In particular,
   35.62 +     *             an <code>IOException</code> may be thrown if the
   35.63 +     *             output stream has been closed.
   35.64 +     */
   35.65 +    public abstract void write(int b) throws IOException;
   35.66 +
   35.67 +    /**
   35.68 +     * Writes <code>b.length</code> bytes from the specified byte array
   35.69 +     * to this output stream. The general contract for <code>write(b)</code>
   35.70 +     * is that it should have exactly the same effect as the call
   35.71 +     * <code>write(b, 0, b.length)</code>.
   35.72 +     *
   35.73 +     * @param      b   the data.
   35.74 +     * @exception  IOException  if an I/O error occurs.
   35.75 +     * @see        java.io.OutputStream#write(byte[], int, int)
   35.76 +     */
   35.77 +    public void write(byte b[]) throws IOException {
   35.78 +        write(b, 0, b.length);
   35.79 +    }
   35.80 +
   35.81 +    /**
   35.82 +     * Writes <code>len</code> bytes from the specified byte array
   35.83 +     * starting at offset <code>off</code> to this output stream.
   35.84 +     * The general contract for <code>write(b, off, len)</code> is that
   35.85 +     * some of the bytes in the array <code>b</code> are written to the
   35.86 +     * output stream in order; element <code>b[off]</code> is the first
   35.87 +     * byte written and <code>b[off+len-1]</code> is the last byte written
   35.88 +     * by this operation.
   35.89 +     * <p>
   35.90 +     * The <code>write</code> method of <code>OutputStream</code> calls
   35.91 +     * the write method of one argument on each of the bytes to be
   35.92 +     * written out. Subclasses are encouraged to override this method and
   35.93 +     * provide a more efficient implementation.
   35.94 +     * <p>
   35.95 +     * If <code>b</code> is <code>null</code>, a
   35.96 +     * <code>NullPointerException</code> is thrown.
   35.97 +     * <p>
   35.98 +     * If <code>off</code> is negative, or <code>len</code> is negative, or
   35.99 +     * <code>off+len</code> is greater than the length of the array
  35.100 +     * <code>b</code>, then an <tt>IndexOutOfBoundsException</tt> is thrown.
  35.101 +     *
  35.102 +     * @param      b     the data.
  35.103 +     * @param      off   the start offset in the data.
  35.104 +     * @param      len   the number of bytes to write.
  35.105 +     * @exception  IOException  if an I/O error occurs. In particular,
  35.106 +     *             an <code>IOException</code> is thrown if the output
  35.107 +     *             stream is closed.
  35.108 +     */
  35.109 +    public void write(byte b[], int off, int len) throws IOException {
  35.110 +        if (b == null) {
  35.111 +            throw new NullPointerException();
  35.112 +        } else if ((off < 0) || (off > b.length) || (len < 0) ||
  35.113 +                   ((off + len) > b.length) || ((off + len) < 0)) {
  35.114 +            throw new IndexOutOfBoundsException();
  35.115 +        } else if (len == 0) {
  35.116 +            return;
  35.117 +        }
  35.118 +        for (int i = 0 ; i < len ; i++) {
  35.119 +            write(b[off + i]);
  35.120 +        }
  35.121 +    }
  35.122 +
  35.123 +    /**
  35.124 +     * Flushes this output stream and forces any buffered output bytes
  35.125 +     * to be written out. The general contract of <code>flush</code> is
  35.126 +     * that calling it is an indication that, if any bytes previously
  35.127 +     * written have been buffered by the implementation of the output
  35.128 +     * stream, such bytes should immediately be written to their
  35.129 +     * intended destination.
  35.130 +     * <p>
  35.131 +     * If the intended destination of this stream is an abstraction provided by
  35.132 +     * the underlying operating system, for example a file, then flushing the
  35.133 +     * stream guarantees only that bytes previously written to the stream are
  35.134 +     * passed to the operating system for writing; it does not guarantee that
  35.135 +     * they are actually written to a physical device such as a disk drive.
  35.136 +     * <p>
  35.137 +     * The <code>flush</code> method of <code>OutputStream</code> does nothing.
  35.138 +     *
  35.139 +     * @exception  IOException  if an I/O error occurs.
  35.140 +     */
  35.141 +    public void flush() throws IOException {
  35.142 +    }
  35.143 +
  35.144 +    /**
  35.145 +     * Closes this output stream and releases any system resources
  35.146 +     * associated with this stream. The general contract of <code>close</code>
  35.147 +     * is that it closes the output stream. A closed stream cannot perform
  35.148 +     * output operations and cannot be reopened.
  35.149 +     * <p>
  35.150 +     * The <code>close</code> method of <code>OutputStream</code> does nothing.
  35.151 +     *
  35.152 +     * @exception  IOException  if an I/O error occurs.
  35.153 +     */
  35.154 +    public void close() throws IOException {
  35.155 +    }
  35.156 +
  35.157 +}
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/emul/compact/src/main/java/java/io/StreamCorruptedException.java	Tue Feb 05 17:04:22 2013 +0100
    36.3 @@ -0,0 +1,54 @@
    36.4 +/*
    36.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
    36.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    36.7 + *
    36.8 + * This code is free software; you can redistribute it and/or modify it
    36.9 + * under the terms of the GNU General Public License version 2 only, as
   36.10 + * published by the Free Software Foundation.  Oracle designates this
   36.11 + * particular file as subject to the "Classpath" exception as provided
   36.12 + * by Oracle in the LICENSE file that accompanied this code.
   36.13 + *
   36.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   36.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   36.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   36.17 + * version 2 for more details (a copy is included in the LICENSE file that
   36.18 + * accompanied this code).
   36.19 + *
   36.20 + * You should have received a copy of the GNU General Public License version
   36.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   36.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   36.23 + *
   36.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   36.25 + * or visit www.oracle.com if you need additional information or have any
   36.26 + * questions.
   36.27 + */
   36.28 +
   36.29 +package java.io;
   36.30 +
   36.31 +/**
   36.32 + * Thrown when control information that was read from an object stream
   36.33 + * violates internal consistency checks.
   36.34 + *
   36.35 + * @author  unascribed
   36.36 + * @since   JDK1.1
   36.37 + */
   36.38 +public class StreamCorruptedException extends ObjectStreamException {
   36.39 +
   36.40 +    private static final long serialVersionUID = 8983558202217591746L;
   36.41 +
   36.42 +    /**
   36.43 +     * Create a StreamCorruptedException and list a reason why thrown.
   36.44 +     *
   36.45 +     * @param reason  String describing the reason for the exception.
   36.46 +     */
   36.47 +    public StreamCorruptedException(String reason) {
   36.48 +        super(reason);
   36.49 +    }
   36.50 +
   36.51 +    /**
   36.52 +     * Create a StreamCorruptedException and list no reason why thrown.
   36.53 +     */
   36.54 +    public StreamCorruptedException() {
   36.55 +        super();
   36.56 +    }
   36.57 +}
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/emul/compact/src/main/java/java/io/WriteAbortedException.java	Tue Feb 05 17:04:22 2013 +0100
    37.3 @@ -0,0 +1,93 @@
    37.4 +/*
    37.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
    37.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    37.7 + *
    37.8 + * This code is free software; you can redistribute it and/or modify it
    37.9 + * under the terms of the GNU General Public License version 2 only, as
   37.10 + * published by the Free Software Foundation.  Oracle designates this
   37.11 + * particular file as subject to the "Classpath" exception as provided
   37.12 + * by Oracle in the LICENSE file that accompanied this code.
   37.13 + *
   37.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   37.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   37.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   37.17 + * version 2 for more details (a copy is included in the LICENSE file that
   37.18 + * accompanied this code).
   37.19 + *
   37.20 + * You should have received a copy of the GNU General Public License version
   37.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   37.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   37.23 + *
   37.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   37.25 + * or visit www.oracle.com if you need additional information or have any
   37.26 + * questions.
   37.27 + */
   37.28 +
   37.29 +package java.io;
   37.30 +
   37.31 +/**
   37.32 + * Signals that one of the ObjectStreamExceptions was thrown during a
   37.33 + * write operation.  Thrown during a read operation when one of the
   37.34 + * ObjectStreamExceptions was thrown during a write operation.  The
   37.35 + * exception that terminated the write can be found in the detail
   37.36 + * field. The stream is reset to it's initial state and all references
   37.37 + * to objects already deserialized are discarded.
   37.38 + *
   37.39 + * <p>As of release 1.4, this exception has been retrofitted to conform to
   37.40 + * the general purpose exception-chaining mechanism.  The "exception causing
   37.41 + * the abort" that is provided at construction time and
   37.42 + * accessed via the public {@link #detail} field is now known as the
   37.43 + * <i>cause</i>, and may be accessed via the {@link Throwable#getCause()}
   37.44 + * method, as well as the aforementioned "legacy field."
   37.45 + *
   37.46 + * @author  unascribed
   37.47 + * @since   JDK1.1
   37.48 + */
   37.49 +public class WriteAbortedException extends ObjectStreamException {
   37.50 +    private static final long serialVersionUID = -3326426625597282442L;
   37.51 +
   37.52 +    /**
   37.53 +     * Exception that was caught while writing the ObjectStream.
   37.54 +     *
   37.55 +     * <p>This field predates the general-purpose exception chaining facility.
   37.56 +     * The {@link Throwable#getCause()} method is now the preferred means of
   37.57 +     * obtaining this information.
   37.58 +     *
   37.59 +     * @serial
   37.60 +     */
   37.61 +    public Exception detail;
   37.62 +
   37.63 +    /**
   37.64 +     * Constructs a WriteAbortedException with a string describing
   37.65 +     * the exception and the exception causing the abort.
   37.66 +     * @param s   String describing the exception.
   37.67 +     * @param ex  Exception causing the abort.
   37.68 +     */
   37.69 +    public WriteAbortedException(String s, Exception ex) {
   37.70 +        super(s);
   37.71 +        initCause(null);  // Disallow subsequent initCause
   37.72 +        detail = ex;
   37.73 +    }
   37.74 +
   37.75 +    /**
   37.76 +     * Produce the message and include the message from the nested
   37.77 +     * exception, if there is one.
   37.78 +     */
   37.79 +    public String getMessage() {
   37.80 +        if (detail == null)
   37.81 +            return super.getMessage();
   37.82 +        else
   37.83 +            return super.getMessage() + "; " + detail.toString();
   37.84 +    }
   37.85 +
   37.86 +    /**
   37.87 +     * Returns the exception that terminated the operation (the <i>cause</i>).
   37.88 +     *
   37.89 +     * @return  the exception that terminated the operation (the <i>cause</i>),
   37.90 +     *          which may be null.
   37.91 +     * @since   1.4
   37.92 +     */
   37.93 +    public Throwable getCause() {
   37.94 +        return detail;
   37.95 +    }
   37.96 +}
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/emul/compact/src/main/java/java/lang/AbstractMethodError.java	Tue Feb 05 17:04:22 2013 +0100
    38.3 @@ -0,0 +1,58 @@
    38.4 +/*
    38.5 + * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
    38.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    38.7 + *
    38.8 + * This code is free software; you can redistribute it and/or modify it
    38.9 + * under the terms of the GNU General Public License version 2 only, as
   38.10 + * published by the Free Software Foundation.  Oracle designates this
   38.11 + * particular file as subject to the "Classpath" exception as provided
   38.12 + * by Oracle in the LICENSE file that accompanied this code.
   38.13 + *
   38.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   38.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   38.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   38.17 + * version 2 for more details (a copy is included in the LICENSE file that
   38.18 + * accompanied this code).
   38.19 + *
   38.20 + * You should have received a copy of the GNU General Public License version
   38.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   38.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   38.23 + *
   38.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   38.25 + * or visit www.oracle.com if you need additional information or have any
   38.26 + * questions.
   38.27 + */
   38.28 +
   38.29 +package java.lang;
   38.30 +
   38.31 +/**
   38.32 + * Thrown when an application tries to call an abstract method.
   38.33 + * Normally, this error is caught by the compiler; this error can
   38.34 + * only occur at run time if the definition of some class has
   38.35 + * incompatibly changed since the currently executing method was last
   38.36 + * compiled.
   38.37 + *
   38.38 + * @author  unascribed
   38.39 + * @since   JDK1.0
   38.40 + */
   38.41 +public
   38.42 +class AbstractMethodError extends IncompatibleClassChangeError {
   38.43 +    private static final long serialVersionUID = -1654391082989018462L;
   38.44 +
   38.45 +    /**
   38.46 +     * Constructs an <code>AbstractMethodError</code> with no detail  message.
   38.47 +     */
   38.48 +    public AbstractMethodError() {
   38.49 +        super();
   38.50 +    }
   38.51 +
   38.52 +    /**
   38.53 +     * Constructs an <code>AbstractMethodError</code> with the specified
   38.54 +     * detail message.
   38.55 +     *
   38.56 +     * @param   s   the detail message.
   38.57 +     */
   38.58 +    public AbstractMethodError(String s) {
   38.59 +        super(s);
   38.60 +    }
   38.61 +}
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/emul/compact/src/main/java/java/lang/IncompatibleClassChangeError.java	Tue Feb 05 17:04:22 2013 +0100
    39.3 @@ -0,0 +1,57 @@
    39.4 +/*
    39.5 + * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
    39.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    39.7 + *
    39.8 + * This code is free software; you can redistribute it and/or modify it
    39.9 + * under the terms of the GNU General Public License version 2 only, as
   39.10 + * published by the Free Software Foundation.  Oracle designates this
   39.11 + * particular file as subject to the "Classpath" exception as provided
   39.12 + * by Oracle in the LICENSE file that accompanied this code.
   39.13 + *
   39.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   39.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   39.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   39.17 + * version 2 for more details (a copy is included in the LICENSE file that
   39.18 + * accompanied this code).
   39.19 + *
   39.20 + * You should have received a copy of the GNU General Public License version
   39.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   39.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   39.23 + *
   39.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   39.25 + * or visit www.oracle.com if you need additional information or have any
   39.26 + * questions.
   39.27 + */
   39.28 +
   39.29 +package java.lang;
   39.30 +
   39.31 +/**
   39.32 + * Thrown when an incompatible class change has occurred to some class
   39.33 + * definition. The definition of some class, on which the currently
   39.34 + * executing method depends, has since changed.
   39.35 + *
   39.36 + * @author  unascribed
   39.37 + * @since   JDK1.0
   39.38 + */
   39.39 +public
   39.40 +class IncompatibleClassChangeError extends LinkageError {
   39.41 +    private static final long serialVersionUID = -4914975503642802119L;
   39.42 +
   39.43 +    /**
   39.44 +     * Constructs an <code>IncompatibleClassChangeError</code> with no
   39.45 +     * detail message.
   39.46 +     */
   39.47 +    public IncompatibleClassChangeError () {
   39.48 +        super();
   39.49 +    }
   39.50 +
   39.51 +    /**
   39.52 +     * Constructs an <code>IncompatibleClassChangeError</code> with the
   39.53 +     * specified detail message.
   39.54 +     *
   39.55 +     * @param   s   the detail message.
   39.56 +     */
   39.57 +    public IncompatibleClassChangeError(String s) {
   39.58 +        super(s);
   39.59 +    }
   39.60 +}
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/emul/compact/src/main/java/java/lang/NoSuchFieldError.java	Tue Feb 05 17:04:22 2013 +0100
    40.3 @@ -0,0 +1,59 @@
    40.4 +/*
    40.5 + * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
    40.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    40.7 + *
    40.8 + * This code is free software; you can redistribute it and/or modify it
    40.9 + * under the terms of the GNU General Public License version 2 only, as
   40.10 + * published by the Free Software Foundation.  Oracle designates this
   40.11 + * particular file as subject to the "Classpath" exception as provided
   40.12 + * by Oracle in the LICENSE file that accompanied this code.
   40.13 + *
   40.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   40.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   40.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   40.17 + * version 2 for more details (a copy is included in the LICENSE file that
   40.18 + * accompanied this code).
   40.19 + *
   40.20 + * You should have received a copy of the GNU General Public License version
   40.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   40.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   40.23 + *
   40.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   40.25 + * or visit www.oracle.com if you need additional information or have any
   40.26 + * questions.
   40.27 + */
   40.28 +
   40.29 +package java.lang;
   40.30 +
   40.31 +/**
   40.32 + * Thrown if an application tries to access or modify a specified
   40.33 + * field of an object, and that object no longer has that field.
   40.34 + * <p>
   40.35 + * Normally, this error is caught by the compiler; this error can
   40.36 + * only occur at run time if the definition of a class has
   40.37 + * incompatibly changed.
   40.38 + *
   40.39 + * @author  unascribed
   40.40 + * @since   JDK1.0
   40.41 + */
   40.42 +public
   40.43 +class NoSuchFieldError extends IncompatibleClassChangeError {
   40.44 +    private static final long serialVersionUID = -3456430195886129035L;
   40.45 +
   40.46 +    /**
   40.47 +     * Constructs a <code>NoSuchFieldError</code> with no detail message.
   40.48 +     */
   40.49 +    public NoSuchFieldError() {
   40.50 +        super();
   40.51 +    }
   40.52 +
   40.53 +    /**
   40.54 +     * Constructs a <code>NoSuchFieldError</code> with the specified
   40.55 +     * detail message.
   40.56 +     *
   40.57 +     * @param   s   the detail message.
   40.58 +     */
   40.59 +    public NoSuchFieldError(String s) {
   40.60 +        super(s);
   40.61 +    }
   40.62 +}
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/emul/compact/src/main/java/java/lang/System.java	Tue Feb 05 17:04:22 2013 +0100
    41.3 @@ -0,0 +1,36 @@
    41.4 +/**
    41.5 + * Back 2 Browser Bytecode Translator
    41.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    41.7 + *
    41.8 + * This program is free software: you can redistribute it and/or modify
    41.9 + * it under the terms of the GNU General Public License as published by
   41.10 + * the Free Software Foundation, version 2 of the License.
   41.11 + *
   41.12 + * This program is distributed in the hope that it will be useful,
   41.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   41.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   41.15 + * GNU General Public License for more details.
   41.16 + *
   41.17 + * You should have received a copy of the GNU General Public License
   41.18 + * along with this program. Look for COPYING file in the top folder.
   41.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   41.20 + */
   41.21 +package java.lang;
   41.22 +
   41.23 +/** Poor man's re-implementation of most important System methods.
   41.24 + *
   41.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   41.26 + */
   41.27 +public class System {
   41.28 +    private System() {
   41.29 +    }
   41.30 +    
   41.31 +    public static void arraycopy(Object value, int srcBegin, Object dst, int dstBegin, int count) {
   41.32 +        org.apidesign.bck2brwsr.emul.lang.System.arraycopy(value, srcBegin, dst, dstBegin, count);
   41.33 +    }
   41.34 +    
   41.35 +    public static long currentTimeMillis() {
   41.36 +        return org.apidesign.bck2brwsr.emul.lang.System.currentTimeMillis();
   41.37 +    }
   41.38 +    
   41.39 +}
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/emul/compact/src/main/java/java/lang/ref/PhantomReference.java	Tue Feb 05 17:04:22 2013 +0100
    42.3 @@ -0,0 +1,83 @@
    42.4 +/*
    42.5 + * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
    42.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    42.7 + *
    42.8 + * This code is free software; you can redistribute it and/or modify it
    42.9 + * under the terms of the GNU General Public License version 2 only, as
   42.10 + * published by the Free Software Foundation.  Oracle designates this
   42.11 + * particular file as subject to the "Classpath" exception as provided
   42.12 + * by Oracle in the LICENSE file that accompanied this code.
   42.13 + *
   42.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   42.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   42.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   42.17 + * version 2 for more details (a copy is included in the LICENSE file that
   42.18 + * accompanied this code).
   42.19 + *
   42.20 + * You should have received a copy of the GNU General Public License version
   42.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   42.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   42.23 + *
   42.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   42.25 + * or visit www.oracle.com if you need additional information or have any
   42.26 + * questions.
   42.27 + */
   42.28 +
   42.29 +package java.lang.ref;
   42.30 +
   42.31 +
   42.32 +/**
   42.33 + * Phantom reference objects, which are enqueued after the collector
   42.34 + * determines that their referents may otherwise be reclaimed.  Phantom
   42.35 + * references are most often used for scheduling pre-mortem cleanup actions in
   42.36 + * a more flexible way than is possible with the Java finalization mechanism.
   42.37 + *
   42.38 + * <p> If the garbage collector determines at a certain point in time that the
   42.39 + * referent of a phantom reference is <a
   42.40 + * href="package-summary.html#reachability">phantom reachable</a>, then at that
   42.41 + * time or at some later time it will enqueue the reference.
   42.42 + *
   42.43 + * <p> In order to ensure that a reclaimable object remains so, the referent of
   42.44 + * a phantom reference may not be retrieved: The <code>get</code> method of a
   42.45 + * phantom reference always returns <code>null</code>.
   42.46 + *
   42.47 + * <p> Unlike soft and weak references, phantom references are not
   42.48 + * automatically cleared by the garbage collector as they are enqueued.  An
   42.49 + * object that is reachable via phantom references will remain so until all
   42.50 + * such references are cleared or themselves become unreachable.
   42.51 + *
   42.52 + * @author   Mark Reinhold
   42.53 + * @since    1.2
   42.54 + */
   42.55 +
   42.56 +public class PhantomReference<T> extends Reference<T> {
   42.57 +
   42.58 +    /**
   42.59 +     * Returns this reference object's referent.  Because the referent of a
   42.60 +     * phantom reference is always inaccessible, this method always returns
   42.61 +     * <code>null</code>.
   42.62 +     *
   42.63 +     * @return  <code>null</code>
   42.64 +     */
   42.65 +    public T get() {
   42.66 +        return null;
   42.67 +    }
   42.68 +
   42.69 +    /**
   42.70 +     * Creates a new phantom reference that refers to the given object and
   42.71 +     * is registered with the given queue.
   42.72 +     *
   42.73 +     * <p> It is possible to create a phantom reference with a <tt>null</tt>
   42.74 +     * queue, but such a reference is completely useless: Its <tt>get</tt>
   42.75 +     * method will always return null and, since it does not have a queue, it
   42.76 +     * will never be enqueued.
   42.77 +     *
   42.78 +     * @param referent the object the new phantom reference will refer to
   42.79 +     * @param q the queue with which the reference is to be registered,
   42.80 +     *          or <tt>null</tt> if registration is not required
   42.81 +     */
   42.82 +    public PhantomReference(T referent, ReferenceQueue<? super T> q) {
   42.83 +        super(referent, q);
   42.84 +    }
   42.85 +
   42.86 +}
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/emul/compact/src/main/java/java/lang/ref/Reference.java	Tue Feb 05 17:04:22 2013 +0100
    43.3 @@ -0,0 +1,185 @@
    43.4 +/*
    43.5 + * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
    43.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    43.7 + *
    43.8 + * This code is free software; you can redistribute it and/or modify it
    43.9 + * under the terms of the GNU General Public License version 2 only, as
   43.10 + * published by the Free Software Foundation.  Oracle designates this
   43.11 + * particular file as subject to the "Classpath" exception as provided
   43.12 + * by Oracle in the LICENSE file that accompanied this code.
   43.13 + *
   43.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   43.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   43.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   43.17 + * version 2 for more details (a copy is included in the LICENSE file that
   43.18 + * accompanied this code).
   43.19 + *
   43.20 + * You should have received a copy of the GNU General Public License version
   43.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   43.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   43.23 + *
   43.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   43.25 + * or visit www.oracle.com if you need additional information or have any
   43.26 + * questions.
   43.27 + */
   43.28 +
   43.29 +package java.lang.ref;
   43.30 +
   43.31 +
   43.32 +/**
   43.33 + * Abstract base class for reference objects.  This class defines the
   43.34 + * operations common to all reference objects.  Because reference objects are
   43.35 + * implemented in close cooperation with the garbage collector, this class may
   43.36 + * not be subclassed directly.
   43.37 + *
   43.38 + * @author   Mark Reinhold
   43.39 + * @since    1.2
   43.40 + */
   43.41 +
   43.42 +public abstract class Reference<T> {
   43.43 +
   43.44 +    /* A Reference instance is in one of four possible internal states:
   43.45 +     *
   43.46 +     *     Active: Subject to special treatment by the garbage collector.  Some
   43.47 +     *     time after the collector detects that the reachability of the
   43.48 +     *     referent has changed to the appropriate state, it changes the
   43.49 +     *     instance's state to either Pending or Inactive, depending upon
   43.50 +     *     whether or not the instance was registered with a queue when it was
   43.51 +     *     created.  In the former case it also adds the instance to the
   43.52 +     *     pending-Reference list.  Newly-created instances are Active.
   43.53 +     *
   43.54 +     *     Pending: An element of the pending-Reference list, waiting to be
   43.55 +     *     enqueued by the Reference-handler thread.  Unregistered instances
   43.56 +     *     are never in this state.
   43.57 +     *
   43.58 +     *     Enqueued: An element of the queue with which the instance was
   43.59 +     *     registered when it was created.  When an instance is removed from
   43.60 +     *     its ReferenceQueue, it is made Inactive.  Unregistered instances are
   43.61 +     *     never in this state.
   43.62 +     *
   43.63 +     *     Inactive: Nothing more to do.  Once an instance becomes Inactive its
   43.64 +     *     state will never change again.
   43.65 +     *
   43.66 +     * The state is encoded in the queue and next fields as follows:
   43.67 +     *
   43.68 +     *     Active: queue = ReferenceQueue with which instance is registered, or
   43.69 +     *     ReferenceQueue.NULL if it was not registered with a queue; next =
   43.70 +     *     null.
   43.71 +     *
   43.72 +     *     Pending: queue = ReferenceQueue with which instance is registered;
   43.73 +     *     next = Following instance in queue, or this if at end of list.
   43.74 +     *
   43.75 +     *     Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance
   43.76 +     *     in queue, or this if at end of list.
   43.77 +     *
   43.78 +     *     Inactive: queue = ReferenceQueue.NULL; next = this.
   43.79 +     *
   43.80 +     * With this scheme the collector need only examine the next field in order
   43.81 +     * to determine whether a Reference instance requires special treatment: If
   43.82 +     * the next field is null then the instance is active; if it is non-null,
   43.83 +     * then the collector should treat the instance normally.
   43.84 +     *
   43.85 +     * To ensure that concurrent collector can discover active Reference
   43.86 +     * objects without interfering with application threads that may apply
   43.87 +     * the enqueue() method to those objects, collectors should link
   43.88 +     * discovered objects through the discovered field.
   43.89 +     */
   43.90 +
   43.91 +    private T referent;         /* Treated specially by GC */
   43.92 +
   43.93 +    ReferenceQueue<? super T> queue;
   43.94 +
   43.95 +    Reference next;
   43.96 +    transient private Reference<T> discovered;  /* used by VM */
   43.97 +
   43.98 +
   43.99 +    /* Object used to synchronize with the garbage collector.  The collector
  43.100 +     * must acquire this lock at the beginning of each collection cycle.  It is
  43.101 +     * therefore critical that any code holding this lock complete as quickly
  43.102 +     * as possible, allocate no new objects, and avoid calling user code.
  43.103 +     */
  43.104 +    static private class Lock { };
  43.105 +    private static Lock lock = new Lock();
  43.106 +
  43.107 +
  43.108 +    /* List of References waiting to be enqueued.  The collector adds
  43.109 +     * References to this list, while the Reference-handler thread removes
  43.110 +     * them.  This list is protected by the above lock object.
  43.111 +     */
  43.112 +    private static Reference pending = null;
  43.113 +
  43.114 +
  43.115 +
  43.116 +    /* -- Referent accessor and setters -- */
  43.117 +
  43.118 +    /**
  43.119 +     * Returns this reference object's referent.  If this reference object has
  43.120 +     * been cleared, either by the program or by the garbage collector, then
  43.121 +     * this method returns <code>null</code>.
  43.122 +     *
  43.123 +     * @return   The object to which this reference refers, or
  43.124 +     *           <code>null</code> if this reference object has been cleared
  43.125 +     */
  43.126 +    public T get() {
  43.127 +        return this.referent;
  43.128 +    }
  43.129 +
  43.130 +    /**
  43.131 +     * Clears this reference object.  Invoking this method will not cause this
  43.132 +     * object to be enqueued.
  43.133 +     *
  43.134 +     * <p> This method is invoked only by Java code; when the garbage collector
  43.135 +     * clears references it does so directly, without invoking this method.
  43.136 +     */
  43.137 +    public void clear() {
  43.138 +        this.referent = null;
  43.139 +    }
  43.140 +
  43.141 +
  43.142 +    /* -- Queue operations -- */
  43.143 +
  43.144 +    /**
  43.145 +     * Tells whether or not this reference object has been enqueued, either by
  43.146 +     * the program or by the garbage collector.  If this reference object was
  43.147 +     * not registered with a queue when it was created, then this method will
  43.148 +     * always return <code>false</code>.
  43.149 +     *
  43.150 +     * @return   <code>true</code> if and only if this reference object has
  43.151 +     *           been enqueued
  43.152 +     */
  43.153 +    public boolean isEnqueued() {
  43.154 +        /* In terms of the internal states, this predicate actually tests
  43.155 +           whether the instance is either Pending or Enqueued */
  43.156 +        synchronized (this) {
  43.157 +            return (this.queue != ReferenceQueue.NULL) && (this.next != null);
  43.158 +        }
  43.159 +    }
  43.160 +
  43.161 +    /**
  43.162 +     * Adds this reference object to the queue with which it is registered,
  43.163 +     * if any.
  43.164 +     *
  43.165 +     * <p> This method is invoked only by Java code; when the garbage collector
  43.166 +     * enqueues references it does so directly, without invoking this method.
  43.167 +     *
  43.168 +     * @return   <code>true</code> if this reference object was successfully
  43.169 +     *           enqueued; <code>false</code> if it was already enqueued or if
  43.170 +     *           it was not registered with a queue when it was created
  43.171 +     */
  43.172 +    public boolean enqueue() {
  43.173 +        return this.queue.enqueue(this);
  43.174 +    }
  43.175 +
  43.176 +
  43.177 +    /* -- Constructors -- */
  43.178 +
  43.179 +    Reference(T referent) {
  43.180 +        this(referent, null);
  43.181 +    }
  43.182 +
  43.183 +    Reference(T referent, ReferenceQueue<? super T> queue) {
  43.184 +        this.referent = referent;
  43.185 +        this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
  43.186 +    }
  43.187 +
  43.188 +}
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/emul/compact/src/main/java/java/lang/ref/ReferenceQueue.java	Tue Feb 05 17:04:22 2013 +0100
    44.3 @@ -0,0 +1,148 @@
    44.4 +/*
    44.5 + * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
    44.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    44.7 + *
    44.8 + * This code is free software; you can redistribute it and/or modify it
    44.9 + * under the terms of the GNU General Public License version 2 only, as
   44.10 + * published by the Free Software Foundation.  Oracle designates this
   44.11 + * particular file as subject to the "Classpath" exception as provided
   44.12 + * by Oracle in the LICENSE file that accompanied this code.
   44.13 + *
   44.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   44.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   44.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   44.17 + * version 2 for more details (a copy is included in the LICENSE file that
   44.18 + * accompanied this code).
   44.19 + *
   44.20 + * You should have received a copy of the GNU General Public License version
   44.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   44.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   44.23 + *
   44.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   44.25 + * or visit www.oracle.com if you need additional information or have any
   44.26 + * questions.
   44.27 + */
   44.28 +
   44.29 +package java.lang.ref;
   44.30 +
   44.31 +/**
   44.32 + * Reference queues, to which registered reference objects are appended by the
   44.33 + * garbage collector after the appropriate reachability changes are detected.
   44.34 + *
   44.35 + * @author   Mark Reinhold
   44.36 + * @since    1.2
   44.37 + */
   44.38 +
   44.39 +public class ReferenceQueue<T> {
   44.40 +
   44.41 +    /**
   44.42 +     * Constructs a new reference-object queue.
   44.43 +     */
   44.44 +    public ReferenceQueue() { }
   44.45 +
   44.46 +    private static class Null extends ReferenceQueue {
   44.47 +        boolean enqueue(Reference r) {
   44.48 +            return false;
   44.49 +        }
   44.50 +    }
   44.51 +
   44.52 +    static ReferenceQueue NULL = new Null();
   44.53 +    static ReferenceQueue ENQUEUED = new Null();
   44.54 +
   44.55 +    static private class Lock { };
   44.56 +    private Lock lock = new Lock();
   44.57 +    private volatile Reference<? extends T> head = null;
   44.58 +    private long queueLength = 0;
   44.59 +
   44.60 +    boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
   44.61 +        synchronized (r) {
   44.62 +            if (r.queue == ENQUEUED) return false;
   44.63 +            synchronized (lock) {
   44.64 +                r.queue = ENQUEUED;
   44.65 +                r.next = (head == null) ? r : head;
   44.66 +                head = r;
   44.67 +                queueLength++;
   44.68 +                lock.notifyAll();
   44.69 +                return true;
   44.70 +            }
   44.71 +        }
   44.72 +    }
   44.73 +
   44.74 +    private Reference<? extends T> reallyPoll() {       /* Must hold lock */
   44.75 +        if (head != null) {
   44.76 +            Reference<? extends T> r = head;
   44.77 +            head = (r.next == r) ? null : r.next;
   44.78 +            r.queue = NULL;
   44.79 +            r.next = r;
   44.80 +            queueLength--;
   44.81 +            return r;
   44.82 +        }
   44.83 +        return null;
   44.84 +    }
   44.85 +
   44.86 +    /**
   44.87 +     * Polls this queue to see if a reference object is available.  If one is
   44.88 +     * available without further delay then it is removed from the queue and
   44.89 +     * returned.  Otherwise this method immediately returns <tt>null</tt>.
   44.90 +     *
   44.91 +     * @return  A reference object, if one was immediately available,
   44.92 +     *          otherwise <code>null</code>
   44.93 +     */
   44.94 +    public Reference<? extends T> poll() {
   44.95 +        if (head == null)
   44.96 +            return null;
   44.97 +        synchronized (lock) {
   44.98 +            return reallyPoll();
   44.99 +        }
  44.100 +    }
  44.101 +
  44.102 +    /**
  44.103 +     * Removes the next reference object in this queue, blocking until either
  44.104 +     * one becomes available or the given timeout period expires.
  44.105 +     *
  44.106 +     * <p> This method does not offer real-time guarantees: It schedules the
  44.107 +     * timeout as if by invoking the {@link Object#wait(long)} method.
  44.108 +     *
  44.109 +     * @param  timeout  If positive, block for up to <code>timeout</code>
  44.110 +     *                  milliseconds while waiting for a reference to be
  44.111 +     *                  added to this queue.  If zero, block indefinitely.
  44.112 +     *
  44.113 +     * @return  A reference object, if one was available within the specified
  44.114 +     *          timeout period, otherwise <code>null</code>
  44.115 +     *
  44.116 +     * @throws  IllegalArgumentException
  44.117 +     *          If the value of the timeout argument is negative
  44.118 +     *
  44.119 +     * @throws  InterruptedException
  44.120 +     *          If the timeout wait is interrupted
  44.121 +     */
  44.122 +    public Reference<? extends T> remove(long timeout)
  44.123 +        throws IllegalArgumentException, InterruptedException
  44.124 +    {
  44.125 +        if (timeout < 0) {
  44.126 +            throw new IllegalArgumentException("Negative timeout value");
  44.127 +        }
  44.128 +        synchronized (lock) {
  44.129 +            Reference<? extends T> r = reallyPoll();
  44.130 +            if (r != null) return r;
  44.131 +            for (;;) {
  44.132 +                lock.wait(timeout);
  44.133 +                r = reallyPoll();
  44.134 +                if (r != null) return r;
  44.135 +                if (timeout != 0) return null;
  44.136 +            }
  44.137 +        }
  44.138 +    }
  44.139 +
  44.140 +    /**
  44.141 +     * Removes the next reference object in this queue, blocking until one
  44.142 +     * becomes available.
  44.143 +     *
  44.144 +     * @return A reference object, blocking until one becomes available
  44.145 +     * @throws  InterruptedException  If the wait is interrupted
  44.146 +     */
  44.147 +    public Reference<? extends T> remove() throws InterruptedException {
  44.148 +        return remove(0);
  44.149 +    }
  44.150 +
  44.151 +}
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/emul/compact/src/main/java/java/lang/ref/SoftReference.java	Tue Feb 05 17:04:22 2013 +0100
    45.3 @@ -0,0 +1,118 @@
    45.4 +/*
    45.5 + * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
    45.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    45.7 + *
    45.8 + * This code is free software; you can redistribute it and/or modify it
    45.9 + * under the terms of the GNU General Public License version 2 only, as
   45.10 + * published by the Free Software Foundation.  Oracle designates this
   45.11 + * particular file as subject to the "Classpath" exception as provided
   45.12 + * by Oracle in the LICENSE file that accompanied this code.
   45.13 + *
   45.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   45.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   45.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   45.17 + * version 2 for more details (a copy is included in the LICENSE file that
   45.18 + * accompanied this code).
   45.19 + *
   45.20 + * You should have received a copy of the GNU General Public License version
   45.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   45.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   45.23 + *
   45.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   45.25 + * or visit www.oracle.com if you need additional information or have any
   45.26 + * questions.
   45.27 + */
   45.28 +
   45.29 +package java.lang.ref;
   45.30 +
   45.31 +
   45.32 +/**
   45.33 + * Soft reference objects, which are cleared at the discretion of the garbage
   45.34 + * collector in response to memory demand.  Soft references are most often used
   45.35 + * to implement memory-sensitive caches.
   45.36 + *
   45.37 + * <p> Suppose that the garbage collector determines at a certain point in time
   45.38 + * that an object is <a href="package-summary.html#reachability">softly
   45.39 + * reachable</a>.  At that time it may choose to clear atomically all soft
   45.40 + * references to that object and all soft references to any other
   45.41 + * softly-reachable objects from which that object is reachable through a chain
   45.42 + * of strong references.  At the same time or at some later time it will
   45.43 + * enqueue those newly-cleared soft references that are registered with
   45.44 + * reference queues.
   45.45 + *
   45.46 + * <p> All soft references to softly-reachable objects are guaranteed to have
   45.47 + * been cleared before the virtual machine throws an
   45.48 + * <code>OutOfMemoryError</code>.  Otherwise no constraints are placed upon the
   45.49 + * time at which a soft reference will be cleared or the order in which a set
   45.50 + * of such references to different objects will be cleared.  Virtual machine
   45.51 + * implementations are, however, encouraged to bias against clearing
   45.52 + * recently-created or recently-used soft references.
   45.53 + *
   45.54 + * <p> Direct instances of this class may be used to implement simple caches;
   45.55 + * this class or derived subclasses may also be used in larger data structures
   45.56 + * to implement more sophisticated caches.  As long as the referent of a soft
   45.57 + * reference is strongly reachable, that is, is actually in use, the soft
   45.58 + * reference will not be cleared.  Thus a sophisticated cache can, for example,
   45.59 + * prevent its most recently used entries from being discarded by keeping
   45.60 + * strong referents to those entries, leaving the remaining entries to be
   45.61 + * discarded at the discretion of the garbage collector.
   45.62 + *
   45.63 + * @author   Mark Reinhold
   45.64 + * @since    1.2
   45.65 + */
   45.66 +
   45.67 +public class SoftReference<T> extends Reference<T> {
   45.68 +
   45.69 +    /**
   45.70 +     * Timestamp clock, updated by the garbage collector
   45.71 +     */
   45.72 +    static private long clock;
   45.73 +
   45.74 +    /**
   45.75 +     * Timestamp updated by each invocation of the get method.  The VM may use
   45.76 +     * this field when selecting soft references to be cleared, but it is not
   45.77 +     * required to do so.
   45.78 +     */
   45.79 +    private long timestamp;
   45.80 +
   45.81 +    /**
   45.82 +     * Creates a new soft reference that refers to the given object.  The new
   45.83 +     * reference is not registered with any queue.
   45.84 +     *
   45.85 +     * @param referent object the new soft reference will refer to
   45.86 +     */
   45.87 +    public SoftReference(T referent) {
   45.88 +        super(referent);
   45.89 +        this.timestamp = clock;
   45.90 +    }
   45.91 +
   45.92 +    /**
   45.93 +     * Creates a new soft reference that refers to the given object and is
   45.94 +     * registered with the given queue.
   45.95 +     *
   45.96 +     * @param referent object the new soft reference will refer to
   45.97 +     * @param q the queue with which the reference is to be registered,
   45.98 +     *          or <tt>null</tt> if registration is not required
   45.99 +     *
  45.100 +     */
  45.101 +    public SoftReference(T referent, ReferenceQueue<? super T> q) {
  45.102 +        super(referent, q);
  45.103 +        this.timestamp = clock;
  45.104 +    }
  45.105 +
  45.106 +    /**
  45.107 +     * Returns this reference object's referent.  If this reference object has
  45.108 +     * been cleared, either by the program or by the garbage collector, then
  45.109 +     * this method returns <code>null</code>.
  45.110 +     *
  45.111 +     * @return   The object to which this reference refers, or
  45.112 +     *           <code>null</code> if this reference object has been cleared
  45.113 +     */
  45.114 +    public T get() {
  45.115 +        T o = super.get();
  45.116 +        if (o != null && this.timestamp != clock)
  45.117 +            this.timestamp = clock;
  45.118 +        return o;
  45.119 +    }
  45.120 +
  45.121 +}
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/emul/compact/src/main/java/java/lang/ref/WeakReference.java	Tue Feb 05 17:04:22 2013 +0100
    46.3 @@ -0,0 +1,72 @@
    46.4 +/*
    46.5 + * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
    46.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    46.7 + *
    46.8 + * This code is free software; you can redistribute it and/or modify it
    46.9 + * under the terms of the GNU General Public License version 2 only, as
   46.10 + * published by the Free Software Foundation.  Oracle designates this
   46.11 + * particular file as subject to the "Classpath" exception as provided
   46.12 + * by Oracle in the LICENSE file that accompanied this code.
   46.13 + *
   46.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   46.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   46.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   46.17 + * version 2 for more details (a copy is included in the LICENSE file that
   46.18 + * accompanied this code).
   46.19 + *
   46.20 + * You should have received a copy of the GNU General Public License version
   46.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   46.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   46.23 + *
   46.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   46.25 + * or visit www.oracle.com if you need additional information or have any
   46.26 + * questions.
   46.27 + */
   46.28 +
   46.29 +package java.lang.ref;
   46.30 +
   46.31 +
   46.32 +/**
   46.33 + * Weak reference objects, which do not prevent their referents from being
   46.34 + * made finalizable, finalized, and then reclaimed.  Weak references are most
   46.35 + * often used to implement canonicalizing mappings.
   46.36 + *
   46.37 + * <p> Suppose that the garbage collector determines at a certain point in time
   46.38 + * that an object is <a href="package-summary.html#reachability">weakly
   46.39 + * reachable</a>.  At that time it will atomically clear all weak references to
   46.40 + * that object and all weak references to any other weakly-reachable objects
   46.41 + * from which that object is reachable through a chain of strong and soft
   46.42 + * references.  At the same time it will declare all of the formerly
   46.43 + * weakly-reachable objects to be finalizable.  At the same time or at some
   46.44 + * later time it will enqueue those newly-cleared weak references that are
   46.45 + * registered with reference queues.
   46.46 + *
   46.47 + * @author   Mark Reinhold
   46.48 + * @since    1.2
   46.49 + */
   46.50 +
   46.51 +public class WeakReference<T> extends Reference<T> {
   46.52 +
   46.53 +    /**
   46.54 +     * Creates a new weak reference that refers to the given object.  The new
   46.55 +     * reference is not registered with any queue.
   46.56 +     *
   46.57 +     * @param referent object the new weak reference will refer to
   46.58 +     */
   46.59 +    public WeakReference(T referent) {
   46.60 +        super(referent);
   46.61 +    }
   46.62 +
   46.63 +    /**
   46.64 +     * Creates a new weak reference that refers to the given object and is
   46.65 +     * registered with the given queue.
   46.66 +     *
   46.67 +     * @param referent object the new weak reference will refer to
   46.68 +     * @param q the queue with which the reference is to be registered,
   46.69 +     *          or <tt>null</tt> if registration is not required
   46.70 +     */
   46.71 +    public WeakReference(T referent, ReferenceQueue<? super T> q) {
   46.72 +        super(referent, q);
   46.73 +    }
   46.74 +
   46.75 +}
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/emul/compact/src/main/java/java/lang/ref/package.html	Tue Feb 05 17:04:22 2013 +0100
    47.3 @@ -0,0 +1,147 @@
    47.4 +<!--
    47.5 + Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved.
    47.6 + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    47.7 +
    47.8 + This code is free software; you can redistribute it and/or modify it
    47.9 + under the terms of the GNU General Public License version 2 only, as
   47.10 + published by the Free Software Foundation.  Oracle designates this
   47.11 + particular file as subject to the "Classpath" exception as provided
   47.12 + by Oracle in the LICENSE file that accompanied this code.
   47.13 +
   47.14 + This code is distributed in the hope that it will be useful, but WITHOUT
   47.15 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   47.16 + FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   47.17 + version 2 for more details (a copy is included in the LICENSE file that
   47.18 + accompanied this code).
   47.19 +
   47.20 + You should have received a copy of the GNU General Public License version
   47.21 + 2 along with this work; if not, write to the Free Software Foundation,
   47.22 + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   47.23 +
   47.24 + Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   47.25 + or visit www.oracle.com if you need additional information or have any
   47.26 + questions.
   47.27 +-->
   47.28 +
   47.29 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
   47.30 +<html>
   47.31 +<body bgcolor="white">
   47.32 +
   47.33 +
   47.34 +Provides reference-object classes, which support a limited degree of
   47.35 +interaction with the garbage collector.  A program may use a reference object
   47.36 +to maintain a reference to some other object in such a way that the latter
   47.37 +object may still be reclaimed by the collector.  A program may also arrange to
   47.38 +be notified some time after the collector has determined that the reachability
   47.39 +of a given object has changed.
   47.40 +
   47.41 +
   47.42 +<h2>Package Specification</h2>
   47.43 +
   47.44 +A <em>reference object</em> encapsulates a reference to some other object so
   47.45 +that the reference itself may be examined and manipulated like any other
   47.46 +object.  Three types of reference objects are provided, each weaker than the
   47.47 +last: <em>soft</em>, <em>weak</em>, and <em>phantom</em>.  Each type
   47.48 +corresponds to a different level of reachability, as defined below.  Soft
   47.49 +references are for implementing memory-sensitive caches, weak references are
   47.50 +for implementing canonicalizing mappings that do not prevent their keys (or
   47.51 +values) from being reclaimed, and phantom references are for scheduling
   47.52 +pre-mortem cleanup actions in a more flexible way than is possible with the
   47.53 +Java finalization mechanism.
   47.54 +
   47.55 +<p> Each reference-object type is implemented by a subclass of the abstract
   47.56 +base <code>{@link java.lang.ref.Reference}</code> class.  An instance of one of
   47.57 +these subclasses encapsulates a single reference to a particular object, called
   47.58 +the <em>referent</em>.  Every reference object provides methods for getting and
   47.59 +clearing the reference.  Aside from the clearing operation reference objects
   47.60 +are otherwise immutable, so no <code>set</code> operation is provided.  A
   47.61 +program may further subclass these subclasses, adding whatever fields and
   47.62 +methods are required for its purposes, or it may use these subclasses without
   47.63 +change.
   47.64 +
   47.65 +
   47.66 +<h3>Notification</h3>
   47.67 +
   47.68 +A program may request to be notified of changes in an object's reachability by
   47.69 +<em>registering</em> an appropriate reference object with a <em>reference
   47.70 +queue</em> at the time the reference object is created.  Some time after the
   47.71 +garbage collector determines that the reachability of the referent has changed
   47.72 +to the value corresponding to the type of the reference, it will add the
   47.73 +reference to the associated queue.  At this point, the reference is considered
   47.74 +to be <em>enqueued</em>.  The program may remove references from a queue either
   47.75 +by polling or by blocking until a reference becomes available.  Reference
   47.76 +queues are implemented by the <code>{@link java.lang.ref.ReferenceQueue}</code>
   47.77 +class.
   47.78 +
   47.79 +<p> The relationship between a registered reference object and its queue is
   47.80 +one-sided.  That is, a queue does not keep track of the references that are
   47.81 +registered with it.  If a registered reference becomes unreachable itself, then
   47.82 +it will never be enqueued.  It is the responsibility of the program using
   47.83 +reference objects to ensure that the objects remain reachable for as long as
   47.84 +the program is interested in their referents.
   47.85 +
   47.86 +<p> While some programs will choose to dedicate a thread to removing reference
   47.87 +objects from one or more queues and processing them, this is by no means
   47.88 +necessary.  A tactic that often works well is to examine a reference queue in
   47.89 +the course of performing some other fairly-frequent action.  For example, a
   47.90 +hashtable that uses weak references to implement weak keys could poll its
   47.91 +reference queue each time the table is accessed.  This is how the <code>{@link
   47.92 +java.util.WeakHashMap}</code> class works.  Because the <code>{@link
   47.93 +java.lang.ref.ReferenceQueue#poll ReferenceQueue.poll}</code> method simply
   47.94 +checks an internal data structure, this check will add little overhead to the
   47.95 +hashtable access methods.
   47.96 +
   47.97 +
   47.98 +<h3>Automatically-cleared references</h3>
   47.99 +
  47.100 +Soft and weak references are automatically cleared by the collector before
  47.101 +being added to the queues with which they are registered, if any.  Therefore
  47.102 +soft and weak references need not be registered with a queue in order to be
  47.103 +useful, while phantom references do.  An object that is reachable via phantom
  47.104 +references will remain so until all such references are cleared or themselves
  47.105 +become unreachable.
  47.106 +
  47.107 +
  47.108 +<a name="reachability"></a>
  47.109 +<h3>Reachability</h3>
  47.110 +
  47.111 +Going from strongest to weakest, the different levels of reachability reflect
  47.112 +the life cycle of an object.  They are operationally defined as follows:
  47.113 +
  47.114 +<ul>
  47.115 +
  47.116 +<li> An object is <em>strongly reachable</em> if it can be reached by some
  47.117 +thread without traversing any reference objects.  A newly-created object is
  47.118 +strongly reachable by the thread that created it.
  47.119 +
  47.120 +<li> An object is <em>softly reachable</em> if it is not strongly reachable but
  47.121 +can be reached by traversing a soft reference.
  47.122 +
  47.123 +<li> An object is <em>weakly reachable</em> if it is neither strongly nor
  47.124 +softly reachable but can be reached by traversing a weak reference.  When the
  47.125 +weak references to a weakly-reachable object are cleared, the object becomes
  47.126 +eligible for finalization.
  47.127 +
  47.128 +<li> An object is <em>phantom reachable</em> if it is neither strongly, softly,
  47.129 +nor weakly reachable, it has been finalized, and some phantom reference refers
  47.130 +to it.
  47.131 +
  47.132 +<li> Finally, an object is <em>unreachable</em>, and therefore eligible for
  47.133 +reclamation, when it is not reachable in any of the above ways.
  47.134 +
  47.135 +</ul>
  47.136 +
  47.137 +
  47.138 +@author	  Mark Reinhold
  47.139 +@since	  1.2
  47.140 +
  47.141 +<!--
  47.142 +<h2>Related Documentation</h2>
  47.143 +
  47.144 +For overviews, tutorials, examples, guides, and tool documentation, please see:
  47.145 +<ul>
  47.146 +  <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a>
  47.147 +</ul>
  47.148 +-->
  47.149 +</body>
  47.150 +</html>
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/emul/compact/src/main/java/java/util/AbstractQueue.java	Tue Feb 05 17:04:22 2013 +0100
    48.3 @@ -0,0 +1,192 @@
    48.4 +/*
    48.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    48.6 + *
    48.7 + * This code is free software; you can redistribute it and/or modify it
    48.8 + * under the terms of the GNU General Public License version 2 only, as
    48.9 + * published by the Free Software Foundation.  Oracle designates this
   48.10 + * particular file as subject to the "Classpath" exception as provided
   48.11 + * by Oracle in the LICENSE file that accompanied this code.
   48.12 + *
   48.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
   48.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   48.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   48.16 + * version 2 for more details (a copy is included in the LICENSE file that
   48.17 + * accompanied this code).
   48.18 + *
   48.19 + * You should have received a copy of the GNU General Public License version
   48.20 + * 2 along with this work; if not, write to the Free Software Foundation,
   48.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   48.22 + *
   48.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   48.24 + * or visit www.oracle.com if you need additional information or have any
   48.25 + * questions.
   48.26 + */
   48.27 +
   48.28 +/*
   48.29 + * This file is available under and governed by the GNU General Public
   48.30 + * License version 2 only, as published by the Free Software Foundation.
   48.31 + * However, the following notice accompanied the original version of this
   48.32 + * file:
   48.33 + *
   48.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
   48.35 + * Expert Group and released to the public domain, as explained at
   48.36 + * http://creativecommons.org/publicdomain/zero/1.0/
   48.37 + */
   48.38 +
   48.39 +package java.util;
   48.40 +
   48.41 +/**
   48.42 + * This class provides skeletal implementations of some {@link Queue}
   48.43 + * operations. The implementations in this class are appropriate when
   48.44 + * the base implementation does <em>not</em> allow <tt>null</tt>
   48.45 + * elements.  Methods {@link #add add}, {@link #remove remove}, and
   48.46 + * {@link #element element} are based on {@link #offer offer}, {@link
   48.47 + * #poll poll}, and {@link #peek peek}, respectively, but throw
   48.48 + * exceptions instead of indicating failure via <tt>false</tt> or
   48.49 + * <tt>null</tt> returns.
   48.50 + *
   48.51 + * <p>A <tt>Queue</tt> implementation that extends this class must
   48.52 + * minimally define a method {@link Queue#offer} which does not permit
   48.53 + * insertion of <tt>null</tt> elements, along with methods {@link
   48.54 + * Queue#peek}, {@link Queue#poll}, {@link Collection#size}, and
   48.55 + * {@link Collection#iterator}.  Typically, additional methods will be
   48.56 + * overridden as well.  If these requirements cannot be met, consider
   48.57 + * instead subclassing {@link AbstractCollection}.
   48.58 + *
   48.59 + * <p>This class is a member of the
   48.60 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
   48.61 + * Java Collections Framework</a>.
   48.62 + *
   48.63 + * @since 1.5
   48.64 + * @author Doug Lea
   48.65 + * @param <E> the type of elements held in this collection
   48.66 + */
   48.67 +public abstract class AbstractQueue<E>
   48.68 +    extends AbstractCollection<E>
   48.69 +    implements Queue<E> {
   48.70 +
   48.71 +    /**
   48.72 +     * Constructor for use by subclasses.
   48.73 +     */
   48.74 +    protected AbstractQueue() {
   48.75 +    }
   48.76 +
   48.77 +    /**
   48.78 +     * Inserts the specified element into this queue if it is possible to do so
   48.79 +     * immediately without violating capacity restrictions, returning
   48.80 +     * <tt>true</tt> upon success and throwing an <tt>IllegalStateException</tt>
   48.81 +     * if no space is currently available.
   48.82 +     *
   48.83 +     * <p>This implementation returns <tt>true</tt> if <tt>offer</tt> succeeds,
   48.84 +     * else throws an <tt>IllegalStateException</tt>.
   48.85 +     *
   48.86 +     * @param e the element to add
   48.87 +     * @return <tt>true</tt> (as specified by {@link Collection#add})
   48.88 +     * @throws IllegalStateException if the element cannot be added at this
   48.89 +     *         time due to capacity restrictions
   48.90 +     * @throws ClassCastException if the class of the specified element
   48.91 +     *         prevents it from being added to this queue
   48.92 +     * @throws NullPointerException if the specified element is null and
   48.93 +     *         this queue does not permit null elements
   48.94 +     * @throws IllegalArgumentException if some property of this element
   48.95 +     *         prevents it from being added to this queue
   48.96 +     */
   48.97 +    public boolean add(E e) {
   48.98 +        if (offer(e))
   48.99 +            return true;
  48.100 +        else
  48.101 +            throw new IllegalStateException("Queue full");
  48.102 +    }
  48.103 +
  48.104 +    /**
  48.105 +     * Retrieves and removes the head of this queue.  This method differs
  48.106 +     * from {@link #poll poll} only in that it throws an exception if this
  48.107 +     * queue is empty.
  48.108 +     *
  48.109 +     * <p>This implementation returns the result of <tt>poll</tt>
  48.110 +     * unless the queue is empty.
  48.111 +     *
  48.112 +     * @return the head of this queue
  48.113 +     * @throws NoSuchElementException if this queue is empty
  48.114 +     */
  48.115 +    public E remove() {
  48.116 +        E x = poll();
  48.117 +        if (x != null)
  48.118 +            return x;
  48.119 +        else
  48.120 +            throw new NoSuchElementException();
  48.121 +    }
  48.122 +
  48.123 +    /**
  48.124 +     * Retrieves, but does not remove, the head of this queue.  This method
  48.125 +     * differs from {@link #peek peek} only in that it throws an exception if
  48.126 +     * this queue is empty.
  48.127 +     *
  48.128 +     * <p>This implementation returns the result of <tt>peek</tt>
  48.129 +     * unless the queue is empty.
  48.130 +     *
  48.131 +     * @return the head of this queue
  48.132 +     * @throws NoSuchElementException if this queue is empty
  48.133 +     */
  48.134 +    public E element() {
  48.135 +        E x = peek();
  48.136 +        if (x != null)
  48.137 +            return x;
  48.138 +        else
  48.139 +            throw new NoSuchElementException();
  48.140 +    }
  48.141 +
  48.142 +    /**
  48.143 +     * Removes all of the elements from this queue.
  48.144 +     * The queue will be empty after this call returns.
  48.145 +     *
  48.146 +     * <p>This implementation repeatedly invokes {@link #poll poll} until it
  48.147 +     * returns <tt>null</tt>.
  48.148 +     */
  48.149 +    public void clear() {
  48.150 +        while (poll() != null)
  48.151 +            ;
  48.152 +    }
  48.153 +
  48.154 +    /**
  48.155 +     * Adds all of the elements in the specified collection to this
  48.156 +     * queue.  Attempts to addAll of a queue to itself result in
  48.157 +     * <tt>IllegalArgumentException</tt>. Further, the behavior of
  48.158 +     * this operation is undefined if the specified collection is
  48.159 +     * modified while the operation is in progress.
  48.160 +     *
  48.161 +     * <p>This implementation iterates over the specified collection,
  48.162 +     * and adds each element returned by the iterator to this
  48.163 +     * queue, in turn.  A runtime exception encountered while
  48.164 +     * trying to add an element (including, in particular, a
  48.165 +     * <tt>null</tt> element) may result in only some of the elements
  48.166 +     * having been successfully added when the associated exception is
  48.167 +     * thrown.
  48.168 +     *
  48.169 +     * @param c collection containing elements to be added to this queue
  48.170 +     * @return <tt>true</tt> if this queue changed as a result of the call
  48.171 +     * @throws ClassCastException if the class of an element of the specified
  48.172 +     *         collection prevents it from being added to this queue
  48.173 +     * @throws NullPointerException if the specified collection contains a
  48.174 +     *         null element and this queue does not permit null elements,
  48.175 +     *         or if the specified collection is null
  48.176 +     * @throws IllegalArgumentException if some property of an element of the
  48.177 +     *         specified collection prevents it from being added to this
  48.178 +     *         queue, or if the specified collection is this queue
  48.179 +     * @throws IllegalStateException if not all the elements can be added at
  48.180 +     *         this time due to insertion restrictions
  48.181 +     * @see #add(Object)
  48.182 +     */
  48.183 +    public boolean addAll(Collection<? extends E> c) {
  48.184 +        if (c == null)
  48.185 +            throw new NullPointerException();
  48.186 +        if (c == this)
  48.187 +            throw new IllegalArgumentException();
  48.188 +        boolean modified = false;
  48.189 +        for (E e : c)
  48.190 +            if (add(e))
  48.191 +                modified = true;
  48.192 +        return modified;
  48.193 +    }
  48.194 +
  48.195 +}
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/emul/compact/src/main/java/java/util/AbstractSequentialList.java	Tue Feb 05 17:04:22 2013 +0100
    49.3 @@ -0,0 +1,253 @@
    49.4 +/*
    49.5 + * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
    49.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    49.7 + *
    49.8 + * This code is free software; you can redistribute it and/or modify it
    49.9 + * under the terms of the GNU General Public License version 2 only, as
   49.10 + * published by the Free Software Foundation.  Oracle designates this
   49.11 + * particular file as subject to the "Classpath" exception as provided
   49.12 + * by Oracle in the LICENSE file that accompanied this code.
   49.13 + *
   49.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   49.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   49.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   49.17 + * version 2 for more details (a copy is included in the LICENSE file that
   49.18 + * accompanied this code).
   49.19 + *
   49.20 + * You should have received a copy of the GNU General Public License version
   49.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   49.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   49.23 + *
   49.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   49.25 + * or visit www.oracle.com if you need additional information or have any
   49.26 + * questions.
   49.27 + */
   49.28 +
   49.29 +package java.util;
   49.30 +
   49.31 +/**
   49.32 + * This class provides a skeletal implementation of the <tt>List</tt>
   49.33 + * interface to minimize the effort required to implement this interface
   49.34 + * backed by a "sequential access" data store (such as a linked list).  For
   49.35 + * random access data (such as an array), <tt>AbstractList</tt> should be used
   49.36 + * in preference to this class.<p>
   49.37 + *
   49.38 + * This class is the opposite of the <tt>AbstractList</tt> class in the sense
   49.39 + * that it implements the "random access" methods (<tt>get(int index)</tt>,
   49.40 + * <tt>set(int index, E element)</tt>, <tt>add(int index, E element)</tt> and
   49.41 + * <tt>remove(int index)</tt>) on top of the list's list iterator, instead of
   49.42 + * the other way around.<p>
   49.43 + *
   49.44 + * To implement a list the programmer needs only to extend this class and
   49.45 + * provide implementations for the <tt>listIterator</tt> and <tt>size</tt>
   49.46 + * methods.  For an unmodifiable list, the programmer need only implement the
   49.47 + * list iterator's <tt>hasNext</tt>, <tt>next</tt>, <tt>hasPrevious</tt>,
   49.48 + * <tt>previous</tt> and <tt>index</tt> methods.<p>
   49.49 + *
   49.50 + * For a modifiable list the programmer should additionally implement the list
   49.51 + * iterator's <tt>set</tt> method.  For a variable-size list the programmer
   49.52 + * should additionally implement the list iterator's <tt>remove</tt> and
   49.53 + * <tt>add</tt> methods.<p>
   49.54 + *
   49.55 + * The programmer should generally provide a void (no argument) and collection
   49.56 + * constructor, as per the recommendation in the <tt>Collection</tt> interface
   49.57 + * specification.<p>
   49.58 + *
   49.59 + * This class is a member of the
   49.60 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
   49.61 + * Java Collections Framework</a>.
   49.62 + *
   49.63 + * @author  Josh Bloch
   49.64 + * @author  Neal Gafter
   49.65 + * @see Collection
   49.66 + * @see List
   49.67 + * @see AbstractList
   49.68 + * @see AbstractCollection
   49.69 + * @since 1.2
   49.70 + */
   49.71 +
   49.72 +public abstract class AbstractSequentialList<E> extends AbstractList<E> {
   49.73 +    /**
   49.74 +     * Sole constructor.  (For invocation by subclass constructors, typically
   49.75 +     * implicit.)
   49.76 +     */
   49.77 +    protected AbstractSequentialList() {
   49.78 +    }
   49.79 +
   49.80 +    /**
   49.81 +     * Returns the element at the specified position in this list.
   49.82 +     *
   49.83 +     * <p>This implementation first gets a list iterator pointing to the
   49.84 +     * indexed element (with <tt>listIterator(index)</tt>).  Then, it gets
   49.85 +     * the element using <tt>ListIterator.next</tt> and returns it.
   49.86 +     *
   49.87 +     * @throws IndexOutOfBoundsException {@inheritDoc}
   49.88 +     */
   49.89 +    public E get(int index) {
   49.90 +        try {
   49.91 +            return listIterator(index).next();
   49.92 +        } catch (NoSuchElementException exc) {
   49.93 +            throw new IndexOutOfBoundsException("Index: "+index);
   49.94 +        }
   49.95 +    }
   49.96 +
   49.97 +    /**
   49.98 +     * Replaces the element at the specified position in this list with the
   49.99 +     * specified element (optional operation).
  49.100 +     *
  49.101 +     * <p>This implementation first gets a list iterator pointing to the
  49.102 +     * indexed element (with <tt>listIterator(index)</tt>).  Then, it gets
  49.103 +     * the current element using <tt>ListIterator.next</tt> and replaces it
  49.104 +     * with <tt>ListIterator.set</tt>.
  49.105 +     *
  49.106 +     * <p>Note that this implementation will throw an
  49.107 +     * <tt>UnsupportedOperationException</tt> if the list iterator does not
  49.108 +     * implement the <tt>set</tt> operation.
  49.109 +     *
  49.110 +     * @throws UnsupportedOperationException {@inheritDoc}
  49.111 +     * @throws ClassCastException            {@inheritDoc}
  49.112 +     * @throws NullPointerException          {@inheritDoc}
  49.113 +     * @throws IllegalArgumentException      {@inheritDoc}
  49.114 +     * @throws IndexOutOfBoundsException     {@inheritDoc}
  49.115 +     */
  49.116 +    public E set(int index, E element) {
  49.117 +        try {
  49.118 +            ListIterator<E> e = listIterator(index);
  49.119 +            E oldVal = e.next();
  49.120 +            e.set(element);
  49.121 +            return oldVal;
  49.122 +        } catch (NoSuchElementException exc) {
  49.123 +            throw new IndexOutOfBoundsException("Index: "+index);
  49.124 +        }
  49.125 +    }
  49.126 +
  49.127 +    /**
  49.128 +     * Inserts the specified element at the specified position in this list
  49.129 +     * (optional operation).  Shifts the element currently at that position
  49.130 +     * (if any) and any subsequent elements to the right (adds one to their
  49.131 +     * indices).
  49.132 +     *
  49.133 +     * <p>This implementation first gets a list iterator pointing to the
  49.134 +     * indexed element (with <tt>listIterator(index)</tt>).  Then, it
  49.135 +     * inserts the specified element with <tt>ListIterator.add</tt>.
  49.136 +     *
  49.137 +     * <p>Note that this implementation will throw an
  49.138 +     * <tt>UnsupportedOperationException</tt> if the list iterator does not
  49.139 +     * implement the <tt>add</tt> operation.
  49.140 +     *
  49.141 +     * @throws UnsupportedOperationException {@inheritDoc}
  49.142 +     * @throws ClassCastException            {@inheritDoc}
  49.143 +     * @throws NullPointerException          {@inheritDoc}
  49.144 +     * @throws IllegalArgumentException      {@inheritDoc}
  49.145 +     * @throws IndexOutOfBoundsException     {@inheritDoc}
  49.146 +     */
  49.147 +    public void add(int index, E element) {
  49.148 +        try {
  49.149 +            listIterator(index).add(element);
  49.150 +        } catch (NoSuchElementException exc) {
  49.151 +            throw new IndexOutOfBoundsException("Index: "+index);
  49.152 +        }
  49.153 +    }
  49.154 +
  49.155 +    /**
  49.156 +     * Removes the element at the specified position in this list (optional
  49.157 +     * operation).  Shifts any subsequent elements to the left (subtracts one
  49.158 +     * from their indices).  Returns the element that was removed from the
  49.159 +     * list.
  49.160 +     *
  49.161 +     * <p>This implementation first gets a list iterator pointing to the
  49.162 +     * indexed element (with <tt>listIterator(index)</tt>).  Then, it removes
  49.163 +     * the element with <tt>ListIterator.remove</tt>.
  49.164 +     *
  49.165 +     * <p>Note that this implementation will throw an
  49.166 +     * <tt>UnsupportedOperationException</tt> if the list iterator does not
  49.167 +     * implement the <tt>remove</tt> operation.
  49.168 +     *
  49.169 +     * @throws UnsupportedOperationException {@inheritDoc}
  49.170 +     * @throws IndexOutOfBoundsException     {@inheritDoc}
  49.171 +     */
  49.172 +    public E remove(int index) {
  49.173 +        try {
  49.174 +            ListIterator<E> e = listIterator(index);
  49.175 +            E outCast = e.next();
  49.176 +            e.remove();
  49.177 +            return outCast;
  49.178 +        } catch (NoSuchElementException exc) {
  49.179 +            throw new IndexOutOfBoundsException("Index: "+index);
  49.180 +        }
  49.181 +    }
  49.182 +
  49.183 +
  49.184 +    // Bulk Operations
  49.185 +
  49.186 +    /**
  49.187 +     * Inserts all of the elements in the specified collection into this
  49.188 +     * list at the specified position (optional operation).  Shifts the
  49.189 +     * element currently at that position (if any) and any subsequent
  49.190 +     * elements to the right (increases their indices).  The new elements
  49.191 +     * will appear in this list in the order that they are returned by the
  49.192 +     * specified collection's iterator.  The behavior of this operation is
  49.193 +     * undefined if the specified collection is modified while the
  49.194 +     * operation is in progress.  (Note that this will occur if the specified
  49.195 +     * collection is this list, and it's nonempty.)
  49.196 +     *
  49.197 +     * <p>This implementation gets an iterator over the specified collection and
  49.198 +     * a list iterator over this list pointing to the indexed element (with
  49.199 +     * <tt>listIterator(index)</tt>).  Then, it iterates over the specified
  49.200 +     * collection, inserting the elements obtained from the iterator into this
  49.201 +     * list, one at a time, using <tt>ListIterator.add</tt> followed by
  49.202 +     * <tt>ListIterator.next</tt> (to skip over the added element).
  49.203 +     *
  49.204 +     * <p>Note that this implementation will throw an
  49.205 +     * <tt>UnsupportedOperationException</tt> if the list iterator returned by
  49.206 +     * the <tt>listIterator</tt> method does not implement the <tt>add</tt>
  49.207 +     * operation.
  49.208 +     *
  49.209 +     * @throws UnsupportedOperationException {@inheritDoc}
  49.210 +     * @throws ClassCastException            {@inheritDoc}
  49.211 +     * @throws NullPointerException          {@inheritDoc}
  49.212 +     * @throws IllegalArgumentException      {@inheritDoc}
  49.213 +     * @throws IndexOutOfBoundsException     {@inheritDoc}
  49.214 +     */
  49.215 +    public boolean addAll(int index, Collection<? extends E> c) {
  49.216 +        try {
  49.217 +            boolean modified = false;
  49.218 +            ListIterator<E> e1 = listIterator(index);
  49.219 +            Iterator<? extends E> e2 = c.iterator();
  49.220 +            while (e2.hasNext()) {
  49.221 +                e1.add(e2.next());
  49.222 +                modified = true;
  49.223 +            }
  49.224 +            return modified;
  49.225 +        } catch (NoSuchElementException exc) {
  49.226 +            throw new IndexOutOfBoundsException("Index: "+index);
  49.227 +        }
  49.228 +    }
  49.229 +
  49.230 +
  49.231 +    // Iterators
  49.232 +
  49.233 +    /**
  49.234 +     * Returns an iterator over the elements in this list (in proper
  49.235 +     * sequence).<p>
  49.236 +     *
  49.237 +     * This implementation merely returns a list iterator over the list.
  49.238 +     *
  49.239 +     * @return an iterator over the elements in this list (in proper sequence)
  49.240 +     */
  49.241 +    public Iterator<E> iterator() {
  49.242 +        return listIterator();
  49.243 +    }
  49.244 +
  49.245 +    /**
  49.246 +     * Returns a list iterator over the elements in this list (in proper
  49.247 +     * sequence).
  49.248 +     *
  49.249 +     * @param  index index of first element to be returned from the list
  49.250 +     *         iterator (by a call to the <code>next</code> method)
  49.251 +     * @return a list iterator over the elements in this list (in proper
  49.252 +     *         sequence)
  49.253 +     * @throws IndexOutOfBoundsException {@inheritDoc}
  49.254 +     */
  49.255 +    public abstract ListIterator<E> listIterator(int index);
  49.256 +}
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/emul/compact/src/main/java/java/util/ArrayDeque.java	Tue Feb 05 17:04:22 2013 +0100
    50.3 @@ -0,0 +1,830 @@
    50.4 +/*
    50.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    50.6 + *
    50.7 + * This code is free software; you can redistribute it and/or modify it
    50.8 + * under the terms of the GNU General Public License version 2 only, as
    50.9 + * published by the Free Software Foundation.  Oracle designates this
   50.10 + * particular file as subject to the "Classpath" exception as provided
   50.11 + * by Oracle in the LICENSE file that accompanied this code.
   50.12 + *
   50.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
   50.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   50.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   50.16 + * version 2 for more details (a copy is included in the LICENSE file that
   50.17 + * accompanied this code).
   50.18 + *
   50.19 + * You should have received a copy of the GNU General Public License version
   50.20 + * 2 along with this work; if not, write to the Free Software Foundation,
   50.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   50.22 + *
   50.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   50.24 + * or visit www.oracle.com if you need additional information or have any
   50.25 + * questions.
   50.26 + */
   50.27 +
   50.28 +/*
   50.29 + * This file is available under and governed by the GNU General Public
   50.30 + * License version 2 only, as published by the Free Software Foundation.
   50.31 + * However, the following notice accompanied the original version of this
   50.32 + * file:
   50.33 + *
   50.34 + * Written by Josh Bloch of Google Inc. and released to the public domain,
   50.35 + * as explained at http://creativecommons.org/publicdomain/zero/1.0/.
   50.36 + */
   50.37 +
   50.38 +package java.util;
   50.39 +import java.io.*;
   50.40 +
   50.41 +/**
   50.42 + * Resizable-array implementation of the {@link Deque} interface.  Array
   50.43 + * deques have no capacity restrictions; they grow as necessary to support
   50.44 + * usage.  They are not thread-safe; in the absence of external
   50.45 + * synchronization, they do not support concurrent access by multiple threads.
   50.46 + * Null elements are prohibited.  This class is likely to be faster than
   50.47 + * {@link Stack} when used as a stack, and faster than {@link LinkedList}
   50.48 + * when used as a queue.
   50.49 + *
   50.50 + * <p>Most <tt>ArrayDeque</tt> operations run in amortized constant time.
   50.51 + * Exceptions include {@link #remove(Object) remove}, {@link
   50.52 + * #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence
   50.53 + * removeLastOccurrence}, {@link #contains contains}, {@link #iterator
   50.54 + * iterator.remove()}, and the bulk operations, all of which run in linear
   50.55 + * time.
   50.56 + *
   50.57 + * <p>The iterators returned by this class's <tt>iterator</tt> method are
   50.58 + * <i>fail-fast</i>: If the deque is modified at any time after the iterator
   50.59 + * is created, in any way except through the iterator's own <tt>remove</tt>
   50.60 + * method, the iterator will generally throw a {@link
   50.61 + * ConcurrentModificationException}.  Thus, in the face of concurrent
   50.62 + * modification, the iterator fails quickly and cleanly, rather than risking
   50.63 + * arbitrary, non-deterministic behavior at an undetermined time in the
   50.64 + * future.
   50.65 + *
   50.66 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
   50.67 + * as it is, generally speaking, impossible to make any hard guarantees in the
   50.68 + * presence of unsynchronized concurrent modification.  Fail-fast iterators
   50.69 + * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
   50.70 + * Therefore, it would be wrong to write a program that depended on this
   50.71 + * exception for its correctness: <i>the fail-fast behavior of iterators
   50.72 + * should be used only to detect bugs.</i>
   50.73 + *
   50.74 + * <p>This class and its iterator implement all of the
   50.75 + * <em>optional</em> methods of the {@link Collection} and {@link
   50.76 + * Iterator} interfaces.
   50.77 + *
   50.78 + * <p>This class is a member of the
   50.79 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
   50.80 + * Java Collections Framework</a>.
   50.81 + *
   50.82 + * @author  Josh Bloch and Doug Lea
   50.83 + * @since   1.6
   50.84 + * @param <E> the type of elements held in this collection
   50.85 + */
   50.86 +public class ArrayDeque<E> extends AbstractCollection<E>
   50.87 +                           implements Deque<E>, Cloneable, Serializable
   50.88 +{
   50.89 +    /**
   50.90 +     * The array in which the elements of the deque are stored.
   50.91 +     * The capacity of the deque is the length of this array, which is
   50.92 +     * always a power of two. The array is never allowed to become
   50.93 +     * full, except transiently within an addX method where it is
   50.94 +     * resized (see doubleCapacity) immediately upon becoming full,
   50.95 +     * thus avoiding head and tail wrapping around to equal each
   50.96 +     * other.  We also guarantee that all array cells not holding
   50.97 +     * deque elements are always null.
   50.98 +     */
   50.99 +    private transient E[] elements;
  50.100 +
  50.101 +    /**
  50.102 +     * The index of the element at the head of the deque (which is the
  50.103 +     * element that would be removed by remove() or pop()); or an
  50.104 +     * arbitrary number equal to tail if the deque is empty.
  50.105 +     */
  50.106 +    private transient int head;
  50.107 +
  50.108 +    /**
  50.109 +     * The index at which the next element would be added to the tail
  50.110 +     * of the deque (via addLast(E), add(E), or push(E)).
  50.111 +     */
  50.112 +    private transient int tail;
  50.113 +
  50.114 +    /**
  50.115 +     * The minimum capacity that we'll use for a newly created deque.
  50.116 +     * Must be a power of 2.
  50.117 +     */
  50.118 +    private static final int MIN_INITIAL_CAPACITY = 8;
  50.119 +
  50.120 +    // ******  Array allocation and resizing utilities ******
  50.121 +
  50.122 +    /**
  50.123 +     * Allocate empty array to hold the given number of elements.
  50.124 +     *
  50.125 +     * @param numElements  the number of elements to hold
  50.126 +     */
  50.127 +    private void allocateElements(int numElements) {
  50.128 +        int initialCapacity = MIN_INITIAL_CAPACITY;
  50.129 +        // Find the best power of two to hold elements.
  50.130 +        // Tests "<=" because arrays aren't kept full.
  50.131 +        if (numElements >= initialCapacity) {
  50.132 +            initialCapacity = numElements;
  50.133 +            initialCapacity |= (initialCapacity >>>  1);
  50.134 +            initialCapacity |= (initialCapacity >>>  2);
  50.135 +            initialCapacity |= (initialCapacity >>>  4);
  50.136 +            initialCapacity |= (initialCapacity >>>  8);
  50.137 +            initialCapacity |= (initialCapacity >>> 16);
  50.138 +            initialCapacity++;
  50.139 +
  50.140 +            if (initialCapacity < 0)   // Too many elements, must back off
  50.141 +                initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
  50.142 +        }
  50.143 +        elements = (E[]) new Object[initialCapacity];
  50.144 +    }
  50.145 +
  50.146 +    /**
  50.147 +     * Double the capacity of this deque.  Call only when full, i.e.,
  50.148 +     * when head and tail have wrapped around to become equal.
  50.149 +     */
  50.150 +    private void doubleCapacity() {
  50.151 +        assert head == tail;
  50.152 +        int p = head;
  50.153 +        int n = elements.length;
  50.154 +        int r = n - p; // number of elements to the right of p
  50.155 +        int newCapacity = n << 1;
  50.156 +        if (newCapacity < 0)
  50.157 +            throw new IllegalStateException("Sorry, deque too big");
  50.158 +        Object[] a = new Object[newCapacity];
  50.159 +        System.arraycopy(elements, p, a, 0, r);
  50.160 +        System.arraycopy(elements, 0, a, r, p);
  50.161 +        elements = (E[])a;
  50.162 +        head = 0;
  50.163 +        tail = n;
  50.164 +    }
  50.165 +
  50.166 +    /**
  50.167 +     * Copies the elements from our element array into the specified array,
  50.168 +     * in order (from first to last element in the deque).  It is assumed
  50.169 +     * that the array is large enough to hold all elements in the deque.
  50.170 +     *
  50.171 +     * @return its argument
  50.172 +     */
  50.173 +    private <T> T[] copyElements(T[] a) {
  50.174 +        if (head < tail) {
  50.175 +            System.arraycopy(elements, head, a, 0, size());
  50.176 +        } else if (head > tail) {
  50.177 +            int headPortionLen = elements.length - head;
  50.178 +            System.arraycopy(elements, head, a, 0, headPortionLen);
  50.179 +            System.arraycopy(elements, 0, a, headPortionLen, tail);
  50.180 +        }
  50.181 +        return a;
  50.182 +    }
  50.183 +
  50.184 +    /**
  50.185 +     * Constructs an empty array deque with an initial capacity
  50.186 +     * sufficient to hold 16 elements.
  50.187 +     */
  50.188 +    public ArrayDeque() {
  50.189 +        elements = (E[]) new Object[16];
  50.190 +    }
  50.191 +
  50.192 +    /**
  50.193 +     * Constructs an empty array deque with an initial capacity
  50.194 +     * sufficient to hold the specified number of elements.
  50.195 +     *
  50.196 +     * @param numElements  lower bound on initial capacity of the deque
  50.197 +     */
  50.198 +    public ArrayDeque(int numElements) {
  50.199 +        allocateElements(numElements);
  50.200 +    }
  50.201 +
  50.202 +    /**
  50.203 +     * Constructs a deque containing the elements of the specified
  50.204 +     * collection, in the order they are returned by the collection's
  50.205 +     * iterator.  (The first element returned by the collection's
  50.206 +     * iterator becomes the first element, or <i>front</i> of the
  50.207 +     * deque.)
  50.208 +     *
  50.209 +     * @param c the collection whose elements are to be placed into the deque
  50.210 +     * @throws NullPointerException if the specified collection is null
  50.211 +     */
  50.212 +    public ArrayDeque(Collection<? extends E> c) {
  50.213 +        allocateElements(c.size());
  50.214 +        addAll(c);
  50.215 +    }
  50.216 +
  50.217 +    // The main insertion and extraction methods are addFirst,
  50.218 +    // addLast, pollFirst, pollLast. The other methods are defined in
  50.219 +    // terms of these.
  50.220 +
  50.221 +    /**
  50.222 +     * Inserts the specified element at the front of this deque.
  50.223 +     *
  50.224 +     * @param e the element to add
  50.225 +     * @throws NullPointerException if the specified element is null
  50.226 +     */
  50.227 +    public void addFirst(E e) {
  50.228 +        if (e == null)
  50.229 +            throw new NullPointerException();
  50.230 +        elements[head = (head - 1) & (elements.length - 1)] = e;
  50.231 +        if (head == tail)
  50.232 +            doubleCapacity();
  50.233 +    }
  50.234 +
  50.235 +    /**
  50.236 +     * Inserts the specified element at the end of this deque.
  50.237 +     *
  50.238 +     * <p>This method is equivalent to {@link #add}.
  50.239 +     *
  50.240 +     * @param e the element to add
  50.241 +     * @throws NullPointerException if the specified element is null
  50.242 +     */
  50.243 +    public void addLast(E e) {
  50.244 +        if (e == null)
  50.245 +            throw new NullPointerException();
  50.246 +        elements[tail] = e;
  50.247 +        if ( (tail = (tail + 1) & (elements.length - 1)) == head)
  50.248 +            doubleCapacity();
  50.249 +    }
  50.250 +
  50.251 +    /**
  50.252 +     * Inserts the specified element at the front of this deque.
  50.253 +     *
  50.254 +     * @param e the element to add
  50.255 +     * @return <tt>true</tt> (as specified by {@link Deque#offerFirst})
  50.256 +     * @throws NullPointerException if the specified element is null
  50.257 +     */
  50.258 +    public boolean offerFirst(E e) {
  50.259 +        addFirst(e);
  50.260 +        return true;
  50.261 +    }
  50.262 +
  50.263 +    /**
  50.264 +     * Inserts the specified element at the end of this deque.
  50.265 +     *
  50.266 +     * @param e the element to add
  50.267 +     * @return <tt>true</tt> (as specified by {@link Deque#offerLast})
  50.268 +     * @throws NullPointerException if the specified element is null
  50.269 +     */
  50.270 +    public boolean offerLast(E e) {
  50.271 +        addLast(e);
  50.272 +        return true;
  50.273 +    }
  50.274 +
  50.275 +    /**
  50.276 +     * @throws NoSuchElementException {@inheritDoc}
  50.277 +     */
  50.278 +    public E removeFirst() {
  50.279 +        E x = pollFirst();
  50.280 +        if (x == null)
  50.281 +            throw new NoSuchElementException();
  50.282 +        return x;
  50.283 +    }
  50.284 +
  50.285 +    /**
  50.286 +     * @throws NoSuchElementException {@inheritDoc}
  50.287 +     */
  50.288 +    public E removeLast() {
  50.289 +        E x = pollLast();
  50.290 +        if (x == null)
  50.291 +            throw new NoSuchElementException();
  50.292 +        return x;
  50.293 +    }
  50.294 +
  50.295 +    public E pollFirst() {
  50.296 +        int h = head;
  50.297 +        E result = elements[h]; // Element is null if deque empty
  50.298 +        if (result == null)
  50.299 +            return null;
  50.300 +        elements[h] = null;     // Must null out slot
  50.301 +        head = (h + 1) & (elements.length - 1);
  50.302 +        return result;
  50.303 +    }
  50.304 +
  50.305 +    public E pollLast() {
  50.306 +        int t = (tail - 1) & (elements.length - 1);
  50.307 +        E result = elements[t];
  50.308 +        if (result == null)
  50.309 +            return null;
  50.310 +        elements[t] = null;
  50.311 +        tail = t;
  50.312 +        return result;
  50.313 +    }
  50.314 +
  50.315 +    /**
  50.316 +     * @throws NoSuchElementException {@inheritDoc}
  50.317 +     */
  50.318 +    public E getFirst() {
  50.319 +        E x = elements[head];
  50.320 +        if (x == null)
  50.321 +            throw new NoSuchElementException();
  50.322 +        return x;
  50.323 +    }
  50.324 +
  50.325 +    /**
  50.326 +     * @throws NoSuchElementException {@inheritDoc}
  50.327 +     */
  50.328 +    public E getLast() {
  50.329 +        E x = elements[(tail - 1) & (elements.length - 1)];
  50.330 +        if (x == null)
  50.331 +            throw new NoSuchElementException();
  50.332 +        return x;
  50.333 +    }
  50.334 +
  50.335 +    public E peekFirst() {
  50.336 +        return elements[head]; // elements[head] is null if deque empty
  50.337 +    }
  50.338 +
  50.339 +    public E peekLast() {
  50.340 +        return elements[(tail - 1) & (elements.length - 1)];
  50.341 +    }
  50.342 +
  50.343 +    /**
  50.344 +     * Removes the first occurrence of the specified element in this
  50.345 +     * deque (when traversing the deque from head to tail).
  50.346 +     * If the deque does not contain the element, it is unchanged.
  50.347 +     * More formally, removes the first element <tt>e</tt> such that
  50.348 +     * <tt>o.equals(e)</tt> (if such an element exists).
  50.349 +     * Returns <tt>true</tt> if this deque contained the specified element
  50.350 +     * (or equivalently, if this deque changed as a result of the call).
  50.351 +     *
  50.352 +     * @param o element to be removed from this deque, if present
  50.353 +     * @return <tt>true</tt> if the deque contained the specified element
  50.354 +     */
  50.355 +    public boolean removeFirstOccurrence(Object o) {
  50.356 +        if (o == null)
  50.357 +            return false;
  50.358 +        int mask = elements.length - 1;
  50.359 +        int i = head;
  50.360 +        E x;
  50.361 +        while ( (x = elements[i]) != null) {
  50.362 +            if (o.equals(x)) {
  50.363 +                delete(i);
  50.364 +                return true;
  50.365 +            }
  50.366 +            i = (i + 1) & mask;
  50.367 +        }
  50.368 +        return false;
  50.369 +    }
  50.370 +
  50.371 +    /**
  50.372 +     * Removes the last occurrence of the specified element in this
  50.373 +     * deque (when traversing the deque from head to tail).
  50.374 +     * If the deque does not contain the element, it is unchanged.
  50.375 +     * More formally, removes the last element <tt>e</tt> such that
  50.376 +     * <tt>o.equals(e)</tt> (if such an element exists).
  50.377 +     * Returns <tt>true</tt> if this deque contained the specified element
  50.378 +     * (or equivalently, if this deque changed as a result of the call).
  50.379 +     *
  50.380 +     * @param o element to be removed from this deque, if present
  50.381 +     * @return <tt>true</tt> if the deque contained the specified element
  50.382 +     */
  50.383 +    public boolean removeLastOccurrence(Object o) {
  50.384 +        if (o == null)
  50.385 +            return false;
  50.386 +        int mask = elements.length - 1;
  50.387 +        int i = (tail - 1) & mask;
  50.388 +        E x;
  50.389 +        while ( (x = elements[i]) != null) {
  50.390 +            if (o.equals(x)) {
  50.391 +                delete(i);
  50.392 +                return true;
  50.393 +            }
  50.394 +            i = (i - 1) & mask;
  50.395 +        }
  50.396 +        return false;
  50.397 +    }
  50.398 +
  50.399 +    // *** Queue methods ***
  50.400 +
  50.401 +    /**
  50.402 +     * Inserts the specified element at the end of this deque.
  50.403 +     *
  50.404 +     * <p>This method is equivalent to {@link #addLast}.
  50.405 +     *
  50.406 +     * @param e the element to add
  50.407 +     * @return <tt>true</tt> (as specified by {@link Collection#add})
  50.408 +     * @throws NullPointerException if the specified element is null
  50.409 +     */
  50.410 +    public boolean add(E e) {
  50.411 +        addLast(e);
  50.412 +        return true;
  50.413 +    }
  50.414 +
  50.415 +    /**
  50.416 +     * Inserts the specified element at the end of this deque.
  50.417 +     *
  50.418 +     * <p>This method is equivalent to {@link #offerLast}.
  50.419 +     *
  50.420 +     * @param e the element to add
  50.421 +     * @return <tt>true</tt> (as specified by {@link Queue#offer})
  50.422 +     * @throws NullPointerException if the specified element is null
  50.423 +     */
  50.424 +    public boolean offer(E e) {
  50.425 +        return offerLast(e);
  50.426 +    }
  50.427 +
  50.428 +    /**
  50.429 +     * Retrieves and removes the head of the queue represented by this deque.
  50.430 +     *
  50.431 +     * This method differs from {@link #poll poll} only in that it throws an
  50.432 +     * exception if this deque is empty.
  50.433 +     *
  50.434 +     * <p>This method is equivalent to {@link #removeFirst}.
  50.435 +     *
  50.436 +     * @return the head of the queue represented by this deque
  50.437 +     * @throws NoSuchElementException {@inheritDoc}
  50.438 +     */
  50.439 +    public E remove() {
  50.440 +        return removeFirst();
  50.441 +    }
  50.442 +
  50.443 +    /**
  50.444 +     * Retrieves and removes the head of the queue represented by this deque
  50.445 +     * (in other words, the first element of this deque), or returns
  50.446 +     * <tt>null</tt> if this deque is empty.
  50.447 +     *
  50.448 +     * <p>This method is equivalent to {@link #pollFirst}.
  50.449 +     *
  50.450 +     * @return the head of the queue represented by this deque, or
  50.451 +     *         <tt>null</tt> if this deque is empty
  50.452 +     */
  50.453 +    public E poll() {
  50.454 +        return pollFirst();
  50.455 +    }
  50.456 +
  50.457 +    /**
  50.458 +     * Retrieves, but does not remove, the head of the queue represented by
  50.459 +     * this deque.  This method differs from {@link #peek peek} only in
  50.460 +     * that it throws an exception if this deque is empty.
  50.461 +     *
  50.462 +     * <p>This method is equivalent to {@link #getFirst}.
  50.463 +     *
  50.464 +     * @return the head of the queue represented by this deque
  50.465 +     * @throws NoSuchElementException {@inheritDoc}
  50.466 +     */
  50.467 +    public E element() {
  50.468 +        return getFirst();
  50.469 +    }
  50.470 +
  50.471 +    /**
  50.472 +     * Retrieves, but does not remove, the head of the queue represented by
  50.473 +     * this deque, or returns <tt>null</tt> if this deque is empty.
  50.474 +     *
  50.475 +     * <p>This method is equivalent to {@link #peekFirst}.
  50.476 +     *
  50.477 +     * @return the head of the queue represented by this deque, or
  50.478 +     *         <tt>null</tt> if this deque is empty
  50.479 +     */
  50.480 +    public E peek() {
  50.481 +        return peekFirst();
  50.482 +    }
  50.483 +
  50.484 +    // *** Stack methods ***
  50.485 +
  50.486 +    /**
  50.487 +     * Pushes an element onto the stack represented by this deque.  In other
  50.488 +     * words, inserts the element at the front of this deque.
  50.489 +     *
  50.490 +     * <p>This method is equivalent to {@link #addFirst}.
  50.491 +     *
  50.492 +     * @param e the element to push
  50.493 +     * @throws NullPointerException if the specified element is null
  50.494 +     */
  50.495 +    public void push(E e) {
  50.496 +        addFirst(e);
  50.497 +    }
  50.498 +
  50.499 +    /**
  50.500 +     * Pops an element from the stack represented by this deque.  In other
  50.501 +     * words, removes and returns the first element of this deque.
  50.502 +     *
  50.503 +     * <p>This method is equivalent to {@link #removeFirst()}.
  50.504 +     *
  50.505 +     * @return the element at the front of this deque (which is the top
  50.506 +     *         of the stack represented by this deque)
  50.507 +     * @throws NoSuchElementException {@inheritDoc}
  50.508 +     */
  50.509 +    public E pop() {
  50.510 +        return removeFirst();
  50.511 +    }
  50.512 +
  50.513 +    private void checkInvariants() {
  50.514 +        assert elements[tail] == null;
  50.515 +        assert head == tail ? elements[head] == null :
  50.516 +            (elements[head] != null &&
  50.517 +             elements[(tail - 1) & (elements.length - 1)] != null);
  50.518 +        assert elements[(head - 1) & (elements.length - 1)] == null;
  50.519 +    }
  50.520 +
  50.521 +    /**
  50.522 +     * Removes the element at the specified position in the elements array,
  50.523 +     * adjusting head and tail as necessary.  This can result in motion of
  50.524 +     * elements backwards or forwards in the array.
  50.525 +     *
  50.526 +     * <p>This method is called delete rather than remove to emphasize
  50.527 +     * that its semantics differ from those of {@link List#remove(int)}.
  50.528 +     *
  50.529 +     * @return true if elements moved backwards
  50.530 +     */
  50.531 +    private boolean delete(int i) {
  50.532 +        checkInvariants();
  50.533 +        final E[] elements = this.elements;
  50.534 +        final int mask = elements.length - 1;
  50.535 +        final int h = head;
  50.536 +        final int t = tail;
  50.537 +        final int front = (i - h) & mask;
  50.538 +        final int back  = (t - i) & mask;
  50.539 +
  50.540 +        // Invariant: head <= i < tail mod circularity
  50.541 +        if (front >= ((t - h) & mask))
  50.542 +            throw new ConcurrentModificationException();
  50.543 +
  50.544 +        // Optimize for least element motion
  50.545 +        if (front < back) {
  50.546 +            if (h <= i) {
  50.547 +                System.arraycopy(elements, h, elements, h + 1, front);
  50.548 +            } else { // Wrap around
  50.549 +                System.arraycopy(elements, 0, elements, 1, i);
  50.550 +                elements[0] = elements[mask];
  50.551 +                System.arraycopy(elements, h, elements, h + 1, mask - h);
  50.552 +            }
  50.553 +            elements[h] = null;
  50.554 +            head = (h + 1) & mask;
  50.555 +            return false;
  50.556 +        } else {
  50.557 +            if (i < t) { // Copy the null tail as well
  50.558 +                System.arraycopy(elements, i + 1, elements, i, back);
  50.559 +                tail = t - 1;
  50.560 +            } else { // Wrap around
  50.561 +                System.arraycopy(elements, i + 1, elements, i, mask - i);
  50.562 +                elements[mask] = elements[0];
  50.563 +                System.arraycopy(elements, 1, elements, 0, t);
  50.564 +                tail = (t - 1) & mask;
  50.565 +            }
  50.566 +            return true;
  50.567 +        }
  50.568 +    }
  50.569 +
  50.570 +    // *** Collection Methods ***
  50.571 +
  50.572 +    /**
  50.573 +     * Returns the number of elements in this deque.
  50.574 +     *
  50.575 +     * @return the number of elements in this deque
  50.576 +     */
  50.577 +    public int size() {
  50.578 +        return (tail - head) & (elements.length - 1);
  50.579 +    }
  50.580 +
  50.581 +    /**
  50.582 +     * Returns <tt>true</tt> if this deque contains no elements.
  50.583 +     *
  50.584 +     * @return <tt>true</tt> if this deque contains no elements
  50.585 +     */
  50.586 +    public boolean isEmpty() {
  50.587 +        return head == tail;
  50.588 +    }
  50.589 +
  50.590 +    /**
  50.591 +     * Returns an iterator over the elements in this deque.  The elements
  50.592 +     * will be ordered from first (head) to last (tail).  This is the same
  50.593 +     * order that elements would be dequeued (via successive calls to
  50.594 +     * {@link #remove} or popped (via successive calls to {@link #pop}).
  50.595 +     *
  50.596 +     * @return an iterator over the elements in this deque
  50.597 +     */
  50.598 +    public Iterator<E> iterator() {
  50.599 +        return new DeqIterator();
  50.600 +    }
  50.601 +
  50.602 +    public Iterator<E> descendingIterator() {
  50.603 +        return new DescendingIterator();
  50.604 +    }
  50.605 +
  50.606 +    private class DeqIterator implements Iterator<E> {
  50.607 +        /**
  50.608 +         * Index of element to be returned by subsequent call to next.
  50.609 +         */
  50.610 +        private int cursor = head;
  50.611 +
  50.612 +        /**
  50.613 +         * Tail recorded at construction (also in remove), to stop
  50.614 +         * iterator and also to check for comodification.
  50.615 +         */
  50.616 +        private int fence = tail;
  50.617 +
  50.618 +        /**
  50.619 +         * Index of element returned by most recent call to next.
  50.620 +         * Reset to -1 if element is deleted by a call to remove.
  50.621 +         */
  50.622 +        private int lastRet = -1;
  50.623 +
  50.624 +        public boolean hasNext() {
  50.625 +            return cursor != fence;
  50.626 +        }
  50.627 +
  50.628 +        public E next() {
  50.629 +            if (cursor == fence)
  50.630 +                throw new NoSuchElementException();
  50.631 +            E result = elements[cursor];
  50.632 +            // This check doesn't catch all possible comodifications,
  50.633 +            // but does catch the ones that corrupt traversal
  50.634 +            if (tail != fence || result == null)
  50.635 +                throw new ConcurrentModificationException();
  50.636 +            lastRet = cursor;
  50.637 +            cursor = (cursor + 1) & (elements.length - 1);
  50.638 +            return result;
  50.639 +        }
  50.640 +
  50.641 +        public void remove() {
  50.642 +            if (lastRet < 0)
  50.643 +                throw new IllegalStateException();
  50.644 +            if (delete(lastRet)) { // if left-shifted, undo increment in next()
  50.645 +                cursor = (cursor - 1) & (elements.length - 1);
  50.646 +                fence = tail;
  50.647 +            }
  50.648 +            lastRet = -1;
  50.649 +        }
  50.650 +    }
  50.651 +
  50.652 +    private class DescendingIterator implements Iterator<E> {
  50.653 +        /*
  50.654 +         * This class is nearly a mirror-image of DeqIterator, using
  50.655 +         * tail instead of head for initial cursor, and head instead of
  50.656 +         * tail for fence.
  50.657 +         */
  50.658 +        private int cursor = tail;
  50.659 +        private int fence = head;
  50.660 +        private int lastRet = -1;
  50.661 +
  50.662 +        public boolean hasNext() {
  50.663 +            return cursor != fence;
  50.664 +        }
  50.665 +
  50.666 +        public E next() {
  50.667 +            if (cursor == fence)
  50.668 +                throw new NoSuchElementException();
  50.669 +            cursor = (cursor - 1) & (elements.length - 1);
  50.670 +            E result = elements[cursor];
  50.671 +            if (head != fence || result == null)
  50.672 +                throw new ConcurrentModificationException();
  50.673 +            lastRet = cursor;
  50.674 +            return result;
  50.675 +        }
  50.676 +
  50.677 +        public void remove() {
  50.678 +            if (lastRet < 0)
  50.679 +                throw new IllegalStateException();
  50.680 +            if (!delete(lastRet)) {
  50.681 +                cursor = (cursor + 1) & (elements.length - 1);
  50.682 +                fence = head;
  50.683 +            }
  50.684 +            lastRet = -1;
  50.685 +        }
  50.686 +    }
  50.687 +
  50.688 +    /**
  50.689 +     * Returns <tt>true</tt> if this deque contains the specified element.
  50.690 +     * More formally, returns <tt>true</tt> if and only if this deque contains
  50.691 +     * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
  50.692 +     *
  50.693 +     * @param o object to be checked for containment in this deque
  50.694 +     * @return <tt>true</tt> if this deque contains the specified element
  50.695 +     */
  50.696 +    public boolean contains(Object o) {
  50.697 +        if (o == null)
  50.698 +            return false;
  50.699 +        int mask = elements.length - 1;
  50.700 +        int i = head;
  50.701 +        E x;
  50.702 +        while ( (x = elements[i]) != null) {
  50.703 +            if (o.equals(x))
  50.704 +                return true;
  50.705 +            i = (i + 1) & mask;
  50.706 +        }
  50.707 +        return false;
  50.708 +    }
  50.709 +
  50.710 +    /**
  50.711 +     * Removes a single instance of the specified element from this deque.
  50.712 +     * If the deque does not contain the element, it is unchanged.
  50.713 +     * More formally, removes the first element <tt>e</tt> such that
  50.714 +     * <tt>o.equals(e)</tt> (if such an element exists).
  50.715 +     * Returns <tt>true</tt> if this deque contained the specified element
  50.716 +     * (or equivalently, if this deque changed as a result of the call).
  50.717 +     *
  50.718 +     * <p>This method is equivalent to {@link #removeFirstOccurrence}.
  50.719 +     *
  50.720 +     * @param o element to be removed from this deque, if present
  50.721 +     * @return <tt>true</tt> if this deque contained the specified element
  50.722 +     */
  50.723 +    public boolean remove(Object o) {
  50.724 +        return removeFirstOccurrence(o);
  50.725 +    }
  50.726 +
  50.727 +    /**
  50.728 +     * Removes all of the elements from this deque.
  50.729 +     * The deque will be empty after this call returns.
  50.730 +     */
  50.731 +    public void clear() {
  50.732 +        int h = head;
  50.733 +        int t = tail;
  50.734 +        if (h != t) { // clear all cells
  50.735 +            head = tail = 0;
  50.736 +            int i = h;
  50.737 +            int mask = elements.length - 1;
  50.738 +            do {
  50.739 +                elements[i] = null;
  50.740 +                i = (i + 1) & mask;
  50.741 +            } while (i != t);
  50.742 +        }
  50.743 +    }
  50.744 +
  50.745 +    /**
  50.746 +     * Returns an array containing all of the elements in this deque
  50.747 +     * in proper sequence (from first to last element).
  50.748 +     *
  50.749 +     * <p>The returned array will be "safe" in that no references to it are
  50.750 +     * maintained by this deque.  (In other words, this method must allocate
  50.751 +     * a new array).  The caller is thus free to modify the returned array.
  50.752 +     *
  50.753 +     * <p>This method acts as bridge between array-based and collection-based
  50.754 +     * APIs.
  50.755 +     *
  50.756 +     * @return an array containing all of the elements in this deque
  50.757 +     */
  50.758 +    public Object[] toArray() {
  50.759 +        return copyElements(new Object[size()]);
  50.760 +    }
  50.761 +
  50.762 +    /**
  50.763 +     * Returns an array containing all of the elements in this deque in
  50.764 +     * proper sequence (from first to last element); the runtime type of the
  50.765 +     * returned array is that of the specified array.  If the deque fits in
  50.766 +     * the specified array, it is returned therein.  Otherwise, a new array
  50.767 +     * is allocated with the runtime type of the specified array and the
  50.768 +     * size of this deque.
  50.769 +     *
  50.770 +     * <p>If this deque fits in the specified array with room to spare
  50.771 +     * (i.e., the array has more elements than this deque), the element in
  50.772 +     * the array immediately following the end of the deque is set to
  50.773 +     * <tt>null</tt>.
  50.774 +     *
  50.775 +     * <p>Like the {@link #toArray()} method, this method acts as bridge between
  50.776 +     * array-based and collection-based APIs.  Further, this method allows
  50.777 +     * precise control over the runtime type of the output array, and may,
  50.778 +     * under certain circumstances, be used to save allocation costs.
  50.779 +     *
  50.780 +     * <p>Suppose <tt>x</tt> is a deque known to contain only strings.
  50.781 +     * The following code can be used to dump the deque into a newly
  50.782 +     * allocated array of <tt>String</tt>:
  50.783 +     *
  50.784 +     * <pre>
  50.785 +     *     String[] y = x.toArray(new String[0]);</pre>
  50.786 +     *
  50.787 +     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
  50.788 +     * <tt>toArray()</tt>.
  50.789 +     *
  50.790 +     * @param a the array into which the elements of the deque are to
  50.791 +     *          be stored, if it is big enough; otherwise, a new array of the
  50.792 +     *          same runtime type is allocated for this purpose
  50.793 +     * @return an array containing all of the elements in this deque
  50.794 +     * @throws ArrayStoreException if the runtime type of the specified array
  50.795 +     *         is not a supertype of the runtime type of every element in
  50.796 +     *         this deque
  50.797 +     * @throws NullPointerException if the specified array is null
  50.798 +     */
  50.799 +    public <T> T[] toArray(T[] a) {
  50.800 +        int size = size();
  50.801 +        if (a.length < size)
  50.802 +            a = (T[])java.lang.reflect.Array.newInstance(
  50.803 +                    a.getClass().getComponentType(), size);
  50.804 +        copyElements(a);
  50.805 +        if (a.length > size)
  50.806 +            a[size] = null;
  50.807 +        return a;
  50.808 +    }
  50.809 +
  50.810 +    // *** Object methods ***
  50.811 +
  50.812 +    /**
  50.813 +     * Returns a copy of this deque.
  50.814 +     *
  50.815 +     * @return a copy of this deque
  50.816 +     */
  50.817 +    public ArrayDeque<E> clone() {
  50.818 +        try {
  50.819 +            ArrayDeque<E> result = (ArrayDeque<E>) super.clone();
  50.820 +            result.elements = Arrays.copyOf(elements, elements.length);
  50.821 +            return result;
  50.822 +
  50.823 +        } catch (CloneNotSupportedException e) {
  50.824 +            throw new AssertionError();
  50.825 +        }
  50.826 +    }
  50.827 +
  50.828 +    /**
  50.829 +     * Appease the serialization gods.
  50.830 +     */
  50.831 +    private static final long serialVersionUID = 2340985798034038923L;
  50.832 +
  50.833 +}
    51.1 --- a/emul/compact/src/main/java/java/util/ArrayList.java	Tue Feb 05 16:40:01 2013 +0100
    51.2 +++ b/emul/compact/src/main/java/java/util/ArrayList.java	Tue Feb 05 17:04:22 2013 +0100
    51.3 @@ -25,7 +25,6 @@
    51.4  
    51.5  package java.util;
    51.6  
    51.7 -import org.apidesign.bck2brwsr.emul.lang.System;
    51.8  
    51.9  /**
   51.10   * Resizable-array implementation of the <tt>List</tt> interface.  Implements
    52.1 --- a/emul/compact/src/main/java/java/util/Arrays.java	Tue Feb 05 16:40:01 2013 +0100
    52.2 +++ b/emul/compact/src/main/java/java/util/Arrays.java	Tue Feb 05 17:04:22 2013 +0100
    52.3 @@ -26,7 +26,6 @@
    52.4  package java.util;
    52.5  
    52.6  import java.lang.reflect.*;
    52.7 -import org.apidesign.bck2brwsr.emul.lang.System;
    52.8  
    52.9  /**
   52.10   * This class contains various methods for manipulating arrays (such as
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/emul/compact/src/main/java/java/util/Collections.java	Tue Feb 05 17:04:22 2013 +0100
    53.3 @@ -0,0 +1,3953 @@
    53.4 +/*
    53.5 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
    53.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    53.7 + *
    53.8 + * This code is free software; you can redistribute it and/or modify it
    53.9 + * under the terms of the GNU General Public License version 2 only, as
   53.10 + * published by the Free Software Foundation.  Oracle designates this
   53.11 + * particular file as subject to the "Classpath" exception as provided
   53.12 + * by Oracle in the LICENSE file that accompanied this code.
   53.13 + *
   53.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   53.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   53.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   53.17 + * version 2 for more details (a copy is included in the LICENSE file that
   53.18 + * accompanied this code).
   53.19 + *
   53.20 + * You should have received a copy of the GNU General Public License version
   53.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   53.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   53.23 + *
   53.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   53.25 + * or visit www.oracle.com if you need additional information or have any
   53.26 + * questions.
   53.27 + */
   53.28 +
   53.29 +package java.util;
   53.30 +import java.io.Serializable;
   53.31 +import java.io.IOException;
   53.32 +import java.lang.reflect.Array;
   53.33 +
   53.34 +/**
   53.35 + * This class consists exclusively of static methods that operate on or return
   53.36 + * collections.  It contains polymorphic algorithms that operate on
   53.37 + * collections, "wrappers", which return a new collection backed by a
   53.38 + * specified collection, and a few other odds and ends.
   53.39 + *
   53.40 + * <p>The methods of this class all throw a <tt>NullPointerException</tt>
   53.41 + * if the collections or class objects provided to them are null.
   53.42 + *
   53.43 + * <p>The documentation for the polymorphic algorithms contained in this class
   53.44 + * generally includes a brief description of the <i>implementation</i>.  Such
   53.45 + * descriptions should be regarded as <i>implementation notes</i>, rather than
   53.46 + * parts of the <i>specification</i>.  Implementors should feel free to
   53.47 + * substitute other algorithms, so long as the specification itself is adhered
   53.48 + * to.  (For example, the algorithm used by <tt>sort</tt> does not have to be
   53.49 + * a mergesort, but it does have to be <i>stable</i>.)
   53.50 + *
   53.51 + * <p>The "destructive" algorithms contained in this class, that is, the
   53.52 + * algorithms that modify the collection on which they operate, are specified
   53.53 + * to throw <tt>UnsupportedOperationException</tt> if the collection does not
   53.54 + * support the appropriate mutation primitive(s), such as the <tt>set</tt>
   53.55 + * method.  These algorithms may, but are not required to, throw this
   53.56 + * exception if an invocation would have no effect on the collection.  For
   53.57 + * example, invoking the <tt>sort</tt> method on an unmodifiable list that is
   53.58 + * already sorted may or may not throw <tt>UnsupportedOperationException</tt>.
   53.59 + *
   53.60 + * <p>This class is a member of the
   53.61 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
   53.62 + * Java Collections Framework</a>.
   53.63 + *
   53.64 + * @author  Josh Bloch
   53.65 + * @author  Neal Gafter
   53.66 + * @see     Collection
   53.67 + * @see     Set
   53.68 + * @see     List
   53.69 + * @see     Map
   53.70 + * @since   1.2
   53.71 + */
   53.72 +
   53.73 +public class Collections {
   53.74 +    // Suppresses default constructor, ensuring non-instantiability.
   53.75 +    private Collections() {
   53.76 +    }
   53.77 +
   53.78 +    // Algorithms
   53.79 +
   53.80 +    /*
   53.81 +     * Tuning parameters for algorithms - Many of the List algorithms have
   53.82 +     * two implementations, one of which is appropriate for RandomAccess
   53.83 +     * lists, the other for "sequential."  Often, the random access variant
   53.84 +     * yields better performance on small sequential access lists.  The
   53.85 +     * tuning parameters below determine the cutoff point for what constitutes
   53.86 +     * a "small" sequential access list for each algorithm.  The values below
   53.87 +     * were empirically determined to work well for LinkedList. Hopefully
   53.88 +     * they should be reasonable for other sequential access List
   53.89 +     * implementations.  Those doing performance work on this code would
   53.90 +     * do well to validate the values of these parameters from time to time.
   53.91 +     * (The first word of each tuning parameter name is the algorithm to which
   53.92 +     * it applies.)
   53.93 +     */
   53.94 +    private static final int BINARYSEARCH_THRESHOLD   = 5000;
   53.95 +    private static final int REVERSE_THRESHOLD        =   18;
   53.96 +    private static final int SHUFFLE_THRESHOLD        =    5;
   53.97 +    private static final int FILL_THRESHOLD           =   25;
   53.98 +    private static final int ROTATE_THRESHOLD         =  100;
   53.99 +    private static final int COPY_THRESHOLD           =   10;
  53.100 +    private static final int REPLACEALL_THRESHOLD     =   11;
  53.101 +    private static final int INDEXOFSUBLIST_THRESHOLD =   35;
  53.102 +
  53.103 +    /**
  53.104 +     * Sorts the specified list into ascending order, according to the
  53.105 +     * {@linkplain Comparable natural ordering} of its elements.
  53.106 +     * All elements in the list must implement the {@link Comparable}
  53.107 +     * interface.  Furthermore, all elements in the list must be
  53.108 +     * <i>mutually comparable</i> (that is, {@code e1.compareTo(e2)}
  53.109 +     * must not throw a {@code ClassCastException} for any elements
  53.110 +     * {@code e1} and {@code e2} in the list).
  53.111 +     *
  53.112 +     * <p>This sort is guaranteed to be <i>stable</i>:  equal elements will
  53.113 +     * not be reordered as a result of the sort.
  53.114 +     *
  53.115 +     * <p>The specified list must be modifiable, but need not be resizable.
  53.116 +     *
  53.117 +     * <p>Implementation note: This implementation is a stable, adaptive,
  53.118 +     * iterative mergesort that requires far fewer than n lg(n) comparisons
  53.119 +     * when the input array is partially sorted, while offering the
  53.120 +     * performance of a traditional mergesort when the input array is
  53.121 +     * randomly ordered.  If the input array is nearly sorted, the
  53.122 +     * implementation requires approximately n comparisons.  Temporary
  53.123 +     * storage requirements vary from a small constant for nearly sorted
  53.124 +     * input arrays to n/2 object references for randomly ordered input
  53.125 +     * arrays.
  53.126 +     *
  53.127 +     * <p>The implementation takes equal advantage of ascending and
  53.128 +     * descending order in its input array, and can take advantage of
  53.129 +     * ascending and descending order in different parts of the same
  53.130 +     * input array.  It is well-suited to merging two or more sorted arrays:
  53.131 +     * simply concatenate the arrays and sort the resulting array.
  53.132 +     *
  53.133 +     * <p>The implementation was adapted from Tim Peters's list sort for Python
  53.134 +     * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt">
  53.135 +     * TimSort</a>).  It uses techiques from Peter McIlroy's "Optimistic
  53.136 +     * Sorting and Information Theoretic Complexity", in Proceedings of the
  53.137 +     * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474,
  53.138 +     * January 1993.
  53.139 +     *
  53.140 +     * <p>This implementation dumps the specified list into an array, sorts
  53.141 +     * the array, and iterates over the list resetting each element
  53.142 +     * from the corresponding position in the array.  This avoids the
  53.143 +     * n<sup>2</sup> log(n) performance that would result from attempting
  53.144 +     * to sort a linked list in place.
  53.145 +     *
  53.146 +     * @param  list the list to be sorted.
  53.147 +     * @throws ClassCastException if the list contains elements that are not
  53.148 +     *         <i>mutually comparable</i> (for example, strings and integers).
  53.149 +     * @throws UnsupportedOperationException if the specified list's
  53.150 +     *         list-iterator does not support the {@code set} operation.
  53.151 +     * @throws IllegalArgumentException (optional) if the implementation
  53.152 +     *         detects that the natural ordering of the list elements is
  53.153 +     *         found to violate the {@link Comparable} contract
  53.154 +     */
  53.155 +    public static <T extends Comparable<? super T>> void sort(List<T> list) {
  53.156 +        Object[] a = list.toArray();
  53.157 +        Arrays.sort(a);
  53.158 +        ListIterator<T> i = list.listIterator();
  53.159 +        for (int j=0; j<a.length; j++) {
  53.160 +            i.next();
  53.161 +            i.set((T)a[j]);
  53.162 +        }
  53.163 +    }
  53.164 +
  53.165 +    /**
  53.166 +     * Sorts the specified list according to the order induced by the
  53.167 +     * specified comparator.  All elements in the list must be <i>mutually
  53.168 +     * comparable</i> using the specified comparator (that is,
  53.169 +     * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException}
  53.170 +     * for any elements {@code e1} and {@code e2} in the list).
  53.171 +     *
  53.172 +     * <p>This sort is guaranteed to be <i>stable</i>:  equal elements will
  53.173 +     * not be reordered as a result of the sort.
  53.174 +     *
  53.175 +     * <p>The specified list must be modifiable, but need not be resizable.
  53.176 +     *
  53.177 +     * <p>Implementation note: This implementation is a stable, adaptive,
  53.178 +     * iterative mergesort that requires far fewer than n lg(n) comparisons
  53.179 +     * when the input array is partially sorted, while offering the
  53.180 +     * performance of a traditional mergesort when the input array is
  53.181 +     * randomly ordered.  If the input array is nearly sorted, the
  53.182 +     * implementation requires approximately n comparisons.  Temporary
  53.183 +     * storage requirements vary from a small constant for nearly sorted
  53.184 +     * input arrays to n/2 object references for randomly ordered input
  53.185 +     * arrays.
  53.186 +     *
  53.187 +     * <p>The implementation takes equal advantage of ascending and
  53.188 +     * descending order in its input array, and can take advantage of
  53.189 +     * ascending and descending order in different parts of the same
  53.190 +     * input array.  It is well-suited to merging two or more sorted arrays:
  53.191 +     * simply concatenate the arrays and sort the resulting array.
  53.192 +     *
  53.193 +     * <p>The implementation was adapted from Tim Peters's list sort for Python
  53.194 +     * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt">
  53.195 +     * TimSort</a>).  It uses techiques from Peter McIlroy's "Optimistic
  53.196 +     * Sorting and Information Theoretic Complexity", in Proceedings of the
  53.197 +     * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474,
  53.198 +     * January 1993.
  53.199 +     *
  53.200 +     * <p>This implementation dumps the specified list into an array, sorts
  53.201 +     * the array, and iterates over the list resetting each element
  53.202 +     * from the corresponding position in the array.  This avoids the
  53.203 +     * n<sup>2</sup> log(n) performance that would result from attempting
  53.204 +     * to sort a linked list in place.
  53.205 +     *
  53.206 +     * @param  list the list to be sorted.
  53.207 +     * @param  c the comparator to determine the order of the list.  A
  53.208 +     *        {@code null} value indicates that the elements' <i>natural
  53.209 +     *        ordering</i> should be used.
  53.210 +     * @throws ClassCastException if the list contains elements that are not
  53.211 +     *         <i>mutually comparable</i> using the specified comparator.
  53.212 +     * @throws UnsupportedOperationException if the specified list's
  53.213 +     *         list-iterator does not support the {@code set} operation.
  53.214 +     * @throws IllegalArgumentException (optional) if the comparator is
  53.215 +     *         found to violate the {@link Comparator} contract
  53.216 +     */
  53.217 +    public static <T> void sort(List<T> list, Comparator<? super T> c) {
  53.218 +        Object[] a = list.toArray();
  53.219 +        Arrays.sort(a, (Comparator)c);
  53.220 +        ListIterator i = list.listIterator();
  53.221 +        for (int j=0; j<a.length; j++) {
  53.222 +            i.next();
  53.223 +            i.set(a[j]);
  53.224 +        }
  53.225 +    }
  53.226 +
  53.227 +
  53.228 +    /**
  53.229 +     * Searches the specified list for the specified object using the binary
  53.230 +     * search algorithm.  The list must be sorted into ascending order
  53.231 +     * according to the {@linkplain Comparable natural ordering} of its
  53.232 +     * elements (as by the {@link #sort(List)} method) prior to making this
  53.233 +     * call.  If it is not sorted, the results are undefined.  If the list
  53.234 +     * contains multiple elements equal to the specified object, there is no
  53.235 +     * guarantee which one will be found.
  53.236 +     *
  53.237 +     * <p>This method runs in log(n) time for a "random access" list (which
  53.238 +     * provides near-constant-time positional access).  If the specified list
  53.239 +     * does not implement the {@link RandomAccess} interface and is large,
  53.240 +     * this method will do an iterator-based binary search that performs
  53.241 +     * O(n) link traversals and O(log n) element comparisons.
  53.242 +     *
  53.243 +     * @param  list the list to be searched.
  53.244 +     * @param  key the key to be searched for.
  53.245 +     * @return the index of the search key, if it is contained in the list;
  53.246 +     *         otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>.  The
  53.247 +     *         <i>insertion point</i> is defined as the point at which the
  53.248 +     *         key would be inserted into the list: the index of the first
  53.249 +     *         element greater than the key, or <tt>list.size()</tt> if all
  53.250 +     *         elements in the list are less than the specified key.  Note
  53.251 +     *         that this guarantees that the return value will be &gt;= 0 if
  53.252 +     *         and only if the key is found.
  53.253 +     * @throws ClassCastException if the list contains elements that are not
  53.254 +     *         <i>mutually comparable</i> (for example, strings and
  53.255 +     *         integers), or the search key is not mutually comparable
  53.256 +     *         with the elements of the list.
  53.257 +     */
  53.258 +    public static <T>
  53.259 +    int binarySearch(List<? extends Comparable<? super T>> list, T key) {
  53.260 +        if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
  53.261 +            return Collections.indexedBinarySearch(list, key);
  53.262 +        else
  53.263 +            return Collections.iteratorBinarySearch(list, key);
  53.264 +    }
  53.265 +
  53.266 +    private static <T>
  53.267 +    int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key)
  53.268 +    {
  53.269 +        int low = 0;
  53.270 +        int high = list.size()-1;
  53.271 +
  53.272 +        while (low <= high) {
  53.273 +            int mid = (low + high) >>> 1;
  53.274 +            Comparable<? super T> midVal = list.get(mid);
  53.275 +            int cmp = midVal.compareTo(key);
  53.276 +
  53.277 +            if (cmp < 0)
  53.278 +                low = mid + 1;
  53.279 +            else if (cmp > 0)
  53.280 +                high = mid - 1;
  53.281 +            else
  53.282 +                return mid; // key found
  53.283 +        }
  53.284 +        return -(low + 1);  // key not found
  53.285 +    }
  53.286 +
  53.287 +    private static <T>
  53.288 +    int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key)
  53.289 +    {
  53.290 +        int low = 0;
  53.291 +        int high = list.size()-1;
  53.292 +        ListIterator<? extends Comparable<? super T>> i = list.listIterator();
  53.293 +
  53.294 +        while (low <= high) {
  53.295 +            int mid = (low + high) >>> 1;
  53.296 +            Comparable<? super T> midVal = get(i, mid);
  53.297 +            int cmp = midVal.compareTo(key);
  53.298 +
  53.299 +            if (cmp < 0)
  53.300 +                low = mid + 1;
  53.301 +            else if (cmp > 0)
  53.302 +                high = mid - 1;
  53.303 +            else
  53.304 +                return mid; // key found
  53.305 +        }
  53.306 +        return -(low + 1);  // key not found
  53.307 +    }
  53.308 +
  53.309 +    /**
  53.310 +     * Gets the ith element from the given list by repositioning the specified
  53.311 +     * list listIterator.
  53.312 +     */
  53.313 +    private static <T> T get(ListIterator<? extends T> i, int index) {
  53.314 +        T obj = null;
  53.315 +        int pos = i.nextIndex();
  53.316 +        if (pos <= index) {
  53.317 +            do {
  53.318 +                obj = i.next();
  53.319 +            } while (pos++ < index);
  53.320 +        } else {
  53.321 +            do {
  53.322 +                obj = i.previous();
  53.323 +            } while (--pos > index);
  53.324 +        }
  53.325 +        return obj;
  53.326 +    }
  53.327 +
  53.328 +    /**
  53.329 +     * Searches the specified list for the specified object using the binary
  53.330 +     * search algorithm.  The list must be sorted into ascending order
  53.331 +     * according to the specified comparator (as by the
  53.332 +     * {@link #sort(List, Comparator) sort(List, Comparator)}
  53.333 +     * method), prior to making this call.  If it is
  53.334 +     * not sorted, the results are undefined.  If the list contains multiple
  53.335 +     * elements equal to the specified object, there is no guarantee which one
  53.336 +     * will be found.
  53.337 +     *
  53.338 +     * <p>This method runs in log(n) time for a "random access" list (which
  53.339 +     * provides near-constant-time positional access).  If the specified list
  53.340 +     * does not implement the {@link RandomAccess} interface and is large,
  53.341 +     * this method will do an iterator-based binary search that performs
  53.342 +     * O(n) link traversals and O(log n) element comparisons.
  53.343 +     *
  53.344 +     * @param  list the list to be searched.
  53.345 +     * @param  key the key to be searched for.
  53.346 +     * @param  c the comparator by which the list is ordered.
  53.347 +     *         A <tt>null</tt> value indicates that the elements'
  53.348 +     *         {@linkplain Comparable natural ordering} should be used.
  53.349 +     * @return the index of the search key, if it is contained in the list;
  53.350 +     *         otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>.  The
  53.351 +     *         <i>insertion point</i> is defined as the point at which the
  53.352 +     *         key would be inserted into the list: the index of the first
  53.353 +     *         element greater than the key, or <tt>list.size()</tt> if all
  53.354 +     *         elements in the list are less than the specified key.  Note
  53.355 +     *         that this guarantees that the return value will be &gt;= 0 if
  53.356 +     *         and only if the key is found.
  53.357 +     * @throws ClassCastException if the list contains elements that are not
  53.358 +     *         <i>mutually comparable</i> using the specified comparator,
  53.359 +     *         or the search key is not mutually comparable with the
  53.360 +     *         elements of the list using this comparator.
  53.361 +     */
  53.362 +    public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c) {
  53.363 +        if (c==null)
  53.364 +            return binarySearch((List) list, key);
  53.365 +
  53.366 +        if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
  53.367 +            return Collections.indexedBinarySearch(list, key, c);
  53.368 +        else
  53.369 +            return Collections.iteratorBinarySearch(list, key, c);
  53.370 +    }
  53.371 +
  53.372 +    private static <T> int indexedBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) {
  53.373 +        int low = 0;
  53.374 +        int high = l.size()-1;
  53.375 +
  53.376 +        while (low <= high) {
  53.377 +            int mid = (low + high) >>> 1;
  53.378 +            T midVal = l.get(mid);
  53.379 +            int cmp = c.compare(midVal, key);
  53.380 +
  53.381 +            if (cmp < 0)
  53.382 +                low = mid + 1;
  53.383 +            else if (cmp > 0)
  53.384 +                high = mid - 1;
  53.385 +            else
  53.386 +                return mid; // key found
  53.387 +        }
  53.388 +        return -(low + 1);  // key not found
  53.389 +    }
  53.390 +
  53.391 +    private static <T> int iteratorBinarySearch(List<? extends T> l, T key, Comparator<? super T> c) {
  53.392 +        int low = 0;
  53.393 +        int high = l.size()-1;
  53.394 +        ListIterator<? extends T> i = l.listIterator();
  53.395 +
  53.396 +        while (low <= high) {
  53.397 +            int mid = (low + high) >>> 1;
  53.398 +            T midVal = get(i, mid);
  53.399 +            int cmp = c.compare(midVal, key);
  53.400 +
  53.401 +            if (cmp < 0)
  53.402 +                low = mid + 1;
  53.403 +            else if (cmp > 0)
  53.404 +                high = mid - 1;
  53.405 +            else
  53.406 +                return mid; // key found
  53.407 +        }
  53.408 +        return -(low + 1);  // key not found
  53.409 +    }
  53.410 +
  53.411 +    private interface SelfComparable extends Comparable<SelfComparable> {}
  53.412 +
  53.413 +
  53.414 +    /**
  53.415 +     * Reverses the order of the elements in the specified list.<p>
  53.416 +     *
  53.417 +     * This method runs in linear time.
  53.418 +     *
  53.419 +     * @param  list the list whose elements are to be reversed.
  53.420 +     * @throws UnsupportedOperationException if the specified list or
  53.421 +     *         its list-iterator does not support the <tt>set</tt> operation.
  53.422 +     */
  53.423 +    public static void reverse(List<?> list) {
  53.424 +        int size = list.size();
  53.425 +        if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {
  53.426 +            for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)
  53.427 +                swap(list, i, j);
  53.428 +        } else {
  53.429 +            ListIterator fwd = list.listIterator();
  53.430 +            ListIterator rev = list.listIterator(size);
  53.431 +            for (int i=0, mid=list.size()>>1; i<mid; i++) {
  53.432 +                Object tmp = fwd.next();
  53.433 +                fwd.set(rev.previous());
  53.434 +                rev.set(tmp);
  53.435 +            }
  53.436 +        }
  53.437 +    }
  53.438 +
  53.439 +    /**
  53.440 +     * Randomly permutes the specified list using a default source of
  53.441 +     * randomness.  All permutations occur with approximately equal
  53.442 +     * likelihood.<p>
  53.443 +     *
  53.444 +     * The hedge "approximately" is used in the foregoing description because
  53.445 +     * default source of randomness is only approximately an unbiased source
  53.446 +     * of independently chosen bits. If it were a perfect source of randomly
  53.447 +     * chosen bits, then the algorithm would choose permutations with perfect
  53.448 +     * uniformity.<p>
  53.449 +     *
  53.450 +     * This implementation traverses the list backwards, from the last element
  53.451 +     * up to the second, repeatedly swapping a randomly selected element into
  53.452 +     * the "current position".  Elements are randomly selected from the
  53.453 +     * portion of the list that runs from the first element to the current
  53.454 +     * position, inclusive.<p>
  53.455 +     *
  53.456 +     * This method runs in linear time.  If the specified list does not
  53.457 +     * implement the {@link RandomAccess} interface and is large, this
  53.458 +     * implementation dumps the specified list into an array before shuffling
  53.459 +     * it, and dumps the shuffled array back into the list.  This avoids the
  53.460 +     * quadratic behavior that would result from shuffling a "sequential
  53.461 +     * access" list in place.
  53.462 +     *
  53.463 +     * @param  list the list to be shuffled.
  53.464 +     * @throws UnsupportedOperationException if the specified list or
  53.465 +     *         its list-iterator does not support the <tt>set</tt> operation.
  53.466 +     */
  53.467 +    public static void shuffle(List<?> list) {
  53.468 +        Random rnd = r;
  53.469 +        if (rnd == null)
  53.470 +            r = rnd = new Random();
  53.471 +        shuffle(list, rnd);
  53.472 +    }
  53.473 +    private static Random r;
  53.474 +
  53.475 +    /**
  53.476 +     * Randomly permute the specified list using the specified source of
  53.477 +     * randomness.  All permutations occur with equal likelihood
  53.478 +     * assuming that the source of randomness is fair.<p>
  53.479 +     *
  53.480 +     * This implementation traverses the list backwards, from the last element
  53.481 +     * up to the second, repeatedly swapping a randomly selected element into
  53.482 +     * the "current position".  Elements are randomly selected from the
  53.483 +     * portion of the list that runs from the first element to the current
  53.484 +     * position, inclusive.<p>
  53.485 +     *
  53.486 +     * This method runs in linear time.  If the specified list does not
  53.487 +     * implement the {@link RandomAccess} interface and is large, this
  53.488 +     * implementation dumps the specified list into an array before shuffling
  53.489 +     * it, and dumps the shuffled array back into the list.  This avoids the
  53.490 +     * quadratic behavior that would result from shuffling a "sequential
  53.491 +     * access" list in place.
  53.492 +     *
  53.493 +     * @param  list the list to be shuffled.
  53.494 +     * @param  rnd the source of randomness to use to shuffle the list.
  53.495 +     * @throws UnsupportedOperationException if the specified list or its
  53.496 +     *         list-iterator does not support the <tt>set</tt> operation.
  53.497 +     */
  53.498 +    public static void shuffle(List<?> list, Random rnd) {
  53.499 +        int size = list.size();
  53.500 +        if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
  53.501 +            for (int i=size; i>1; i--)
  53.502 +                swap(list, i-1, rnd.nextInt(i));
  53.503 +        } else {
  53.504 +            Object arr[] = list.toArray();
  53.505 +
  53.506 +            // Shuffle array
  53.507 +            for (int i=size; i>1; i--)
  53.508 +                swap(arr, i-1, rnd.nextInt(i));
  53.509 +
  53.510 +            // Dump array back into list
  53.511 +            ListIterator it = list.listIterator();
  53.512 +            for (int i=0; i<arr.length; i++) {
  53.513 +                it.next();
  53.514 +                it.set(arr[i]);
  53.515 +            }
  53.516 +        }
  53.517 +    }
  53.518 +
  53.519 +    /**
  53.520 +     * Swaps the elements at the specified positions in the specified list.
  53.521 +     * (If the specified positions are equal, invoking this method leaves
  53.522 +     * the list unchanged.)
  53.523 +     *
  53.524 +     * @param list The list in which to swap elements.
  53.525 +     * @param i the index of one element to be swapped.
  53.526 +     * @param j the index of the other element to be swapped.
  53.527 +     * @throws IndexOutOfBoundsException if either <tt>i</tt> or <tt>j</tt>
  53.528 +     *         is out of range (i &lt; 0 || i &gt;= list.size()
  53.529 +     *         || j &lt; 0 || j &gt;= list.size()).
  53.530 +     * @since 1.4
  53.531 +     */
  53.532 +    public static void swap(List<?> list, int i, int j) {
  53.533 +        final List l = list;
  53.534 +        l.set(i, l.set(j, l.get(i)));
  53.535 +    }
  53.536 +
  53.537 +    /**
  53.538 +     * Swaps the two specified elements in the specified array.
  53.539 +     */
  53.540 +    private static void swap(Object[] arr, int i, int j) {
  53.541 +        Object tmp = arr[i];
  53.542 +        arr[i] = arr[j];
  53.543 +        arr[j] = tmp;
  53.544 +    }
  53.545 +
  53.546 +    /**
  53.547 +     * Replaces all of the elements of the specified list with the specified
  53.548 +     * element. <p>
  53.549 +     *
  53.550 +     * This method runs in linear time.
  53.551 +     *
  53.552 +     * @param  list the list to be filled with the specified element.
  53.553 +     * @param  obj The element with which to fill the specified list.
  53.554 +     * @throws UnsupportedOperationException if the specified list or its
  53.555 +     *         list-iterator does not support the <tt>set</tt> operation.
  53.556 +     */
  53.557 +    public static <T> void fill(List<? super T> list, T obj) {
  53.558 +        int size = list.size();
  53.559 +
  53.560 +        if (size < FILL_THRESHOLD || list instanceof RandomAccess) {
  53.561 +            for (int i=0; i<size; i++)
  53.562 +                list.set(i, obj);
  53.563 +        } else {
  53.564 +            ListIterator<? super T> itr = list.listIterator();
  53.565 +            for (int i=0; i<size; i++) {
  53.566 +                itr.next();
  53.567 +                itr.set(obj);
  53.568 +            }
  53.569 +        }
  53.570 +    }
  53.571 +
  53.572 +    /**
  53.573 +     * Copies all of the elements from one list into another.  After the
  53.574 +     * operation, the index of each copied element in the destination list
  53.575 +     * will be identical to its index in the source list.  The destination
  53.576 +     * list must be at least as long as the source list.  If it is longer, the
  53.577 +     * remaining elements in the destination list are unaffected. <p>
  53.578 +     *
  53.579 +     * This method runs in linear time.
  53.580 +     *
  53.581 +     * @param  dest The destination list.
  53.582 +     * @param  src The source list.
  53.583 +     * @throws IndexOutOfBoundsException if the destination list is too small
  53.584 +     *         to contain the entire source List.
  53.585 +     * @throws UnsupportedOperationException if the destination list's
  53.586 +     *         list-iterator does not support the <tt>set</tt> operation.
  53.587 +     */
  53.588 +    public static <T> void copy(List<? super T> dest, List<? extends T> src) {
  53.589 +        int srcSize = src.size();
  53.590 +        if (srcSize > dest.size())
  53.591 +            throw new IndexOutOfBoundsException("Source does not fit in dest");
  53.592 +
  53.593 +        if (srcSize < COPY_THRESHOLD ||
  53.594 +            (src instanceof RandomAccess && dest instanceof RandomAccess)) {
  53.595 +            for (int i=0; i<srcSize; i++)
  53.596 +                dest.set(i, src.get(i));
  53.597 +        } else {
  53.598 +            ListIterator<? super T> di=dest.listIterator();
  53.599 +            ListIterator<? extends T> si=src.listIterator();
  53.600 +            for (int i=0; i<srcSize; i++) {
  53.601 +                di.next();
  53.602 +                di.set(si.next());
  53.603 +            }
  53.604 +        }
  53.605 +    }
  53.606 +
  53.607 +    /**
  53.608 +     * Returns the minimum element of the given collection, according to the
  53.609 +     * <i>natural ordering</i> of its elements.  All elements in the
  53.610 +     * collection must implement the <tt>Comparable</tt> interface.
  53.611 +     * Furthermore, all elements in the collection must be <i>mutually
  53.612 +     * comparable</i> (that is, <tt>e1.compareTo(e2)</tt> must not throw a
  53.613 +     * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
  53.614 +     * <tt>e2</tt> in the collection).<p>
  53.615 +     *
  53.616 +     * This method iterates over the entire collection, hence it requires
  53.617 +     * time proportional to the size of the collection.
  53.618 +     *
  53.619 +     * @param  coll the collection whose minimum element is to be determined.
  53.620 +     * @return the minimum element of the given collection, according
  53.621 +     *         to the <i>natural ordering</i> of its elements.
  53.622 +     * @throws ClassCastException if the collection contains elements that are
  53.623 +     *         not <i>mutually comparable</i> (for example, strings and
  53.624 +     *         integers).
  53.625 +     * @throws NoSuchElementException if the collection is empty.
  53.626 +     * @see Comparable
  53.627 +     */
  53.628 +    public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) {
  53.629 +        Iterator<? extends T> i = coll.iterator();
  53.630 +        T candidate = i.next();
  53.631 +
  53.632 +        while (i.hasNext()) {
  53.633 +            T next = i.next();
  53.634 +            if (next.compareTo(candidate) < 0)
  53.635 +                candidate = next;
  53.636 +        }
  53.637 +        return candidate;
  53.638 +    }
  53.639 +
  53.640 +    /**
  53.641 +     * Returns the minimum element of the given collection, according to the
  53.642 +     * order induced by the specified comparator.  All elements in the
  53.643 +     * collection must be <i>mutually comparable</i> by the specified
  53.644 +     * comparator (that is, <tt>comp.compare(e1, e2)</tt> must not throw a
  53.645 +     * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
  53.646 +     * <tt>e2</tt> in the collection).<p>
  53.647 +     *
  53.648 +     * This method iterates over the entire collection, hence it requires
  53.649 +     * time proportional to the size of the collection.
  53.650 +     *
  53.651 +     * @param  coll the collection whose minimum element is to be determined.
  53.652 +     * @param  comp the comparator with which to determine the minimum element.
  53.653 +     *         A <tt>null</tt> value indicates that the elements' <i>natural
  53.654 +     *         ordering</i> should be used.
  53.655 +     * @return the minimum element of the given collection, according
  53.656 +     *         to the specified comparator.
  53.657 +     * @throws ClassCastException if the collection contains elements that are
  53.658 +     *         not <i>mutually comparable</i> using the specified comparator.
  53.659 +     * @throws NoSuchElementException if the collection is empty.
  53.660 +     * @see Comparable
  53.661 +     */
  53.662 +    public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) {
  53.663 +        if (comp==null)
  53.664 +            return (T)min((Collection<SelfComparable>) (Collection) coll);
  53.665 +
  53.666 +        Iterator<? extends T> i = coll.iterator();
  53.667 +        T candidate = i.next();
  53.668 +
  53.669 +        while (i.hasNext()) {
  53.670 +            T next = i.next();
  53.671 +            if (comp.compare(next, candidate) < 0)
  53.672 +                candidate = next;
  53.673 +        }
  53.674 +        return candidate;
  53.675 +    }
  53.676 +
  53.677 +    /**
  53.678 +     * Returns the maximum element of the given collection, according to the
  53.679 +     * <i>natural ordering</i> of its elements.  All elements in the
  53.680 +     * collection must implement the <tt>Comparable</tt> interface.
  53.681 +     * Furthermore, all elements in the collection must be <i>mutually
  53.682 +     * comparable</i> (that is, <tt>e1.compareTo(e2)</tt> must not throw a
  53.683 +     * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
  53.684 +     * <tt>e2</tt> in the collection).<p>
  53.685 +     *
  53.686 +     * This method iterates over the entire collection, hence it requires
  53.687 +     * time proportional to the size of the collection.
  53.688 +     *
  53.689 +     * @param  coll the collection whose maximum element is to be determined.
  53.690 +     * @return the maximum element of the given collection, according
  53.691 +     *         to the <i>natural ordering</i> of its elements.
  53.692 +     * @throws ClassCastException if the collection contains elements that are
  53.693 +     *         not <i>mutually comparable</i> (for example, strings and
  53.694 +     *         integers).
  53.695 +     * @throws NoSuchElementException if the collection is empty.
  53.696 +     * @see Comparable
  53.697 +     */
  53.698 +    public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
  53.699 +        Iterator<? extends T> i = coll.iterator();
  53.700 +        T candidate = i.next();
  53.701 +
  53.702 +        while (i.hasNext()) {
  53.703 +            T next = i.next();
  53.704 +            if (next.compareTo(candidate) > 0)
  53.705 +                candidate = next;
  53.706 +        }
  53.707 +        return candidate;
  53.708 +    }
  53.709 +
  53.710 +    /**
  53.711 +     * Returns the maximum element of the given collection, according to the
  53.712 +     * order induced by the specified comparator.  All elements in the
  53.713 +     * collection must be <i>mutually comparable</i> by the specified
  53.714 +     * comparator (that is, <tt>comp.compare(e1, e2)</tt> must not throw a
  53.715 +     * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and
  53.716 +     * <tt>e2</tt> in the collection).<p>
  53.717 +     *
  53.718 +     * This method iterates over the entire collection, hence it requires
  53.719 +     * time proportional to the size of the collection.
  53.720 +     *
  53.721 +     * @param  coll the collection whose maximum element is to be determined.
  53.722 +     * @param  comp the comparator with which to determine the maximum element.
  53.723 +     *         A <tt>null</tt> value indicates that the elements' <i>natural
  53.724 +     *        ordering</i> should be used.
  53.725 +     * @return the maximum element of the given collection, according
  53.726 +     *         to the specified comparator.
  53.727 +     * @throws ClassCastException if the collection contains elements that are
  53.728 +     *         not <i>mutually comparable</i> using the specified comparator.
  53.729 +     * @throws NoSuchElementException if the collection is empty.
  53.730 +     * @see Comparable
  53.731 +     */
  53.732 +    public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) {
  53.733 +        if (comp==null)
  53.734 +            return (T)max((Collection<SelfComparable>) (Collection) coll);
  53.735 +
  53.736 +        Iterator<? extends T> i = coll.iterator();
  53.737 +        T candidate = i.next();
  53.738 +
  53.739 +        while (i.hasNext()) {
  53.740 +            T next = i.next();
  53.741 +            if (comp.compare(next, candidate) > 0)
  53.742 +                candidate = next;
  53.743 +        }
  53.744 +        return candidate;
  53.745 +    }
  53.746 +
  53.747 +    /**
  53.748 +     * Rotates the elements in the specified list by the specified distance.
  53.749 +     * After calling this method, the element at index <tt>i</tt> will be
  53.750 +     * the element previously at index <tt>(i - distance)</tt> mod
  53.751 +     * <tt>list.size()</tt>, for all values of <tt>i</tt> between <tt>0</tt>
  53.752 +     * and <tt>list.size()-1</tt>, inclusive.  (This method has no effect on
  53.753 +     * the size of the list.)
  53.754 +     *
  53.755 +     * <p>For example, suppose <tt>list</tt> comprises<tt> [t, a, n, k, s]</tt>.
  53.756 +     * After invoking <tt>Collections.rotate(list, 1)</tt> (or
  53.757 +     * <tt>Collections.rotate(list, -4)</tt>), <tt>list</tt> will comprise
  53.758 +     * <tt>[s, t, a, n, k]</tt>.
  53.759 +     *
  53.760 +     * <p>Note that this method can usefully be applied to sublists to
  53.761 +     * move one or more elements within a list while preserving the
  53.762 +     * order of the remaining elements.  For example, the following idiom
  53.763 +     * moves the element at index <tt>j</tt> forward to position
  53.764 +     * <tt>k</tt> (which must be greater than or equal to <tt>j</tt>):
  53.765 +     * <pre>
  53.766 +     *     Collections.rotate(list.subList(j, k+1), -1);
  53.767 +     * </pre>
  53.768 +     * To make this concrete, suppose <tt>list</tt> comprises
  53.769 +     * <tt>[a, b, c, d, e]</tt>.  To move the element at index <tt>1</tt>
  53.770 +     * (<tt>b</tt>) forward two positions, perform the following invocation:
  53.771 +     * <pre>
  53.772 +     *     Collections.rotate(l.subList(1, 4), -1);
  53.773 +     * </pre>
  53.774 +     * The resulting list is <tt>[a, c, d, b, e]</tt>.
  53.775 +     *
  53.776 +     * <p>To move more than one element forward, increase the absolute value
  53.777 +     * of the rotation distance.  To move elements backward, use a positive
  53.778 +     * shift distance.
  53.779 +     *
  53.780 +     * <p>If the specified list is small or implements the {@link
  53.781 +     * RandomAccess} interface, this implementation exchanges the first
  53.782 +     * element into the location it should go, and then repeatedly exchanges
  53.783 +     * the displaced element into the location it should go until a displaced
  53.784 +     * element is swapped into the first element.  If necessary, the process
  53.785 +     * is repeated on the second and successive elements, until the rotation
  53.786 +     * is complete.  If the specified list is large and doesn't implement the
  53.787 +     * <tt>RandomAccess</tt> interface, this implementation breaks the
  53.788 +     * list into two sublist views around index <tt>-distance mod size</tt>.
  53.789 +     * Then the {@link #reverse(List)} method is invoked on each sublist view,
  53.790 +     * and finally it is invoked on the entire list.  For a more complete
  53.791 +     * description of both algorithms, see Section 2.3 of Jon Bentley's
  53.792 +     * <i>Programming Pearls</i> (Addison-Wesley, 1986).
  53.793 +     *
  53.794 +     * @param list the list to be rotated.
  53.795 +     * @param distance the distance to rotate the list.  There are no
  53.796 +     *        constraints on this value; it may be zero, negative, or
  53.797 +     *        greater than <tt>list.size()</tt>.
  53.798 +     * @throws UnsupportedOperationException if the specified list or
  53.799 +     *         its list-iterator does not support the <tt>set</tt> operation.
  53.800 +     * @since 1.4
  53.801 +     */
  53.802 +    public static void rotate(List<?> list, int distance) {
  53.803 +        if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD)
  53.804 +            rotate1(list, distance);
  53.805 +        else
  53.806 +            rotate2(list, distance);
  53.807 +    }
  53.808 +
  53.809 +    private static <T> void rotate1(List<T> list, int distance) {
  53.810 +        int size = list.size();
  53.811 +        if (size == 0)
  53.812 +            return;
  53.813 +        distance = distance % size;
  53.814 +        if (distance < 0)
  53.815 +            distance += size;
  53.816 +        if (distance == 0)
  53.817 +            return;
  53.818 +
  53.819 +        for (int cycleStart = 0, nMoved = 0; nMoved != size; cycleStart++) {
  53.820 +            T displaced = list.get(cycleStart);
  53.821 +            int i = cycleStart;
  53.822 +            do {
  53.823 +                i += distance;
  53.824 +                if (i >= size)
  53.825 +                    i -= size;
  53.826 +                displaced = list.set(i, displaced);
  53.827 +                nMoved ++;
  53.828 +            } while (i != cycleStart);
  53.829 +        }
  53.830 +    }
  53.831 +
  53.832 +    private static void rotate2(List<?> list, int distance) {
  53.833 +        int size = list.size();
  53.834 +        if (size == 0)
  53.835 +            return;
  53.836 +        int mid =  -distance % size;
  53.837 +        if (mid < 0)
  53.838 +            mid += size;
  53.839 +        if (mid == 0)
  53.840 +            return;
  53.841 +
  53.842 +        reverse(list.subList(0, mid));
  53.843 +        reverse(list.subList(mid, size));
  53.844 +        reverse(list);
  53.845 +    }
  53.846 +
  53.847 +    /**
  53.848 +     * Replaces all occurrences of one specified value in a list with another.
  53.849 +     * More formally, replaces with <tt>newVal</tt> each element <tt>e</tt>
  53.850 +     * in <tt>list</tt> such that
  53.851 +     * <tt>(oldVal==null ? e==null : oldVal.equals(e))</tt>.
  53.852 +     * (This method has no effect on the size of the list.)
  53.853 +     *
  53.854 +     * @param list the list in which replacement is to occur.
  53.855 +     * @param oldVal the old value to be replaced.
  53.856 +     * @param newVal the new value with which <tt>oldVal</tt> is to be
  53.857 +     *        replaced.
  53.858 +     * @return <tt>true</tt> if <tt>list</tt> contained one or more elements
  53.859 +     *         <tt>e</tt> such that
  53.860 +     *         <tt>(oldVal==null ?  e==null : oldVal.equals(e))</tt>.
  53.861 +     * @throws UnsupportedOperationException if the specified list or
  53.862 +     *         its list-iterator does not support the <tt>set</tt> operation.
  53.863 +     * @since  1.4
  53.864 +     */
  53.865 +    public static <T> boolean replaceAll(List<T> list, T oldVal, T newVal) {
  53.866 +        boolean result = false;
  53.867 +        int size = list.size();
  53.868 +        if (size < REPLACEALL_THRESHOLD || list instanceof RandomAccess) {
  53.869 +            if (oldVal==null) {
  53.870 +                for (int i=0; i<size; i++) {
  53.871 +                    if (list.get(i)==null) {
  53.872 +                        list.set(i, newVal);
  53.873 +                        result = true;
  53.874 +                    }
  53.875 +                }
  53.876 +            } else {
  53.877 +                for (int i=0; i<size; i++) {
  53.878 +                    if (oldVal.equals(list.get(i))) {
  53.879 +                        list.set(i, newVal);
  53.880 +                        result = true;
  53.881 +                    }
  53.882 +                }
  53.883 +            }
  53.884 +        } else {
  53.885 +            ListIterator<T> itr=list.listIterator();
  53.886 +            if (oldVal==null) {
  53.887 +                for (int i=0; i<size; i++) {
  53.888 +                    if (itr.next()==null) {
  53.889 +                        itr.set(newVal);
  53.890 +                        result = true;
  53.891 +                    }
  53.892 +                }
  53.893 +            } else {
  53.894 +                for (int i=0; i<size; i++) {
  53.895 +                    if (oldVal.equals(itr.next())) {
  53.896 +                        itr.set(newVal);
  53.897 +                        result = true;
  53.898 +                    }
  53.899 +                }
  53.900 +            }
  53.901 +        }
  53.902 +        return result;
  53.903 +    }
  53.904 +
  53.905 +    /**
  53.906 +     * Returns the starting position of the first occurrence of the specified
  53.907 +     * target list within the specified source list, or -1 if there is no
  53.908 +     * such occurrence.  More formally, returns the lowest index <tt>i</tt>
  53.909 +     * such that <tt>source.subList(i, i+target.size()).equals(target)</tt>,
  53.910 +     * or -1 if there is no such index.  (Returns -1 if
  53.911 +     * <tt>target.size() > source.size()</tt>.)
  53.912 +     *
  53.913 +     * <p>This implementation uses the "brute force" technique of scanning
  53.914 +     * over the source list, looking for a match with the target at each
  53.915 +     * location in turn.
  53.916 +     *
  53.917 +     * @param source the list in which to search for the first occurrence
  53.918 +     *        of <tt>target</tt>.
  53.919 +     * @param target the list to search for as a subList of <tt>source</tt>.
  53.920 +     * @return the starting position of the first occurrence of the specified
  53.921 +     *         target list within the specified source list, or -1 if there
  53.922 +     *         is no such occurrence.
  53.923 +     * @since  1.4
  53.924 +     */
  53.925 +    public static int indexOfSubList(List<?> source, List<?> target) {
  53.926 +        int sourceSize = source.size();
  53.927 +        int targetSize = target.size();
  53.928 +        int maxCandidate = sourceSize - targetSize;
  53.929 +
  53.930 +        if (sourceSize < INDEXOFSUBLIST_THRESHOLD ||
  53.931 +            (source instanceof RandomAccess&&target instanceof RandomAccess)) {
  53.932 +        nextCand:
  53.933 +            for (int candidate = 0; candidate <= maxCandidate; candidate++) {
  53.934 +                for (int i=0, j=candidate; i<targetSize; i++, j++)
  53.935 +                    if (!eq(target.get(i), source.get(j)))
  53.936 +                        continue nextCand;  // Element mismatch, try next cand
  53.937 +                return candidate;  // All elements of candidate matched target
  53.938 +            }
  53.939 +        } else {  // Iterator version of above algorithm
  53.940 +            ListIterator<?> si = source.listIterator();
  53.941 +        nextCand:
  53.942 +            for (int candidate = 0; candidate <= maxCandidate; candidate++) {
  53.943 +                ListIterator<?> ti = target.listIterator();
  53.944 +                for (int i=0; i<targetSize; i++) {
  53.945 +                    if (!eq(ti.next(), si.next())) {
  53.946 +                        // Back up source iterator to next candidate
  53.947 +                        for (int j=0; j<i; j++)
  53.948 +                            si.previous();
  53.949 +                        continue nextCand;
  53.950 +                    }
  53.951 +                }
  53.952 +                return candidate;
  53.953 +            }
  53.954 +        }
  53.955 +        return -1;  // No candidate matched the target
  53.956 +    }
  53.957 +
  53.958 +    /**
  53.959 +     * Returns the starting position of the last occurrence of the specified
  53.960 +     * target list within the specified source list, or -1 if there is no such
  53.961 +     * occurrence.  More formally, returns the highest index <tt>i</tt>
  53.962 +     * such that <tt>source.subList(i, i+target.size()).equals(target)</tt>,
  53.963 +     * or -1 if there is no such index.  (Returns -1 if
  53.964 +     * <tt>target.size() > source.size()</tt>.)
  53.965 +     *
  53.966 +     * <p>This implementation uses the "brute force" technique of iterating
  53.967 +     * over the source list, looking for a match with the target at each
  53.968 +     * location in turn.
  53.969 +     *
  53.970 +     * @param source the list in which to search for the last occurrence
  53.971 +     *        of <tt>target</tt>.
  53.972 +     * @param target the list to search for as a subList of <tt>source</tt>.
  53.973 +     * @return the starting position of the last occurrence of the specified
  53.974 +     *         target list within the specified source list, or -1 if there
  53.975 +     *         is no such occurrence.
  53.976 +     * @since  1.4
  53.977 +     */
  53.978 +    public static int lastIndexOfSubList(List<?> source, List<?> target) {
  53.979 +        int sourceSize = source.size();
  53.980 +        int targetSize = target.size();
  53.981 +        int maxCandidate = sourceSize - targetSize;
  53.982 +
  53.983 +        if (sourceSize < INDEXOFSUBLIST_THRESHOLD ||
  53.984 +            source instanceof RandomAccess) {   // Index access version
  53.985 +        nextCand:
  53.986 +            for (int candidate = maxCandidate; candidate >= 0; candidate--) {
  53.987 +                for (int i=0, j=candidate; i<targetSize; i++, j++)
  53.988 +                    if (!eq(target.get(i), source.get(j)))
  53.989 +                        continue nextCand;  // Element mismatch, try next cand
  53.990 +                return candidate;  // All elements of candidate matched target
  53.991 +            }
  53.992 +        } else {  // Iterator version of above algorithm
  53.993 +            if (maxCandidate < 0)
  53.994 +                return -1;
  53.995 +            ListIterator<?> si = source.listIterator(maxCandidate);
  53.996 +        nextCand:
  53.997 +            for (int candidate = maxCandidate; candidate >= 0; candidate--) {
  53.998 +                ListIterator<?> ti = target.listIterator();
  53.999 +                for (int i=0; i<targetSize; i++) {
 53.1000 +                    if (!eq(ti.next(), si.next())) {
 53.1001 +                        if (candidate != 0) {
 53.1002 +                            // Back up source iterator to next candidate
 53.1003 +                            for (int j=0; j<=i+1; j++)
 53.1004 +                                si.previous();
 53.1005 +                        }
 53.1006 +                        continue nextCand;
 53.1007 +                    }
 53.1008 +                }
 53.1009 +                return candidate;
 53.1010 +            }
 53.1011 +        }
 53.1012 +        return -1;  // No candidate matched the target
 53.1013 +    }
 53.1014 +
 53.1015 +
 53.1016 +    // Unmodifiable Wrappers
 53.1017 +
 53.1018 +    /**
 53.1019 +     * Returns an unmodifiable view of the specified collection.  This method
 53.1020 +     * allows modules to provide users with "read-only" access to internal
 53.1021 +     * collections.  Query operations on the returned collection "read through"
 53.1022 +     * to the specified collection, and attempts to modify the returned
 53.1023 +     * collection, whether direct or via its iterator, result in an
 53.1024 +     * <tt>UnsupportedOperationException</tt>.<p>
 53.1025 +     *
 53.1026 +     * The returned collection does <i>not</i> pass the hashCode and equals
 53.1027 +     * operations through to the backing collection, but relies on
 53.1028 +     * <tt>Object</tt>'s <tt>equals</tt> and <tt>hashCode</tt> methods.  This
 53.1029 +     * is necessary to preserve the contracts of these operations in the case
 53.1030 +     * that the backing collection is a set or a list.<p>
 53.1031 +     *
 53.1032 +     * The returned collection will be serializable if the specified collection
 53.1033 +     * is serializable.
 53.1034 +     *
 53.1035 +     * @param  c the collection for which an unmodifiable view is to be
 53.1036 +     *         returned.
 53.1037 +     * @return an unmodifiable view of the specified collection.
 53.1038 +     */
 53.1039 +    public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
 53.1040 +        return new UnmodifiableCollection<>(c);
 53.1041 +    }
 53.1042 +
 53.1043 +    /**
 53.1044 +     * @serial include
 53.1045 +     */
 53.1046 +    static class UnmodifiableCollection<E> implements Collection<E>, Serializable {
 53.1047 +        private static final long serialVersionUID = 1820017752578914078L;
 53.1048 +
 53.1049 +        final Collection<? extends E> c;
 53.1050 +
 53.1051 +        UnmodifiableCollection(Collection<? extends E> c) {
 53.1052 +            if (c==null)
 53.1053 +                throw new NullPointerException();
 53.1054 +            this.c = c;
 53.1055 +        }
 53.1056 +
 53.1057 +        public int size()                   {return c.size();}
 53.1058 +        public boolean isEmpty()            {return c.isEmpty();}
 53.1059 +        public boolean contains(Object o)   {return c.contains(o);}
 53.1060 +        public Object[] toArray()           {return c.toArray();}
 53.1061 +        public <T> T[] toArray(T[] a)       {return c.toArray(a);}
 53.1062 +        public String toString()            {return c.toString();}
 53.1063 +
 53.1064 +        public Iterator<E> iterator() {
 53.1065 +            return new Iterator<E>() {
 53.1066 +                private final Iterator<? extends E> i = c.iterator();
 53.1067 +
 53.1068 +                public boolean hasNext() {return i.hasNext();}
 53.1069 +                public E next()          {return i.next();}
 53.1070 +                public void remove() {
 53.1071 +                    throw new UnsupportedOperationException();
 53.1072 +                }
 53.1073 +            };
 53.1074 +        }
 53.1075 +
 53.1076 +        public boolean add(E e) {
 53.1077 +            throw new UnsupportedOperationException();
 53.1078 +        }
 53.1079 +        public boolean remove(Object o) {
 53.1080 +            throw new UnsupportedOperationException();
 53.1081 +        }
 53.1082 +
 53.1083 +        public boolean containsAll(Collection<?> coll) {
 53.1084 +            return c.containsAll(coll);
 53.1085 +        }
 53.1086 +        public boolean addAll(Collection<? extends E> coll) {
 53.1087 +            throw new UnsupportedOperationException();
 53.1088 +        }
 53.1089 +        public boolean removeAll(Collection<?> coll) {
 53.1090 +            throw new UnsupportedOperationException();
 53.1091 +        }
 53.1092 +        public boolean retainAll(Collection<?> coll) {
 53.1093 +            throw new UnsupportedOperationException();
 53.1094 +        }
 53.1095 +        public void clear() {
 53.1096 +            throw new UnsupportedOperationException();
 53.1097 +        }
 53.1098 +    }
 53.1099 +
 53.1100 +    /**
 53.1101 +     * Returns an unmodifiable view of the specified set.  This method allows
 53.1102 +     * modules to provide users with "read-only" access to internal sets.
 53.1103 +     * Query operations on the returned set "read through" to the specified
 53.1104 +     * set, and attempts to modify the returned set, whether direct or via its
 53.1105 +     * iterator, result in an <tt>UnsupportedOperationException</tt>.<p>
 53.1106 +     *
 53.1107 +     * The returned set will be serializable if the specified set
 53.1108 +     * is serializable.
 53.1109 +     *
 53.1110 +     * @param  s the set for which an unmodifiable view is to be returned.
 53.1111 +     * @return an unmodifiable view of the specified set.
 53.1112 +     */
 53.1113 +    public static <T> Set<T> unmodifiableSet(Set<? extends T> s) {
 53.1114 +        return new UnmodifiableSet<>(s);
 53.1115 +    }
 53.1116 +
 53.1117 +    /**
 53.1118 +     * @serial include
 53.1119 +     */
 53.1120 +    static class UnmodifiableSet<E> extends UnmodifiableCollection<E>
 53.1121 +                                 implements Set<E>, Serializable {
 53.1122 +        private static final long serialVersionUID = -9215047833775013803L;
 53.1123 +
 53.1124 +        UnmodifiableSet(Set<? extends E> s)     {super(s);}
 53.1125 +        public boolean equals(Object o) {return o == this || c.equals(o);}
 53.1126 +        public int hashCode()           {return c.hashCode();}
 53.1127 +    }
 53.1128 +
 53.1129 +    /**
 53.1130 +     * Returns an unmodifiable view of the specified sorted set.  This method
 53.1131 +     * allows modules to provide users with "read-only" access to internal
 53.1132 +     * sorted sets.  Query operations on the returned sorted set "read
 53.1133 +     * through" to the specified sorted set.  Attempts to modify the returned
 53.1134 +     * sorted set, whether direct, via its iterator, or via its
 53.1135 +     * <tt>subSet</tt>, <tt>headSet</tt>, or <tt>tailSet</tt> views, result in
 53.1136 +     * an <tt>UnsupportedOperationException</tt>.<p>
 53.1137 +     *
 53.1138 +     * The returned sorted set will be serializable if the specified sorted set
 53.1139 +     * is serializable.
 53.1140 +     *
 53.1141 +     * @param s the sorted set for which an unmodifiable view is to be
 53.1142 +     *        returned.
 53.1143 +     * @return an unmodifiable view of the specified sorted set.
 53.1144 +     */
 53.1145 +    public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s) {
 53.1146 +        return new UnmodifiableSortedSet<>(s);
 53.1147 +    }
 53.1148 +
 53.1149 +    /**
 53.1150 +     * @serial include
 53.1151 +     */
 53.1152 +    static class UnmodifiableSortedSet<E>
 53.1153 +                             extends UnmodifiableSet<E>
 53.1154 +                             implements SortedSet<E>, Serializable {
 53.1155 +        private static final long serialVersionUID = -4929149591599911165L;
 53.1156 +        private final SortedSet<E> ss;
 53.1157 +
 53.1158 +        UnmodifiableSortedSet(SortedSet<E> s) {super(s); ss = s;}
 53.1159 +
 53.1160 +        public Comparator<? super E> comparator() {return ss.comparator();}
 53.1161 +
 53.1162 +        public SortedSet<E> subSet(E fromElement, E toElement) {
 53.1163 +            return new UnmodifiableSortedSet<>(ss.subSet(fromElement,toElement));
 53.1164 +        }
 53.1165 +        public SortedSet<E> headSet(E toElement) {
 53.1166 +            return new UnmodifiableSortedSet<>(ss.headSet(toElement));
 53.1167 +        }
 53.1168 +        public SortedSet<E> tailSet(E fromElement) {
 53.1169 +            return new UnmodifiableSortedSet<>(ss.tailSet(fromElement));
 53.1170 +        }
 53.1171 +
 53.1172 +        public E first()                   {return ss.first();}
 53.1173 +        public E last()                    {return ss.last();}
 53.1174 +    }
 53.1175 +
 53.1176 +    /**
 53.1177 +     * Returns an unmodifiable view of the specified list.  This method allows
 53.1178 +     * modules to provide users with "read-only" access to internal
 53.1179 +     * lists.  Query operations on the returned list "read through" to the
 53.1180 +     * specified list, and attempts to modify the returned list, whether
 53.1181 +     * direct or via its iterator, result in an
 53.1182 +     * <tt>UnsupportedOperationException</tt>.<p>
 53.1183 +     *
 53.1184 +     * The returned list will be serializable if the specified list
 53.1185 +     * is serializable. Similarly, the returned list will implement
 53.1186 +     * {@link RandomAccess} if the specified list does.
 53.1187 +     *
 53.1188 +     * @param  list the list for which an unmodifiable view is to be returned.
 53.1189 +     * @return an unmodifiable view of the specified list.
 53.1190 +     */
 53.1191 +    public static <T> List<T> unmodifiableList(List<? extends T> list) {
 53.1192 +        return (list instanceof RandomAccess ?
 53.1193 +                new UnmodifiableRandomAccessList<>(list) :
 53.1194 +                new UnmodifiableList<>(list));
 53.1195 +    }
 53.1196 +
 53.1197 +    /**
 53.1198 +     * @serial include
 53.1199 +     */
 53.1200 +    static class UnmodifiableList<E> extends UnmodifiableCollection<E>
 53.1201 +                                  implements List<E> {
 53.1202 +        private static final long serialVersionUID = -283967356065247728L;
 53.1203 +        final List<? extends E> list;
 53.1204 +
 53.1205 +        UnmodifiableList(List<? extends E> list) {
 53.1206 +            super(list);
 53.1207 +            this.list = list;
 53.1208 +        }
 53.1209 +
 53.1210 +        public boolean equals(Object o) {return o == this || list.equals(o);}
 53.1211 +        public int hashCode()           {return list.hashCode();}
 53.1212 +
 53.1213 +        public E get(int index) {return list.get(index);}
 53.1214 +        public E set(int index, E element) {
 53.1215 +            throw new UnsupportedOperationException();
 53.1216 +        }
 53.1217 +        public void add(int index, E element) {
 53.1218 +            throw new UnsupportedOperationException();
 53.1219 +        }
 53.1220 +        public E remove(int index) {
 53.1221 +            throw new UnsupportedOperationException();
 53.1222 +        }
 53.1223 +        public int indexOf(Object o)            {return list.indexOf(o);}
 53.1224 +        public int lastIndexOf(Object o)        {return list.lastIndexOf(o);}
 53.1225 +        public boolean addAll(int index, Collection<? extends E> c) {
 53.1226 +            throw new UnsupportedOperationException();
 53.1227 +        }
 53.1228 +        public ListIterator<E> listIterator()   {return listIterator(0);}
 53.1229 +
 53.1230 +        public ListIterator<E> listIterator(final int index) {
 53.1231 +            return new ListIterator<E>() {
 53.1232 +                private final ListIterator<? extends E> i
 53.1233 +                    = list.listIterator(index);
 53.1234 +
 53.1235 +                public boolean hasNext()     {return i.hasNext();}
 53.1236 +                public E next()              {return i.next();}
 53.1237 +                public boolean hasPrevious() {return i.hasPrevious();}
 53.1238 +                public E previous()          {return i.previous();}
 53.1239 +                public int nextIndex()       {return i.nextIndex();}
 53.1240 +                public int previousIndex()   {return i.previousIndex();}
 53.1241 +
 53.1242 +                public void remove() {
 53.1243 +                    throw new UnsupportedOperationException();
 53.1244 +                }
 53.1245 +                public void set(E e) {
 53.1246 +                    throw new UnsupportedOperationException();
 53.1247 +                }
 53.1248 +                public void add(E e) {
 53.1249 +                    throw new UnsupportedOperationException();
 53.1250 +                }
 53.1251 +            };
 53.1252 +        }
 53.1253 +
 53.1254 +        public List<E> subList(int fromIndex, int toIndex) {
 53.1255 +            return new UnmodifiableList<>(list.subList(fromIndex, toIndex));
 53.1256 +        }
 53.1257 +
 53.1258 +        /**
 53.1259 +         * UnmodifiableRandomAccessList instances are serialized as
 53.1260 +         * UnmodifiableList instances to allow them to be deserialized
 53.1261 +         * in pre-1.4 JREs (which do not have UnmodifiableRandomAccessList).
 53.1262 +         * This method inverts the transformation.  As a beneficial
 53.1263 +         * side-effect, it also grafts the RandomAccess marker onto
 53.1264 +         * UnmodifiableList instances that were serialized in pre-1.4 JREs.
 53.1265 +         *
 53.1266 +         * Note: Unfortunately, UnmodifiableRandomAccessList instances
 53.1267 +         * serialized in 1.4.1 and deserialized in 1.4 will become
 53.1268 +         * UnmodifiableList instances, as this method was missing in 1.4.
 53.1269 +         */
 53.1270 +        private Object readResolve() {
 53.1271 +            return (list instanceof RandomAccess
 53.1272 +                    ? new UnmodifiableRandomAccessList<>(list)
 53.1273 +                    : this);
 53.1274 +        }
 53.1275 +    }
 53.1276 +
 53.1277 +    /**
 53.1278 +     * @serial include
 53.1279 +     */
 53.1280 +    static class UnmodifiableRandomAccessList<E> extends UnmodifiableList<E>
 53.1281 +                                              implements RandomAccess
 53.1282 +    {
 53.1283 +        UnmodifiableRandomAccessList(List<? extends E> list) {
 53.1284 +            super(list);
 53.1285 +        }
 53.1286 +
 53.1287 +        public List<E> subList(int fromIndex, int toIndex) {
 53.1288 +            return new UnmodifiableRandomAccessList<>(
 53.1289 +                list.subList(fromIndex, toIndex));
 53.1290 +        }
 53.1291 +
 53.1292 +        private static final long serialVersionUID = -2542308836966382001L;
 53.1293 +
 53.1294 +        /**
 53.1295 +         * Allows instances to be deserialized in pre-1.4 JREs (which do
 53.1296 +         * not have UnmodifiableRandomAccessList).  UnmodifiableList has
 53.1297 +         * a readResolve method that inverts this transformation upon
 53.1298 +         * deserialization.
 53.1299 +         */
 53.1300 +        private Object writeReplace() {
 53.1301 +            return new UnmodifiableList<>(list);
 53.1302 +        }
 53.1303 +    }
 53.1304 +
 53.1305 +    /**
 53.1306 +     * Returns an unmodifiable view of the specified map.  This method
 53.1307 +     * allows modules to provide users with "read-only" access to internal
 53.1308 +     * maps.  Query operations on the returned map "read through"
 53.1309 +     * to the specified map, and attempts to modify the returned
 53.1310 +     * map, whether direct or via its collection views, result in an
 53.1311 +     * <tt>UnsupportedOperationException</tt>.<p>
 53.1312 +     *
 53.1313 +     * The returned map will be serializable if the specified map
 53.1314 +     * is serializable.
 53.1315 +     *
 53.1316 +     * @param  m the map for which an unmodifiable view is to be returned.
 53.1317 +     * @return an unmodifiable view of the specified map.
 53.1318 +     */
 53.1319 +    public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m) {
 53.1320 +        return new UnmodifiableMap<>(m);
 53.1321 +    }
 53.1322 +
 53.1323 +    /**
 53.1324 +     * @serial include
 53.1325 +     */
 53.1326 +    private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable {
 53.1327 +        private static final long serialVersionUID = -1034234728574286014L;
 53.1328 +
 53.1329 +        private final Map<? extends K, ? extends V> m;
 53.1330 +
 53.1331 +        UnmodifiableMap(Map<? extends K, ? extends V> m) {
 53.1332 +            if (m==null)
 53.1333 +                throw new NullPointerException();
 53.1334 +            this.m = m;
 53.1335 +        }
 53.1336 +
 53.1337 +        public int size()                        {return m.size();}
 53.1338 +        public boolean isEmpty()                 {return m.isEmpty();}
 53.1339 +        public boolean containsKey(Object key)   {return m.containsKey(key);}
 53.1340 +        public boolean containsValue(Object val) {return m.containsValue(val);}
 53.1341 +        public V get(Object key)                 {return m.get(key);}
 53.1342 +
 53.1343 +        public V put(K key, V value) {
 53.1344 +            throw new UnsupportedOperationException();
 53.1345 +        }
 53.1346 +        public V remove(Object key) {
 53.1347 +            throw new UnsupportedOperationException();
 53.1348 +        }
 53.1349 +        public void putAll(Map<? extends K, ? extends V> m) {
 53.1350 +            throw new UnsupportedOperationException();
 53.1351 +        }
 53.1352 +        public void clear() {
 53.1353 +            throw new UnsupportedOperationException();
 53.1354 +        }
 53.1355 +
 53.1356 +        private transient Set<K> keySet = null;
 53.1357 +        private transient Set<Map.Entry<K,V>> entrySet = null;
 53.1358 +        private transient Collection<V> values = null;
 53.1359 +
 53.1360 +        public Set<K> keySet() {
 53.1361 +            if (keySet==null)
 53.1362 +                keySet = unmodifiableSet(m.keySet());
 53.1363 +            return keySet;
 53.1364 +        }
 53.1365 +
 53.1366 +        public Set<Map.Entry<K,V>> entrySet() {
 53.1367 +            if (entrySet==null)
 53.1368 +                entrySet = new UnmodifiableEntrySet<>(m.entrySet());
 53.1369 +            return entrySet;
 53.1370 +        }
 53.1371 +
 53.1372 +        public Collection<V> values() {
 53.1373 +            if (values==null)
 53.1374 +                values = unmodifiableCollection(m.values());
 53.1375 +            return values;
 53.1376 +        }
 53.1377 +
 53.1378 +        public boolean equals(Object o) {return o == this || m.equals(o);}
 53.1379 +        public int hashCode()           {return m.hashCode();}
 53.1380 +        public String toString()        {return m.toString();}
 53.1381 +
 53.1382 +        /**
 53.1383 +         * We need this class in addition to UnmodifiableSet as
 53.1384 +         * Map.Entries themselves permit modification of the backing Map
 53.1385 +         * via their setValue operation.  This class is subtle: there are
 53.1386 +         * many possible attacks that must be thwarted.
 53.1387 +         *
 53.1388 +         * @serial include
 53.1389 +         */
 53.1390 +        static class UnmodifiableEntrySet<K,V>
 53.1391 +            extends UnmodifiableSet<Map.Entry<K,V>> {
 53.1392 +            private static final long serialVersionUID = 7854390611657943733L;
 53.1393 +
 53.1394 +            UnmodifiableEntrySet(Set<? extends Map.Entry<? extends K, ? extends V>> s) {
 53.1395 +                super((Set)s);
 53.1396 +            }
 53.1397 +            public Iterator<Map.Entry<K,V>> iterator() {
 53.1398 +                return new Iterator<Map.Entry<K,V>>() {
 53.1399 +                    private final Iterator<? extends Map.Entry<? extends K, ? extends V>> i = c.iterator();
 53.1400 +
 53.1401 +                    public boolean hasNext() {
 53.1402 +                        return i.hasNext();
 53.1403 +                    }
 53.1404 +                    public Map.Entry<K,V> next() {
 53.1405 +                        return new UnmodifiableEntry<>(i.next());
 53.1406 +                    }
 53.1407 +                    public void remove() {
 53.1408 +                        throw new UnsupportedOperationException();
 53.1409 +                    }
 53.1410 +                };
 53.1411 +            }
 53.1412 +
 53.1413 +            public Object[] toArray() {
 53.1414 +                Object[] a = c.toArray();
 53.1415 +                for (int i=0; i<a.length; i++)
 53.1416 +                    a[i] = new UnmodifiableEntry<>((Map.Entry<K,V>)a[i]);
 53.1417 +                return a;
 53.1418 +            }
 53.1419 +
 53.1420 +            public <T> T[] toArray(T[] a) {
 53.1421 +                // We don't pass a to c.toArray, to avoid window of
 53.1422 +                // vulnerability wherein an unscrupulous multithreaded client
 53.1423 +                // could get his hands on raw (unwrapped) Entries from c.
 53.1424 +                Object[] arr = c.toArray(a.length==0 ? a : Arrays.copyOf(a, 0));
 53.1425 +
 53.1426 +                for (int i=0; i<arr.length; i++)
 53.1427 +                    arr[i] = new UnmodifiableEntry<>((Map.Entry<K,V>)arr[i]);
 53.1428 +
 53.1429 +                if (arr.length > a.length)
 53.1430 +                    return (T[])arr;
 53.1431 +
 53.1432 +                System.arraycopy(arr, 0, a, 0, arr.length);
 53.1433 +                if (a.length > arr.length)
 53.1434 +                    a[arr.length] = null;
 53.1435 +                return a;
 53.1436 +            }
 53.1437 +
 53.1438 +            /**
 53.1439 +             * This method is overridden to protect the backing set against
 53.1440 +             * an object with a nefarious equals function that senses
 53.1441 +             * that the equality-candidate is Map.Entry and calls its
 53.1442 +             * setValue method.
 53.1443 +             */
 53.1444 +            public boolean contains(Object o) {
 53.1445 +                if (!(o instanceof Map.Entry))
 53.1446 +                    return false;
 53.1447 +                return c.contains(
 53.1448 +                    new UnmodifiableEntry<>((Map.Entry<?,?>) o));
 53.1449 +            }
 53.1450 +
 53.1451 +            /**
 53.1452 +             * The next two methods are overridden to protect against
 53.1453 +             * an unscrupulous List whose contains(Object o) method senses
 53.1454 +             * when o is a Map.Entry, and calls o.setValue.
 53.1455 +             */
 53.1456 +            public boolean containsAll(Collection<?> coll) {
 53.1457 +                for (Object e : coll) {
 53.1458 +                    if (!contains(e)) // Invokes safe contains() above
 53.1459 +                        return false;
 53.1460 +                }
 53.1461 +                return true;
 53.1462 +            }
 53.1463 +            public boolean equals(Object o) {
 53.1464 +                if (o == this)
 53.1465 +                    return true;
 53.1466 +
 53.1467 +                if (!(o instanceof Set))
 53.1468 +                    return false;
 53.1469 +                Set s = (Set) o;
 53.1470 +                if (s.size() != c.size())
 53.1471 +                    return false;
 53.1472 +                return containsAll(s); // Invokes safe containsAll() above
 53.1473 +            }
 53.1474 +
 53.1475 +            /**
 53.1476 +             * This "wrapper class" serves two purposes: it prevents
 53.1477 +             * the client from modifying the backing Map, by short-circuiting
 53.1478 +             * the setValue method, and it protects the backing Map against
 53.1479 +             * an ill-behaved Map.Entry that attempts to modify another
 53.1480 +             * Map Entry when asked to perform an equality check.
 53.1481 +             */
 53.1482 +            private static class UnmodifiableEntry<K,V> implements Map.Entry<K,V> {
 53.1483 +                private Map.Entry<? extends K, ? extends V> e;
 53.1484 +
 53.1485 +                UnmodifiableEntry(Map.Entry<? extends K, ? extends V> e) {this.e = e;}
 53.1486 +
 53.1487 +                public K getKey()        {return e.getKey();}
 53.1488 +                public V getValue()      {return e.getValue();}
 53.1489 +                public V setValue(V value) {
 53.1490 +                    throw new UnsupportedOperationException();
 53.1491 +                }
 53.1492 +                public int hashCode()    {return e.hashCode();}
 53.1493 +                public boolean equals(Object o) {
 53.1494 +                    if (!(o instanceof Map.Entry))
 53.1495 +                        return false;
 53.1496 +                    Map.Entry t = (Map.Entry)o;
 53.1497 +                    return eq(e.getKey(),   t.getKey()) &&
 53.1498 +                           eq(e.getValue(), t.getValue());
 53.1499 +                }
 53.1500 +                public String toString() {return e.toString();}
 53.1501 +            }
 53.1502 +        }
 53.1503 +    }
 53.1504 +
 53.1505 +    /**
 53.1506 +     * Returns an unmodifiable view of the specified sorted map.  This method
 53.1507 +     * allows modules to provide users with "read-only" access to internal
 53.1508 +     * sorted maps.  Query operations on the returned sorted map "read through"
 53.1509 +     * to the specified sorted map.  Attempts to modify the returned
 53.1510 +     * sorted map, whether direct, via its collection views, or via its
 53.1511 +     * <tt>subMap</tt>, <tt>headMap</tt>, or <tt>tailMap</tt> views, result in
 53.1512 +     * an <tt>UnsupportedOperationException</tt>.<p>
 53.1513 +     *
 53.1514 +     * The returned sorted map will be serializable if the specified sorted map
 53.1515 +     * is serializable.
 53.1516 +     *
 53.1517 +     * @param m the sorted map for which an unmodifiable view is to be
 53.1518 +     *        returned.
 53.1519 +     * @return an unmodifiable view of the specified sorted map.
 53.1520 +     */
 53.1521 +    public static <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K, ? extends V> m) {
 53.1522 +        return new UnmodifiableSortedMap<>(m);
 53.1523 +    }
 53.1524 +
 53.1525 +    /**
 53.1526 +     * @serial include
 53.1527 +     */
 53.1528 +    static class UnmodifiableSortedMap<K,V>
 53.1529 +          extends UnmodifiableMap<K,V>
 53.1530 +          implements SortedMap<K,V>, Serializable {
 53.1531 +        private static final long serialVersionUID = -8806743815996713206L;
 53.1532 +
 53.1533 +        private final SortedMap<K, ? extends V> sm;
 53.1534 +
 53.1535 +        UnmodifiableSortedMap(SortedMap<K, ? extends V> m) {super(m); sm = m;}
 53.1536 +
 53.1537 +        public Comparator<? super K> comparator() {return sm.comparator();}
 53.1538 +
 53.1539 +        public SortedMap<K,V> subMap(K fromKey, K toKey) {
 53.1540 +            return new UnmodifiableSortedMap<>(sm.subMap(fromKey, toKey));
 53.1541 +        }
 53.1542 +        public SortedMap<K,V> headMap(K toKey) {
 53.1543 +            return new UnmodifiableSortedMap<>(sm.headMap(toKey));
 53.1544 +        }
 53.1545 +        public SortedMap<K,V> tailMap(K fromKey) {
 53.1546 +            return new UnmodifiableSortedMap<>(sm.tailMap(fromKey));
 53.1547 +        }
 53.1548 +
 53.1549 +        public K firstKey()           {return sm.firstKey();}
 53.1550 +        public K lastKey()            {return sm.lastKey();}
 53.1551 +    }
 53.1552 +
 53.1553 +
 53.1554 +    // Synch Wrappers
 53.1555 +
 53.1556 +    /**
 53.1557 +     * Returns a synchronized (thread-safe) collection backed by the specified
 53.1558 +     * collection.  In order to guarantee serial access, it is critical that
 53.1559 +     * <strong>all</strong> access to the backing collection is accomplished
 53.1560 +     * through the returned collection.<p>
 53.1561 +     *
 53.1562 +     * It is imperative that the user manually synchronize on the returned
 53.1563 +     * collection when iterating over it:
 53.1564 +     * <pre>
 53.1565 +     *  Collection c = Collections.synchronizedCollection(myCollection);
 53.1566 +     *     ...
 53.1567 +     *  synchronized (c) {
 53.1568 +     *      Iterator i = c.iterator(); // Must be in the synchronized block
 53.1569 +     *      while (i.hasNext())
 53.1570 +     *         foo(i.next());
 53.1571 +     *  }
 53.1572 +     * </pre>
 53.1573 +     * Failure to follow this advice may result in non-deterministic behavior.
 53.1574 +     *
 53.1575 +     * <p>The returned collection does <i>not</i> pass the <tt>hashCode</tt>
 53.1576 +     * and <tt>equals</tt> operations through to the backing collection, but
 53.1577 +     * relies on <tt>Object</tt>'s equals and hashCode methods.  This is
 53.1578 +     * necessary to preserve the contracts of these operations in the case
 53.1579 +     * that the backing collection is a set or a list.<p>
 53.1580 +     *
 53.1581 +     * The returned collection will be serializable if the specified collection
 53.1582 +     * is serializable.
 53.1583 +     *
 53.1584 +     * @param  c the collection to be "wrapped" in a synchronized collection.
 53.1585 +     * @return a synchronized view of the specified collection.
 53.1586 +     */
 53.1587 +    public static <T> Collection<T> synchronizedCollection(Collection<T> c) {
 53.1588 +        return new SynchronizedCollection<>(c);
 53.1589 +    }
 53.1590 +
 53.1591 +    static <T> Collection<T> synchronizedCollection(Collection<T> c, Object mutex) {
 53.1592 +        return new SynchronizedCollection<>(c, mutex);
 53.1593 +    }
 53.1594 +
 53.1595 +    /**
 53.1596 +     * @serial include
 53.1597 +     */
 53.1598 +    static class SynchronizedCollection<E> implements Collection<E>, Serializable {
 53.1599 +        private static final long serialVersionUID = 3053995032091335093L;
 53.1600 +
 53.1601 +        final Collection<E> c;  // Backing Collection
 53.1602 +        final Object mutex;     // Object on which to synchronize
 53.1603 +
 53.1604 +        SynchronizedCollection(Collection<E> c) {
 53.1605 +            if (c==null)
 53.1606 +                throw new NullPointerException();
 53.1607 +            this.c = c;
 53.1608 +            mutex = this;
 53.1609 +        }
 53.1610 +        SynchronizedCollection(Collection<E> c, Object mutex) {
 53.1611 +            this.c = c;
 53.1612 +            this.mutex = mutex;
 53.1613 +        }
 53.1614 +
 53.1615 +        public int size() {
 53.1616 +            synchronized (mutex) {return c.size();}
 53.1617 +        }
 53.1618 +        public boolean isEmpty() {
 53.1619 +            synchronized (mutex) {return c.isEmpty();}
 53.1620 +        }
 53.1621 +        public boolean contains(Object o) {
 53.1622 +            synchronized (mutex) {return c.contains(o);}
 53.1623 +        }
 53.1624 +        public Object[] toArray() {
 53.1625 +            synchronized (mutex) {return c.toArray();}
 53.1626 +        }
 53.1627 +        public <T> T[] toArray(T[] a) {
 53.1628 +            synchronized (mutex) {return c.toArray(a);}
 53.1629 +        }
 53.1630 +
 53.1631 +        public Iterator<E> iterator() {
 53.1632 +            return c.iterator(); // Must be manually synched by user!
 53.1633 +        }
 53.1634 +
 53.1635 +        public boolean add(E e) {
 53.1636 +            synchronized (mutex) {return c.add(e);}
 53.1637 +        }
 53.1638 +        public boolean remove(Object o) {
 53.1639 +            synchronized (mutex) {return c.remove(o);}
 53.1640 +        }
 53.1641 +
 53.1642 +        public boolean containsAll(Collection<?> coll) {
 53.1643 +            synchronized (mutex) {return c.containsAll(coll);}
 53.1644 +        }
 53.1645 +        public boolean addAll(Collection<? extends E> coll) {
 53.1646 +            synchronized (mutex) {return c.addAll(coll);}
 53.1647 +        }
 53.1648 +        public boolean removeAll(Collection<?> coll) {
 53.1649 +            synchronized (mutex) {return c.removeAll(coll);}
 53.1650 +        }
 53.1651 +        public boolean retainAll(Collection<?> coll) {
 53.1652 +            synchronized (mutex) {return c.retainAll(coll);}
 53.1653 +        }
 53.1654 +        public void clear() {
 53.1655 +            synchronized (mutex) {c.clear();}
 53.1656 +        }
 53.1657 +        public String toString() {
 53.1658 +            synchronized (mutex) {return c.toString();}
 53.1659 +        }
 53.1660 +    }
 53.1661 +
 53.1662 +    /**
 53.1663 +     * Returns a synchronized (thread-safe) set backed by the specified
 53.1664 +     * set.  In order to guarantee serial access, it is critical that
 53.1665 +     * <strong>all</strong> access to the backing set is accomplished
 53.1666 +     * through the returned set.<p>
 53.1667 +     *
 53.1668 +     * It is imperative that the user manually synchronize on the returned
 53.1669 +     * set when iterating over it:
 53.1670 +     * <pre>
 53.1671 +     *  Set s = Collections.synchronizedSet(new HashSet());
 53.1672 +     *      ...
 53.1673 +     *  synchronized (s) {
 53.1674 +     *      Iterator i = s.iterator(); // Must be in the synchronized block
 53.1675 +     *      while (i.hasNext())
 53.1676 +     *          foo(i.next());
 53.1677 +     *  }
 53.1678 +     * </pre>
 53.1679 +     * Failure to follow this advice may result in non-deterministic behavior.
 53.1680 +     *
 53.1681 +     * <p>The returned set will be serializable if the specified set is
 53.1682 +     * serializable.
 53.1683 +     *
 53.1684 +     * @param  s the set to be "wrapped" in a synchronized set.
 53.1685 +     * @return a synchronized view of the specified set.
 53.1686 +     */
 53.1687 +    public static <T> Set<T> synchronizedSet(Set<T> s) {
 53.1688 +        return new SynchronizedSet<>(s);
 53.1689 +    }
 53.1690 +
 53.1691 +    static <T> Set<T> synchronizedSet(Set<T> s, Object mutex) {
 53.1692 +        return new SynchronizedSet<>(s, mutex);
 53.1693 +    }
 53.1694 +
 53.1695 +    /**
 53.1696 +     * @serial include
 53.1697 +     */
 53.1698 +    static class SynchronizedSet<E>
 53.1699 +          extends SynchronizedCollection<E>
 53.1700 +          implements Set<E> {
 53.1701 +        private static final long serialVersionUID = 487447009682186044L;
 53.1702 +
 53.1703 +        SynchronizedSet(Set<E> s) {
 53.1704 +            super(s);
 53.1705 +        }
 53.1706 +        SynchronizedSet(Set<E> s, Object mutex) {
 53.1707 +            super(s, mutex);
 53.1708 +        }
 53.1709 +
 53.1710 +        public boolean equals(Object o) {
 53.1711 +            synchronized (mutex) {return c.equals(o);}
 53.1712 +        }
 53.1713 +        public int hashCode() {
 53.1714 +            synchronized (mutex) {return c.hashCode();}
 53.1715 +        }
 53.1716 +    }
 53.1717 +
 53.1718 +    /**
 53.1719 +     * Returns a synchronized (thread-safe) sorted set backed by the specified
 53.1720 +     * sorted set.  In order to guarantee serial access, it is critical that
 53.1721 +     * <strong>all</strong> access to the backing sorted set is accomplished
 53.1722 +     * through the returned sorted set (or its views).<p>
 53.1723 +     *
 53.1724 +     * It is imperative that the user manually synchronize on the returned
 53.1725 +     * sorted set when iterating over it or any of its <tt>subSet</tt>,
 53.1726 +     * <tt>headSet</tt>, or <tt>tailSet</tt> views.
 53.1727 +     * <pre>
 53.1728 +     *  SortedSet s = Collections.synchronizedSortedSet(new TreeSet());
 53.1729 +     *      ...
 53.1730 +     *  synchronized (s) {
 53.1731 +     *      Iterator i = s.iterator(); // Must be in the synchronized block
 53.1732 +     *      while (i.hasNext())
 53.1733 +     *          foo(i.next());
 53.1734 +     *  }
 53.1735 +     * </pre>
 53.1736 +     * or:
 53.1737 +     * <pre>
 53.1738 +     *  SortedSet s = Collections.synchronizedSortedSet(new TreeSet());
 53.1739 +     *  SortedSet s2 = s.headSet(foo);
 53.1740 +     *      ...
 53.1741 +     *  synchronized (s) {  // Note: s, not s2!!!
 53.1742 +     *      Iterator i = s2.iterator(); // Must be in the synchronized block
 53.1743 +     *      while (i.hasNext())
 53.1744 +     *          foo(i.next());
 53.1745 +     *  }
 53.1746 +     * </pre>
 53.1747 +     * Failure to follow this advice may result in non-deterministic behavior.
 53.1748 +     *
 53.1749 +     * <p>The returned sorted set will be serializable if the specified
 53.1750 +     * sorted set is serializable.
 53.1751 +     *
 53.1752 +     * @param  s the sorted set to be "wrapped" in a synchronized sorted set.
 53.1753 +     * @return a synchronized view of the specified sorted set.
 53.1754 +     */
 53.1755 +    public static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s) {
 53.1756 +        return new SynchronizedSortedSet<>(s);
 53.1757 +    }
 53.1758 +
 53.1759 +    /**
 53.1760 +     * @serial include
 53.1761 +     */
 53.1762 +    static class SynchronizedSortedSet<E>
 53.1763 +        extends SynchronizedSet<E>
 53.1764 +        implements SortedSet<E>
 53.1765 +    {
 53.1766 +        private static final long serialVersionUID = 8695801310862127406L;
 53.1767 +
 53.1768 +        private final SortedSet<E> ss;
 53.1769 +
 53.1770 +        SynchronizedSortedSet(SortedSet<E> s) {
 53.1771 +            super(s);
 53.1772 +            ss = s;
 53.1773 +        }
 53.1774 +        SynchronizedSortedSet(SortedSet<E> s, Object mutex) {
 53.1775 +            super(s, mutex);
 53.1776 +            ss = s;
 53.1777 +        }
 53.1778 +
 53.1779 +        public Comparator<? super E> comparator() {
 53.1780 +            synchronized (mutex) {return ss.comparator();}
 53.1781 +        }
 53.1782 +
 53.1783 +        public SortedSet<E> subSet(E fromElement, E toElement) {
 53.1784 +            synchronized (mutex) {
 53.1785 +                return new SynchronizedSortedSet<>(
 53.1786 +                    ss.subSet(fromElement, toElement), mutex);
 53.1787 +            }
 53.1788 +        }
 53.1789 +        public SortedSet<E> headSet(E toElement) {
 53.1790 +            synchronized (mutex) {
 53.1791 +                return new SynchronizedSortedSet<>(ss.headSet(toElement), mutex);
 53.1792 +            }
 53.1793 +        }
 53.1794 +        public SortedSet<E> tailSet(E fromElement) {
 53.1795 +            synchronized (mutex) {
 53.1796 +               return new SynchronizedSortedSet<>(ss.tailSet(fromElement),mutex);
 53.1797 +            }
 53.1798 +        }
 53.1799 +
 53.1800 +        public E first() {
 53.1801 +            synchronized (mutex) {return ss.first();}
 53.1802 +        }
 53.1803 +        public E last() {
 53.1804 +            synchronized (mutex) {return ss.last();}
 53.1805 +        }
 53.1806 +    }
 53.1807 +
 53.1808 +    /**
 53.1809 +     * Returns a synchronized (thread-safe) list backed by the specified
 53.1810 +     * list.  In order to guarantee serial access, it is critical that
 53.1811 +     * <strong>all</strong> access to the backing list is accomplished
 53.1812 +     * through the returned list.<p>
 53.1813 +     *
 53.1814 +     * It is imperative that the user manually synchronize on the returned
 53.1815 +     * list when iterating over it:
 53.1816 +     * <pre>
 53.1817 +     *  List list = Collections.synchronizedList(new ArrayList());
 53.1818 +     *      ...
 53.1819 +     *  synchronized (list) {
 53.1820 +     *      Iterator i = list.iterator(); // Must be in synchronized block
 53.1821 +     *      while (i.hasNext())
 53.1822 +     *          foo(i.next());
 53.1823 +     *  }
 53.1824 +     * </pre>
 53.1825 +     * Failure to follow this advice may result in non-deterministic behavior.
 53.1826 +     *
 53.1827 +     * <p>The returned list will be serializable if the specified list is
 53.1828 +     * serializable.
 53.1829 +     *
 53.1830 +     * @param  list the list to be "wrapped" in a synchronized list.
 53.1831 +     * @return a synchronized view of the specified list.
 53.1832 +     */
 53.1833 +    public static <T> List<T> synchronizedList(List<T> list) {
 53.1834 +        return (list instanceof RandomAccess ?
 53.1835 +                new SynchronizedRandomAccessList<>(list) :
 53.1836 +                new SynchronizedList<>(list));
 53.1837 +    }
 53.1838 +
 53.1839 +    static <T> List<T> synchronizedList(List<T> list, Object mutex) {
 53.1840 +        return (list instanceof RandomAccess ?
 53.1841 +                new SynchronizedRandomAccessList<>(list, mutex) :
 53.1842 +                new SynchronizedList<>(list, mutex));
 53.1843 +    }
 53.1844 +
 53.1845 +    /**
 53.1846 +     * @serial include
 53.1847 +     */
 53.1848 +    static class SynchronizedList<E>
 53.1849 +        extends SynchronizedCollection<E>
 53.1850 +        implements List<E> {
 53.1851 +        private static final long serialVersionUID = -7754090372962971524L;
 53.1852 +
 53.1853 +        final List<E> list;
 53.1854 +
 53.1855 +        SynchronizedList(List<E> list) {
 53.1856 +            super(list);
 53.1857 +            this.list = list;
 53.1858 +        }
 53.1859 +        SynchronizedList(List<E> list, Object mutex) {
 53.1860 +            super(list, mutex);
 53.1861 +            this.list = list;
 53.1862 +        }
 53.1863 +
 53.1864 +        public boolean equals(Object o) {
 53.1865 +            synchronized (mutex) {return list.equals(o);}
 53.1866 +        }
 53.1867 +        public int hashCode() {
 53.1868 +            synchronized (mutex) {return list.hashCode();}
 53.1869 +        }
 53.1870 +
 53.1871 +        public E get(int index) {
 53.1872 +            synchronized (mutex) {return list.get(index);}
 53.1873 +        }
 53.1874 +        public E set(int index, E element) {
 53.1875 +            synchronized (mutex) {return list.set(index, element);}
 53.1876 +        }
 53.1877 +        public void add(int index, E element) {
 53.1878 +            synchronized (mutex) {list.add(index, element);}
 53.1879 +        }
 53.1880 +        public E remove(int index) {
 53.1881 +            synchronized (mutex) {return list.remove(index);}
 53.1882 +        }
 53.1883 +
 53.1884 +        public int indexOf(Object o) {
 53.1885 +            synchronized (mutex) {return list.indexOf(o);}
 53.1886 +        }
 53.1887 +        public int lastIndexOf(Object o) {
 53.1888 +            synchronized (mutex) {return list.lastIndexOf(o);}
 53.1889 +        }
 53.1890 +
 53.1891 +        public boolean addAll(int index, Collection<? extends E> c) {
 53.1892 +            synchronized (mutex) {return list.addAll(index, c);}
 53.1893 +        }
 53.1894 +
 53.1895 +        public ListIterator<E> listIterator() {
 53.1896 +            return list.listIterator(); // Must be manually synched by user
 53.1897 +        }
 53.1898 +
 53.1899 +        public ListIterator<E> listIterator(int index) {
 53.1900 +            return list.listIterator(index); // Must be manually synched by user
 53.1901 +        }
 53.1902 +
 53.1903 +        public List<E> subList(int fromIndex, int toIndex) {
 53.1904 +            synchronized (mutex) {
 53.1905 +                return new SynchronizedList<>(list.subList(fromIndex, toIndex),
 53.1906 +                                            mutex);
 53.1907 +            }
 53.1908 +        }
 53.1909 +
 53.1910 +        /**
 53.1911 +         * SynchronizedRandomAccessList instances are serialized as
 53.1912 +         * SynchronizedList instances to allow them to be deserialized
 53.1913 +         * in pre-1.4 JREs (which do not have SynchronizedRandomAccessList).
 53.1914 +         * This method inverts the transformation.  As a beneficial
 53.1915 +         * side-effect, it also grafts the RandomAccess marker onto
 53.1916 +         * SynchronizedList instances that were serialized in pre-1.4 JREs.
 53.1917 +         *
 53.1918 +         * Note: Unfortunately, SynchronizedRandomAccessList instances
 53.1919 +         * serialized in 1.4.1 and deserialized in 1.4 will become
 53.1920 +         * SynchronizedList instances, as this method was missing in 1.4.
 53.1921 +         */
 53.1922 +        private Object readResolve() {
 53.1923 +            return (list instanceof RandomAccess
 53.1924 +                    ? new SynchronizedRandomAccessList<>(list)
 53.1925 +                    : this);
 53.1926 +        }
 53.1927 +    }
 53.1928 +
 53.1929 +    /**
 53.1930 +     * @serial include
 53.1931 +     */
 53.1932 +    static class SynchronizedRandomAccessList<E>
 53.1933 +        extends SynchronizedList<E>
 53.1934 +        implements RandomAccess {
 53.1935 +
 53.1936 +        SynchronizedRandomAccessList(List<E> list) {
 53.1937 +            super(list);
 53.1938 +        }
 53.1939 +
 53.1940 +        SynchronizedRandomAccessList(List<E> list, Object mutex) {
 53.1941 +            super(list, mutex);
 53.1942 +        }
 53.1943 +
 53.1944 +        public List<E> subList(int fromIndex, int toIndex) {
 53.1945 +            synchronized (mutex) {
 53.1946 +                return new SynchronizedRandomAccessList<>(
 53.1947 +                    list.subList(fromIndex, toIndex), mutex);
 53.1948 +            }
 53.1949 +        }
 53.1950 +
 53.1951 +        private static final long serialVersionUID = 1530674583602358482L;
 53.1952 +
 53.1953 +        /**
 53.1954 +         * Allows instances to be deserialized in pre-1.4 JREs (which do
 53.1955 +         * not have SynchronizedRandomAccessList).  SynchronizedList has
 53.1956 +         * a readResolve method that inverts this transformation upon
 53.1957 +         * deserialization.
 53.1958 +         */
 53.1959 +        private Object writeReplace() {
 53.1960 +            return new SynchronizedList<>(list);
 53.1961 +        }
 53.1962 +    }
 53.1963 +
 53.1964 +    /**
 53.1965 +     * Returns a synchronized (thread-safe) map backed by the specified
 53.1966 +     * map.  In order to guarantee serial access, it is critical that
 53.1967 +     * <strong>all</strong> access to the backing map is accomplished
 53.1968 +     * through the returned map.<p>
 53.1969 +     *
 53.1970 +     * It is imperative that the user manually synchronize on the returned
 53.1971 +     * map when iterating over any of its collection views:
 53.1972 +     * <pre>
 53.1973 +     *  Map m = Collections.synchronizedMap(new HashMap());
 53.1974 +     *      ...
 53.1975 +     *  Set s = m.keySet();  // Needn't be in synchronized block
 53.1976 +     *      ...
 53.1977 +     *  synchronized (m) {  // Synchronizing on m, not s!
 53.1978 +     *      Iterator i = s.iterator(); // Must be in synchronized block
 53.1979 +     *      while (i.hasNext())
 53.1980 +     *          foo(i.next());
 53.1981 +     *  }
 53.1982 +     * </pre>
 53.1983 +     * Failure to follow this advice may result in non-deterministic behavior.
 53.1984 +     *
 53.1985 +     * <p>The returned map will be serializable if the specified map is
 53.1986 +     * serializable.
 53.1987 +     *
 53.1988 +     * @param  m the map to be "wrapped" in a synchronized map.
 53.1989 +     * @return a synchronized view of the specified map.
 53.1990 +     */
 53.1991 +    public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
 53.1992 +        return new SynchronizedMap<>(m);
 53.1993 +    }
 53.1994 +
 53.1995 +    /**
 53.1996 +     * @serial include
 53.1997 +     */
 53.1998 +    private static class SynchronizedMap<K,V>
 53.1999 +        implements Map<K,V>, Serializable {
 53.2000 +        private static final long serialVersionUID = 1978198479659022715L;
 53.2001 +
 53.2002 +        private final Map<K,V> m;     // Backing Map
 53.2003 +        final Object      mutex;        // Object on which to synchronize
 53.2004 +
 53.2005 +        SynchronizedMap(Map<K,V> m) {
 53.2006 +            if (m==null)
 53.2007 +                throw new NullPointerException();
 53.2008 +            this.m = m;
 53.2009 +            mutex = this;
 53.2010 +        }
 53.2011 +
 53.2012 +        SynchronizedMap(Map<K,V> m, Object mutex) {
 53.2013 +            this.m = m;
 53.2014 +            this.mutex = mutex;
 53.2015 +        }
 53.2016 +
 53.2017 +        public int size() {
 53.2018 +            synchronized (mutex) {return m.size();}
 53.2019 +        }
 53.2020 +        public boolean isEmpty() {
 53.2021 +            synchronized (mutex) {return m.isEmpty();}
 53.2022 +        }
 53.2023 +        public boolean containsKey(Object key) {
 53.2024 +            synchronized (mutex) {return m.containsKey(key);}
 53.2025 +        }
 53.2026 +        public boolean containsValue(Object value) {
 53.2027 +            synchronized (mutex) {return m.containsValue(value);}
 53.2028 +        }
 53.2029 +        public V get(Object key) {
 53.2030 +            synchronized (mutex) {return m.get(key);}
 53.2031 +        }
 53.2032 +
 53.2033 +        public V put(K key, V value) {
 53.2034 +            synchronized (mutex) {return m.put(key, value);}
 53.2035 +        }
 53.2036 +        public V remove(Object key) {
 53.2037 +            synchronized (mutex) {return m.remove(key);}
 53.2038 +        }
 53.2039 +        public void putAll(Map<? extends K, ? extends V> map) {
 53.2040 +            synchronized (mutex) {m.putAll(map);}
 53.2041 +        }
 53.2042 +        public void clear() {
 53.2043 +            synchronized (mutex) {m.clear();}
 53.2044 +        }
 53.2045 +
 53.2046 +        private transient Set<K> keySet = null;
 53.2047 +        private transient Set<Map.Entry<K,V>> entrySet = null;
 53.2048 +        private transient Collection<V> values = null;
 53.2049 +
 53.2050 +        public Set<K> keySet() {
 53.2051 +            synchronized (mutex) {
 53.2052 +                if (keySet==null)
 53.2053 +                    keySet = new SynchronizedSet<>(m.keySet(), mutex);
 53.2054 +                return keySet;
 53.2055 +            }
 53.2056 +        }
 53.2057 +
 53.2058 +        public Set<Map.Entry<K,V>> entrySet() {
 53.2059 +            synchronized (mutex) {
 53.2060 +                if (entrySet==null)
 53.2061 +                    entrySet = new SynchronizedSet<>(m.entrySet(), mutex);
 53.2062 +                return entrySet;
 53.2063 +            }
 53.2064 +        }
 53.2065 +
 53.2066 +        public Collection<V> values() {
 53.2067 +            synchronized (mutex) {
 53.2068 +                if (values==null)
 53.2069 +                    values = new SynchronizedCollection<>(m.values(), mutex);
 53.2070 +                return values;
 53.2071 +            }
 53.2072 +        }
 53.2073 +
 53.2074 +        public boolean equals(Object o) {
 53.2075 +            synchronized (mutex) {return m.equals(o);}
 53.2076 +        }
 53.2077 +        public int hashCode() {
 53.2078 +            synchronized (mutex) {return m.hashCode();}
 53.2079 +        }
 53.2080 +        public String toString() {
 53.2081 +            synchronized (mutex) {return m.toString();}
 53.2082 +        }
 53.2083 +    }
 53.2084 +
 53.2085 +    /**
 53.2086 +     * Returns a synchronized (thread-safe) sorted map backed by the specified
 53.2087 +     * sorted map.  In order to guarantee serial access, it is critical that
 53.2088 +     * <strong>all</strong> access to the backing sorted map is accomplished
 53.2089 +     * through the returned sorted map (or its views).<p>
 53.2090 +     *
 53.2091 +     * It is imperative that the user manually synchronize on the returned
 53.2092 +     * sorted map when iterating over any of its collection views, or the
 53.2093 +     * collections views of any of its <tt>subMap</tt>, <tt>headMap</tt> or
 53.2094 +     * <tt>tailMap</tt> views.
 53.2095 +     * <pre>
 53.2096 +     *  SortedMap m = Collections.synchronizedSortedMap(new TreeMap());
 53.2097 +     *      ...
 53.2098 +     *  Set s = m.keySet();  // Needn't be in synchronized block
 53.2099 +     *      ...
 53.2100 +     *  synchronized (m) {  // Synchronizing on m, not s!
 53.2101 +     *      Iterator i = s.iterator(); // Must be in synchronized block
 53.2102 +     *      while (i.hasNext())
 53.2103 +     *          foo(i.next());
 53.2104 +     *  }
 53.2105 +     * </pre>
 53.2106 +     * or:
 53.2107 +     * <pre>
 53.2108 +     *  SortedMap m = Collections.synchronizedSortedMap(new TreeMap());
 53.2109 +     *  SortedMap m2 = m.subMap(foo, bar);
 53.2110 +     *      ...
 53.2111 +     *  Set s2 = m2.keySet();  // Needn't be in synchronized block
 53.2112 +     *      ...
 53.2113 +     *  synchronized (m) {  // Synchronizing on m, not m2 or s2!
 53.2114 +     *      Iterator i = s.iterator(); // Must be in synchronized block
 53.2115 +     *      while (i.hasNext())
 53.2116 +     *          foo(i.next());
 53.2117 +     *  }
 53.2118 +     * </pre>
 53.2119 +     * Failure to follow this advice may result in non-deterministic behavior.
 53.2120 +     *
 53.2121 +     * <p>The returned sorted map will be serializable if the specified
 53.2122 +     * sorted map is serializable.
 53.2123 +     *
 53.2124 +     * @param  m the sorted map to be "wrapped" in a synchronized sorted map.
 53.2125 +     * @return a synchronized view of the specified sorted map.
 53.2126 +     */
 53.2127 +    public static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m) {
 53.2128 +        return new SynchronizedSortedMap<>(m);
 53.2129 +    }
 53.2130 +
 53.2131 +
 53.2132 +    /**
 53.2133 +     * @serial include
 53.2134 +     */
 53.2135 +    static class SynchronizedSortedMap<K,V>
 53.2136 +        extends SynchronizedMap<K,V>
 53.2137 +        implements SortedMap<K,V>
 53.2138 +    {
 53.2139 +        private static final long serialVersionUID = -8798146769416483793L;
 53.2140 +
 53.2141 +        private final SortedMap<K,V> sm;
 53.2142 +
 53.2143 +        SynchronizedSortedMap(SortedMap<K,V> m) {
 53.2144 +            super(m);
 53.2145 +            sm = m;
 53.2146 +        }
 53.2147 +        SynchronizedSortedMap(SortedMap<K,V> m, Object mutex) {
 53.2148 +            super(m, mutex);
 53.2149 +            sm = m;
 53.2150 +        }
 53.2151 +
 53.2152 +        public Comparator<? super K> comparator() {
 53.2153 +            synchronized (mutex) {return sm.comparator();}
 53.2154 +        }
 53.2155 +
 53.2156 +        public SortedMap<K,V> subMap(K fromKey, K toKey) {
 53.2157 +            synchronized (mutex) {
 53.2158 +                return new SynchronizedSortedMap<>(
 53.2159 +                    sm.subMap(fromKey, toKey), mutex);
 53.2160 +            }
 53.2161 +        }
 53.2162 +        public SortedMap<K,V> headMap(K toKey) {
 53.2163 +            synchronized (mutex) {
 53.2164 +                return new SynchronizedSortedMap<>(sm.headMap(toKey), mutex);
 53.2165 +            }
 53.2166 +        }
 53.2167 +        public SortedMap<K,V> tailMap(K fromKey) {
 53.2168 +            synchronized (mutex) {
 53.2169 +               return new SynchronizedSortedMap<>(sm.tailMap(fromKey),mutex);
 53.2170 +            }
 53.2171 +        }
 53.2172 +
 53.2173 +        public K firstKey() {
 53.2174 +            synchronized (mutex) {return sm.firstKey();}
 53.2175 +        }
 53.2176 +        public K lastKey() {
 53.2177 +            synchronized (mutex) {return sm.lastKey();}
 53.2178 +        }
 53.2179 +    }
 53.2180 +
 53.2181 +    // Dynamically typesafe collection wrappers
 53.2182 +
 53.2183 +    /**
 53.2184 +     * Returns a dynamically typesafe view of the specified collection.
 53.2185 +     * Any attempt to insert an element of the wrong type will result in an
 53.2186 +     * immediate {@link ClassCastException}.  Assuming a collection
 53.2187 +     * contains no incorrectly typed elements prior to the time a
 53.2188 +     * dynamically typesafe view is generated, and that all subsequent
 53.2189 +     * access to the collection takes place through the view, it is
 53.2190 +     * <i>guaranteed</i> that the collection cannot contain an incorrectly
 53.2191 +     * typed element.
 53.2192 +     *
 53.2193 +     * <p>The generics mechanism in the language provides compile-time
 53.2194 +     * (static) type checking, but it is possible to defeat this mechanism
 53.2195 +     * with unchecked casts.  Usually this is not a problem, as the compiler
 53.2196 +     * issues warnings on all such unchecked operations.  There are, however,
 53.2197 +     * times when static type checking alone is not sufficient.  For example,
 53.2198 +     * suppose a collection is passed to a third-party library and it is
 53.2199 +     * imperative that the library code not corrupt the collection by
 53.2200 +     * inserting an element of the wrong type.
 53.2201 +     *
 53.2202 +     * <p>Another use of dynamically typesafe views is debugging.  Suppose a
 53.2203 +     * program fails with a {@code ClassCastException}, indicating that an
 53.2204 +     * incorrectly typed element was put into a parameterized collection.
 53.2205 +     * Unfortunately, the exception can occur at any time after the erroneous
 53.2206 +     * element is inserted, so it typically provides little or no information
 53.2207 +     * as to the real source of the problem.  If the problem is reproducible,
 53.2208 +     * one can quickly determine its source by temporarily modifying the
 53.2209 +     * program to wrap the collection with a dynamically typesafe view.
 53.2210 +     * For example, this declaration:
 53.2211 +     *  <pre> {@code
 53.2212 +     *     Collection<String> c = new HashSet<String>();
 53.2213 +     * }</pre>
 53.2214 +     * may be replaced temporarily by this one:
 53.2215 +     *  <pre> {@code
 53.2216 +     *     Collection<String> c = Collections.checkedCollection(
 53.2217 +     *         new HashSet<String>(), String.class);
 53.2218 +     * }</pre>
 53.2219 +     * Running the program again will cause it to fail at the point where
 53.2220 +     * an incorrectly typed element is inserted into the collection, clearly
 53.2221 +     * identifying the source of the problem.  Once the problem is fixed, the
 53.2222 +     * modified declaration may be reverted back to the original.
 53.2223 +     *
 53.2224 +     * <p>The returned collection does <i>not</i> pass the hashCode and equals
 53.2225 +     * operations through to the backing collection, but relies on
 53.2226 +     * {@code Object}'s {@code equals} and {@code hashCode} methods.  This
 53.2227 +     * is necessary to preserve the contracts of these operations in the case
 53.2228 +     * that the backing collection is a set or a list.
 53.2229 +     *
 53.2230 +     * <p>The returned collection will be serializable if the specified
 53.2231 +     * collection is serializable.
 53.2232 +     *
 53.2233 +     * <p>Since {@code null} is considered to be a value of any reference
 53.2234 +     * type, the returned collection permits insertion of null elements
 53.2235 +     * whenever the backing collection does.
 53.2236 +     *
 53.2237 +     * @param c the collection for which a dynamically typesafe view is to be
 53.2238 +     *          returned
 53.2239 +     * @param type the type of element that {@code c} is permitted to hold
 53.2240 +     * @return a dynamically typesafe view of the specified collection
 53.2241 +     * @since 1.5
 53.2242 +     */
 53.2243 +    public static <E> Collection<E> checkedCollection(Collection<E> c,
 53.2244 +                                                      Class<E> type) {
 53.2245 +        return new CheckedCollection<>(c, type);
 53.2246 +    }
 53.2247 +
 53.2248 +    @SuppressWarnings("unchecked")
 53.2249 +    static <T> T[] zeroLengthArray(Class<T> type) {
 53.2250 +        return (T[]) Array.newInstance(type, 0);
 53.2251 +    }
 53.2252 +
 53.2253 +    /**
 53.2254 +     * @serial include
 53.2255 +     */
 53.2256 +    static class CheckedCollection<E> implements Collection<E>, Serializable {
 53.2257 +        private static final long serialVersionUID = 1578914078182001775L;
 53.2258 +
 53.2259 +        final Collection<E> c;
 53.2260 +        final Class<E> type;
 53.2261 +
 53.2262 +        void typeCheck(Object o) {
 53.2263 +            if (o != null && !type.isInstance(o))
 53.2264 +                throw new ClassCastException(badElementMsg(o));
 53.2265 +        }
 53.2266 +
 53.2267 +        private String badElementMsg(Object o) {
 53.2268 +            return "Attempt to insert " + o.getClass() +
 53.2269 +                " element into collection with element type " + type;
 53.2270 +        }
 53.2271 +
 53.2272 +        CheckedCollection(Collection<E> c, Class<E> type) {
 53.2273 +            if (c==null || type == null)
 53.2274 +                throw new NullPointerException();
 53.2275 +            this.c = c;
 53.2276 +            this.type = type;
 53.2277 +        }
 53.2278 +
 53.2279 +        public int size()                 { return c.size(); }
 53.2280 +        public boolean isEmpty()          { return c.isEmpty(); }
 53.2281 +        public boolean contains(Object o) { return c.contains(o); }
 53.2282 +        public Object[] toArray()         { return c.toArray(); }
 53.2283 +        public <T> T[] toArray(T[] a)     { return c.toArray(a); }
 53.2284 +        public String toString()          { return c.toString(); }
 53.2285 +        public boolean remove(Object o)   { return c.remove(o); }
 53.2286 +        public void clear()               {        c.clear(); }
 53.2287 +
 53.2288 +        public boolean containsAll(Collection<?> coll) {
 53.2289 +            return c.containsAll(coll);
 53.2290 +        }
 53.2291 +        public boolean removeAll(Collection<?> coll) {
 53.2292 +            return c.removeAll(coll);
 53.2293 +        }
 53.2294 +        public boolean retainAll(Collection<?> coll) {
 53.2295 +            return c.retainAll(coll);
 53.2296 +        }
 53.2297 +
 53.2298 +        public Iterator<E> iterator() {
 53.2299 +            final Iterator<E> it = c.iterator();
 53.2300 +            return new Iterator<E>() {
 53.2301 +                public boolean hasNext() { return it.hasNext(); }
 53.2302 +                public E next()          { return it.next(); }
 53.2303 +                public void remove()     {        it.remove(); }};
 53.2304 +        }
 53.2305 +
 53.2306 +        public boolean add(E e) {
 53.2307 +            typeCheck(e);
 53.2308 +            return c.add(e);
 53.2309 +        }
 53.2310 +
 53.2311 +        private E[] zeroLengthElementArray = null; // Lazily initialized
 53.2312 +
 53.2313 +        private E[] zeroLengthElementArray() {
 53.2314 +            return zeroLengthElementArray != null ? zeroLengthElementArray :
 53.2315 +                (zeroLengthElementArray = zeroLengthArray(type));
 53.2316 +        }
 53.2317 +
 53.2318 +        @SuppressWarnings("unchecked")
 53.2319 +        Collection<E> checkedCopyOf(Collection<? extends E> coll) {
 53.2320 +            Object[] a = null;
 53.2321 +            try {
 53.2322 +                E[] z = zeroLengthElementArray();
 53.2323 +                a = coll.toArray(z);
 53.2324 +                // Defend against coll violating the toArray contract
 53.2325 +                if (a.getClass() != z.getClass())
 53.2326 +                    a = Arrays.copyOf(a, a.length, z.getClass());
 53.2327 +            } catch (ArrayStoreException ignore) {
 53.2328 +                // To get better and consistent diagnostics,
 53.2329 +                // we call typeCheck explicitly on each element.
 53.2330 +                // We call clone() to defend against coll retaining a
 53.2331 +                // reference to the returned array and storing a bad
 53.2332 +                // element into it after it has been type checked.
 53.2333 +                a = coll.toArray().clone();
 53.2334 +                for (Object o : a)
 53.2335 +                    typeCheck(o);
 53.2336 +            }
 53.2337 +            // A slight abuse of the type system, but safe here.
 53.2338 +            return (Collection<E>) Arrays.asList(a);
 53.2339 +        }
 53.2340 +
 53.2341 +        public boolean addAll(Collection<? extends E> coll) {
 53.2342 +            // Doing things this way insulates us from concurrent changes
 53.2343 +            // in the contents of coll and provides all-or-nothing
 53.2344 +            // semantics (which we wouldn't get if we type-checked each
 53.2345 +            // element as we added it)
 53.2346 +            return c.addAll(checkedCopyOf(coll));
 53.2347 +        }
 53.2348 +    }
 53.2349 +
 53.2350 +    /**
 53.2351 +     * Returns a dynamically typesafe view of the specified set.
 53.2352 +     * Any attempt to insert an element of the wrong type will result in
 53.2353 +     * an immediate {@link ClassCastException}.  Assuming a set contains
 53.2354 +     * no incorrectly typed elements prior to the time a dynamically typesafe
 53.2355 +     * view is generated, and that all subsequent access to the set
 53.2356 +     * takes place through the view, it is <i>guaranteed</i> that the
 53.2357 +     * set cannot contain an incorrectly typed element.
 53.2358 +     *
 53.2359 +     * <p>A discussion of the use of dynamically typesafe views may be
 53.2360 +     * found in the documentation for the {@link #checkedCollection
 53.2361 +     * checkedCollection} method.
 53.2362 +     *
 53.2363 +     * <p>The returned set will be serializable if the specified set is
 53.2364 +     * serializable.
 53.2365 +     *
 53.2366 +     * <p>Since {@code null} is considered to be a value of any reference
 53.2367 +     * type, the returned set permits insertion of null elements whenever
 53.2368 +     * the backing set does.
 53.2369 +     *
 53.2370 +     * @param s the set for which a dynamically typesafe view is to be
 53.2371 +     *          returned
 53.2372 +     * @param type the type of element that {@code s} is permitted to hold
 53.2373 +     * @return a dynamically typesafe view of the specified set
 53.2374 +     * @since 1.5
 53.2375 +     */
 53.2376 +    public static <E> Set<E> checkedSet(Set<E> s, Class<E> type) {
 53.2377 +        return new CheckedSet<>(s, type);
 53.2378 +    }
 53.2379 +
 53.2380 +    /**
 53.2381 +     * @serial include
 53.2382 +     */
 53.2383 +    static class CheckedSet<E> extends CheckedCollection<E>
 53.2384 +                                 implements Set<E>, Serializable
 53.2385 +    {
 53.2386 +        private static final long serialVersionUID = 4694047833775013803L;
 53.2387 +
 53.2388 +        CheckedSet(Set<E> s, Class<E> elementType) { super(s, elementType); }
 53.2389 +
 53.2390 +        public boolean equals(Object o) { return o == this || c.equals(o); }
 53.2391 +        public int hashCode()           { return c.hashCode(); }
 53.2392 +    }
 53.2393 +
 53.2394 +    /**
 53.2395 +     * Returns a dynamically typesafe view of the specified sorted set.
 53.2396 +     * Any attempt to insert an element of the wrong type will result in an
 53.2397 +     * immediate {@link ClassCastException}.  Assuming a sorted set
 53.2398 +     * contains no incorrectly typed elements prior to the time a
 53.2399 +     * dynamically typesafe view is generated, and that all subsequent
 53.2400 +     * access to the sorted set takes place through the view, it is
 53.2401 +     * <i>guaranteed</i> that the sorted set cannot contain an incorrectly
 53.2402 +     * typed element.
 53.2403 +     *
 53.2404 +     * <p>A discussion of the use of dynamically typesafe views may be
 53.2405 +     * found in the documentation for the {@link #checkedCollection
 53.2406 +     * checkedCollection} method.
 53.2407 +     *
 53.2408 +     * <p>The returned sorted set will be serializable if the specified sorted
 53.2409 +     * set is serializable.
 53.2410 +     *
 53.2411 +     * <p>Since {@code null} is considered to be a value of any reference
 53.2412 +     * type, the returned sorted set permits insertion of null elements
 53.2413 +     * whenever the backing sorted set does.
 53.2414 +     *
 53.2415 +     * @param s the sorted set for which a dynamically typesafe view is to be
 53.2416 +     *          returned
 53.2417 +     * @param type the type of element that {@code s} is permitted to hold
 53.2418 +     * @return a dynamically typesafe view of the specified sorted set
 53.2419 +     * @since 1.5
 53.2420 +     */
 53.2421 +    public static <E> SortedSet<E> checkedSortedSet(SortedSet<E> s,
 53.2422 +                                                    Class<E> type) {
 53.2423 +        return new CheckedSortedSet<>(s, type);
 53.2424 +    }
 53.2425 +
 53.2426 +    /**
 53.2427 +     * @serial include
 53.2428 +     */
 53.2429 +    static class CheckedSortedSet<E> extends CheckedSet<E>
 53.2430 +        implements SortedSet<E>, Serializable
 53.2431 +    {
 53.2432 +        private static final long serialVersionUID = 1599911165492914959L;
 53.2433 +        private final SortedSet<E> ss;
 53.2434 +
 53.2435 +        CheckedSortedSet(SortedSet<E> s, Class<E> type) {
 53.2436 +            super(s, type);
 53.2437 +            ss = s;
 53.2438 +        }
 53.2439 +
 53.2440 +        public Comparator<? super E> comparator() { return ss.comparator(); }
 53.2441 +        public E first()                   { return ss.first(); }
 53.2442 +        public E last()                    { return ss.last(); }
 53.2443 +
 53.2444 +        public SortedSet<E> subSet(E fromElement, E toElement) {
 53.2445 +            return checkedSortedSet(ss.subSet(fromElement,toElement), type);
 53.2446 +        }
 53.2447 +        public SortedSet<E> headSet(E toElement) {
 53.2448 +            return checkedSortedSet(ss.headSet(toElement), type);
 53.2449 +        }
 53.2450 +        public SortedSet<E> tailSet(E fromElement) {
 53.2451 +            return checkedSortedSet(ss.tailSet(fromElement), type);
 53.2452 +        }
 53.2453 +    }
 53.2454 +
 53.2455 +    /**
 53.2456 +     * Returns a dynamically typesafe view of the specified list.
 53.2457 +     * Any attempt to insert an element of the wrong type will result in
 53.2458 +     * an immediate {@link ClassCastException}.  Assuming a list contains
 53.2459 +     * no incorrectly typed elements prior to the time a dynamically typesafe
 53.2460 +     * view is generated, and that all subsequent access to the list
 53.2461 +     * takes place through the view, it is <i>guaranteed</i> that the
 53.2462 +     * list cannot contain an incorrectly typed element.
 53.2463 +     *
 53.2464 +     * <p>A discussion of the use of dynamically typesafe views may be
 53.2465 +     * found in the documentation for the {@link #checkedCollection
 53.2466 +     * checkedCollection} method.
 53.2467 +     *
 53.2468 +     * <p>The returned list will be serializable if the specified list
 53.2469 +     * is serializable.
 53.2470 +     *
 53.2471 +     * <p>Since {@code null} is considered to be a value of any reference
 53.2472 +     * type, the returned list permits insertion of null elements whenever
 53.2473 +     * the backing list does.
 53.2474 +     *
 53.2475 +     * @param list the list for which a dynamically typesafe view is to be
 53.2476 +     *             returned
 53.2477 +     * @param type the type of element that {@code list} is permitted to hold
 53.2478 +     * @return a dynamically typesafe view of the specified list
 53.2479 +     * @since 1.5
 53.2480 +     */
 53.2481 +    public static <E> List<E> checkedList(List<E> list, Class<E> type) {
 53.2482 +        return (list instanceof RandomAccess ?
 53.2483 +                new CheckedRandomAccessList<>(list, type) :
 53.2484 +                new CheckedList<>(list, type));
 53.2485 +    }
 53.2486 +
 53.2487 +    /**
 53.2488 +     * @serial include
 53.2489 +     */
 53.2490 +    static class CheckedList<E>
 53.2491 +        extends CheckedCollection<E>
 53.2492 +        implements List<E>
 53.2493 +    {
 53.2494 +        private static final long serialVersionUID = 65247728283967356L;
 53.2495 +        final List<E> list;
 53.2496 +
 53.2497 +        CheckedList(List<E> list, Class<E> type) {
 53.2498 +            super(list, type);
 53.2499 +            this.list = list;
 53.2500 +        }
 53.2501 +
 53.2502 +        public boolean equals(Object o)  { return o == this || list.equals(o); }
 53.2503 +        public int hashCode()            { return list.hashCode(); }
 53.2504 +        public E get(int index)          { return list.get(index); }
 53.2505 +        public E remove(int index)       { return list.remove(index); }
 53.2506 +        public int indexOf(Object o)     { return list.indexOf(o); }
 53.2507 +        public int lastIndexOf(Object o) { return list.lastIndexOf(o); }
 53.2508 +
 53.2509 +        public E set(int index, E element) {
 53.2510 +            typeCheck(element);
 53.2511 +            return list.set(index, element);
 53.2512 +        }
 53.2513 +
 53.2514 +        public void add(int index, E element) {
 53.2515 +            typeCheck(element);
 53.2516 +            list.add(index, element);
 53.2517 +        }
 53.2518 +
 53.2519 +        public boolean addAll(int index, Collection<? extends E> c) {
 53.2520 +            return list.addAll(index, checkedCopyOf(c));
 53.2521 +        }
 53.2522 +        public ListIterator<E> listIterator()   { return listIterator(0); }
 53.2523 +
 53.2524 +        public ListIterator<E> listIterator(final int index) {
 53.2525 +            final ListIterator<E> i = list.listIterator(index);
 53.2526 +
 53.2527 +            return new ListIterator<E>() {
 53.2528 +                public boolean hasNext()     { return i.hasNext(); }
 53.2529 +                public E next()              { return i.next(); }
 53.2530 +                public boolean hasPrevious() { return i.hasPrevious(); }
 53.2531 +                public E previous()          { return i.previous(); }
 53.2532 +                public int nextIndex()       { return i.nextIndex(); }
 53.2533 +                public int previousIndex()   { return i.previousIndex(); }
 53.2534 +                public void remove()         {        i.remove(); }
 53.2535 +
 53.2536 +                public void set(E e) {
 53.2537 +                    typeCheck(e);
 53.2538 +                    i.set(e);
 53.2539 +                }
 53.2540 +
 53.2541 +                public void add(E e) {
 53.2542 +                    typeCheck(e);
 53.2543 +                    i.add(e);
 53.2544 +                }
 53.2545 +            };
 53.2546 +        }
 53.2547 +
 53.2548 +        public List<E> subList(int fromIndex, int toIndex) {
 53.2549 +            return new CheckedList<>(list.subList(fromIndex, toIndex), type);
 53.2550 +        }
 53.2551 +    }
 53.2552 +
 53.2553 +    /**
 53.2554 +     * @serial include
 53.2555 +     */
 53.2556 +    static class CheckedRandomAccessList<E> extends CheckedList<E>
 53.2557 +                                            implements RandomAccess
 53.2558 +    {
 53.2559 +        private static final long serialVersionUID = 1638200125423088369L;
 53.2560 +
 53.2561 +        CheckedRandomAccessList(List<E> list, Class<E> type) {
 53.2562 +            super(list, type);
 53.2563 +        }
 53.2564 +
 53.2565 +        public List<E> subList(int fromIndex, int toIndex) {
 53.2566 +            return new CheckedRandomAccessList<>(
 53.2567 +                list.subList(fromIndex, toIndex), type);
 53.2568 +        }
 53.2569 +    }
 53.2570 +
 53.2571 +    /**
 53.2572 +     * Returns a dynamically typesafe view of the specified map.
 53.2573 +     * Any attempt to insert a mapping whose key or value have the wrong
 53.2574 +     * type will result in an immediate {@link ClassCastException}.
 53.2575 +     * Similarly, any attempt to modify the value currently associated with
 53.2576 +     * a key will result in an immediate {@link ClassCastException},
 53.2577 +     * whether the modification is attempted directly through the map
 53.2578 +     * itself, or through a {@link Map.Entry} instance obtained from the
 53.2579 +     * map's {@link Map#entrySet() entry set} view.
 53.2580 +     *
 53.2581 +     * <p>Assuming a map contains no incorrectly typed keys or values
 53.2582 +     * prior to the time a dynamically typesafe view is generated, and
 53.2583 +     * that all subsequent access to the map takes place through the view
 53.2584 +     * (or one of its collection views), it is <i>guaranteed</i> that the
 53.2585 +     * map cannot contain an incorrectly typed key or value.
 53.2586 +     *
 53.2587 +     * <p>A discussion of the use of dynamically typesafe views may be
 53.2588 +     * found in the documentation for the {@link #checkedCollection
 53.2589 +     * checkedCollection} method.
 53.2590 +     *
 53.2591 +     * <p>The returned map will be serializable if the specified map is
 53.2592 +     * serializable.
 53.2593 +     *
 53.2594 +     * <p>Since {@code null} is considered to be a value of any reference
 53.2595 +     * type, the returned map permits insertion of null keys or values
 53.2596 +     * whenever the backing map does.
 53.2597 +     *
 53.2598 +     * @param m the map for which a dynamically typesafe view is to be
 53.2599 +     *          returned
 53.2600 +     * @param keyType the type of key that {@code m} is permitted to hold
 53.2601 +     * @param valueType the type of value that {@code m} is permitted to hold
 53.2602 +     * @return a dynamically typesafe view of the specified map
 53.2603 +     * @since 1.5
 53.2604 +     */
 53.2605 +    public static <K, V> Map<K, V> checkedMap(Map<K, V> m,
 53.2606 +                                              Class<K> keyType,
 53.2607 +                                              Class<V> valueType) {
 53.2608 +        return new CheckedMap<>(m, keyType, valueType);
 53.2609 +    }
 53.2610 +
 53.2611 +
 53.2612 +    /**
 53.2613 +     * @serial include
 53.2614 +     */
 53.2615 +    private static class CheckedMap<K,V>
 53.2616 +        implements Map<K,V>, Serializable
 53.2617 +    {
 53.2618 +        private static final long serialVersionUID = 5742860141034234728L;
 53.2619 +
 53.2620 +        private final Map<K, V> m;
 53.2621 +        final Class<K> keyType;
 53.2622 +        final Class<V> valueType;
 53.2623 +
 53.2624 +        private void typeCheck(Object key, Object value) {
 53.2625 +            if (key != null && !keyType.isInstance(key))
 53.2626 +                throw new ClassCastException(badKeyMsg(key));
 53.2627 +
 53.2628 +            if (value != null && !valueType.isInstance(value))
 53.2629 +                throw new ClassCastException(badValueMsg(value));
 53.2630 +        }
 53.2631 +
 53.2632 +        private String badKeyMsg(Object key) {
 53.2633 +            return "Attempt to insert " + key.getClass() +
 53.2634 +                " key into map with key type " + keyType;
 53.2635 +        }
 53.2636 +
 53.2637 +        private String badValueMsg(Object value) {
 53.2638 +            return "Attempt to insert " + value.getClass() +
 53.2639 +                " value into map with value type " + valueType;
 53.2640 +        }
 53.2641 +
 53.2642 +        CheckedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType) {
 53.2643 +            if (m == null || keyType == null || valueType == null)
 53.2644 +                throw new NullPointerException();
 53.2645 +            this.m = m;
 53.2646 +            this.keyType = keyType;
 53.2647 +            this.valueType = valueType;
 53.2648 +        }
 53.2649 +
 53.2650 +        public int size()                      { return m.size(); }
 53.2651 +        public boolean isEmpty()               { return m.isEmpty(); }
 53.2652 +        public boolean containsKey(Object key) { return m.containsKey(key); }
 53.2653 +        public boolean containsValue(Object v) { return m.containsValue(v); }
 53.2654 +        public V get(Object key)               { return m.get(key); }
 53.2655 +        public V remove(Object key)            { return m.remove(key); }
 53.2656 +        public void clear()                    { m.clear(); }
 53.2657 +        public Set<K> keySet()                 { return m.keySet(); }
 53.2658 +        public Collection<V> values()          { return m.values(); }
 53.2659 +        public boolean equals(Object o)        { return o == this || m.equals(o); }
 53.2660 +        public int hashCode()                  { return m.hashCode(); }
 53.2661 +        public String toString()               { return m.toString(); }
 53.2662 +
 53.2663 +        public V put(K key, V value) {
 53.2664 +            typeCheck(key, value);
 53.2665 +            return m.put(key, value);
 53.2666 +        }
 53.2667 +
 53.2668 +        @SuppressWarnings("unchecked")
 53.2669 +        public void putAll(Map<? extends K, ? extends V> t) {
 53.2670 +            // Satisfy the following goals:
 53.2671 +            // - good diagnostics in case of type mismatch
 53.2672 +            // - all-or-nothing semantics
 53.2673 +            // - protection from malicious t
 53.2674 +            // - correct behavior if t is a concurrent map
 53.2675 +            Object[] entries = t.entrySet().toArray();
 53.2676 +            List<Map.Entry<K,V>> checked = new ArrayList<>(entries.length);
 53.2677 +            for (Object o : entries) {
 53.2678 +                Map.Entry<?,?> e = (Map.Entry<?,?>) o;
 53.2679 +                Object k = e.getKey();
 53.2680 +                Object v = e.getValue();
 53.2681 +                typeCheck(k, v);
 53.2682 +                checked.add(
 53.2683 +                    new AbstractMap.SimpleImmutableEntry<>((K) k, (V) v));
 53.2684 +            }
 53.2685 +            for (Map.Entry<K,V> e : checked)
 53.2686 +                m.put(e.getKey(), e.getValue());
 53.2687 +        }
 53.2688 +
 53.2689 +        private transient Set<Map.Entry<K,V>> entrySet = null;
 53.2690 +
 53.2691 +        public Set<Map.Entry<K,V>> entrySet() {
 53.2692 +            if (entrySet==null)
 53.2693 +                entrySet = new CheckedEntrySet<>(m.entrySet(), valueType);
 53.2694 +            return entrySet;
 53.2695 +        }
 53.2696 +
 53.2697 +        /**
 53.2698 +         * We need this class in addition to CheckedSet as Map.Entry permits
 53.2699 +         * modification of the backing Map via the setValue operation.  This
 53.2700 +         * class is subtle: there are many possible attacks that must be
 53.2701 +         * thwarted.
 53.2702 +         *
 53.2703 +         * @serial exclude
 53.2704 +         */
 53.2705 +        static class CheckedEntrySet<K,V> implements Set<Map.Entry<K,V>> {
 53.2706 +            private final Set<Map.Entry<K,V>> s;
 53.2707 +            private final Class<V> valueType;
 53.2708 +
 53.2709 +            CheckedEntrySet(Set<Map.Entry<K, V>> s, Class<V> valueType) {
 53.2710 +                this.s = s;
 53.2711 +                this.valueType = valueType;
 53.2712 +            }
 53.2713 +
 53.2714 +            public int size()        { return s.size(); }
 53.2715 +            public boolean isEmpty() { return s.isEmpty(); }
 53.2716 +            public String toString() { return s.toString(); }
 53.2717 +            public int hashCode()    { return s.hashCode(); }
 53.2718 +            public void clear()      {        s.clear(); }
 53.2719 +
 53.2720 +            public boolean add(Map.Entry<K, V> e) {
 53.2721 +                throw new UnsupportedOperationException();
 53.2722 +            }
 53.2723 +            public boolean addAll(Collection<? extends Map.Entry<K, V>> coll) {
 53.2724 +                throw new UnsupportedOperationException();
 53.2725 +            }
 53.2726 +
 53.2727 +            public Iterator<Map.Entry<K,V>> iterator() {
 53.2728 +                final Iterator<Map.Entry<K, V>> i = s.iterator();
 53.2729 +                final Class<V> valueType = this.valueType;
 53.2730 +
 53.2731 +                return new Iterator<Map.Entry<K,V>>() {
 53.2732 +                    public boolean hasNext() { return i.hasNext(); }
 53.2733 +                    public void remove()     { i.remove(); }
 53.2734 +
 53.2735 +                    public Map.Entry<K,V> next() {
 53.2736 +                        return checkedEntry(i.next(), valueType);
 53.2737 +                    }
 53.2738 +                };
 53.2739 +            }
 53.2740 +
 53.2741 +            @SuppressWarnings("unchecked")
 53.2742 +            public Object[] toArray() {
 53.2743 +                Object[] source = s.toArray();
 53.2744 +
 53.2745 +                /*
 53.2746 +                 * Ensure that we don't get an ArrayStoreException even if
 53.2747 +                 * s.toArray returns an array of something other than Object
 53.2748 +                 */
 53.2749 +                Object[] dest = (CheckedEntry.class.isInstance(
 53.2750 +                    source.getClass().getComponentType()) ? source :
 53.2751 +                                 new Object[source.length]);
 53.2752 +
 53.2753 +                for (int i = 0; i < source.length; i++)
 53.2754 +                    dest[i] = checkedEntry((Map.Entry<K,V>)source[i],
 53.2755 +                                           valueType);
 53.2756 +                return dest;
 53.2757 +            }
 53.2758 +
 53.2759 +            @SuppressWarnings("unchecked")
 53.2760 +            public <T> T[] toArray(T[] a) {
 53.2761 +                // We don't pass a to s.toArray, to avoid window of
 53.2762 +                // vulnerability wherein an unscrupulous multithreaded client
 53.2763 +                // could get his hands on raw (unwrapped) Entries from s.
 53.2764 +                T[] arr = s.toArray(a.length==0 ? a : Arrays.copyOf(a, 0));
 53.2765 +
 53.2766 +                for (int i=0; i<arr.length; i++)
 53.2767 +                    arr[i] = (T) checkedEntry((Map.Entry<K,V>)arr[i],
 53.2768 +                                              valueType);
 53.2769 +                if (arr.length > a.length)
 53.2770 +                    return arr;
 53.2771 +
 53.2772 +                System.arraycopy(arr, 0, a, 0, arr.length);
 53.2773 +                if (a.length > arr.length)
 53.2774 +                    a[arr.length] = null;
 53.2775 +                return a;
 53.2776 +            }
 53.2777 +
 53.2778 +            /**
 53.2779 +             * This method is overridden to protect the backing set against
 53.2780 +             * an object with a nefarious equals function that senses
 53.2781 +             * that the equality-candidate is Map.Entry and calls its
 53.2782 +             * setValue method.
 53.2783 +             */
 53.2784 +            public boolean contains(Object o) {
 53.2785 +                if (!(o instanceof Map.Entry))
 53.2786 +                    return false;
 53.2787 +                Map.Entry<?,?> e = (Map.Entry<?,?>) o;
 53.2788 +                return s.contains(
 53.2789 +                    (e instanceof CheckedEntry) ? e : checkedEntry(e, valueType));
 53.2790 +            }
 53.2791 +
 53.2792 +            /**
 53.2793 +             * The bulk collection methods are overridden to protect
 53.2794 +             * against an unscrupulous collection whose contains(Object o)
 53.2795 +             * method senses when o is a Map.Entry, and calls o.setValue.
 53.2796 +             */
 53.2797 +            public boolean containsAll(Collection<?> c) {
 53.2798 +                for (Object o : c)
 53.2799 +                    if (!contains(o)) // Invokes safe contains() above
 53.2800 +                        return false;
 53.2801 +                return true;
 53.2802 +            }
 53.2803 +
 53.2804 +            public boolean remove(Object o) {
 53.2805 +                if (!(o instanceof Map.Entry))
 53.2806 +                    return false;
 53.2807 +                return s.remove(new AbstractMap.SimpleImmutableEntry
 53.2808 +                                <>((Map.Entry<?,?>)o));
 53.2809 +            }
 53.2810 +
 53.2811 +            public boolean removeAll(Collection<?> c) {
 53.2812 +                return batchRemove(c, false);
 53.2813 +            }
 53.2814 +            public boolean retainAll(Collection<?> c) {
 53.2815 +                return batchRemove(c, true);
 53.2816 +            }
 53.2817 +            private boolean batchRemove(Collection<?> c, boolean complement) {
 53.2818 +                boolean modified = false;
 53.2819 +                Iterator<Map.Entry<K,V>> it = iterator();
 53.2820 +                while (it.hasNext()) {
 53.2821 +                    if (c.contains(it.next()) != complement) {
 53.2822 +                        it.remove();
 53.2823 +                        modified = true;
 53.2824 +                    }
 53.2825 +                }
 53.2826 +                return modified;
 53.2827 +            }
 53.2828 +
 53.2829 +            public boolean equals(Object o) {
 53.2830 +                if (o == this)
 53.2831 +                    return true;
 53.2832 +                if (!(o instanceof Set))
 53.2833 +                    return false;
 53.2834 +                Set<?> that = (Set<?>) o;
 53.2835 +                return that.size() == s.size()
 53.2836 +                    && containsAll(that); // Invokes safe containsAll() above
 53.2837 +            }
 53.2838 +
 53.2839 +            static <K,V,T> CheckedEntry<K,V,T> checkedEntry(Map.Entry<K,V> e,
 53.2840 +                                                            Class<T> valueType) {
 53.2841 +                return new CheckedEntry<>(e, valueType);
 53.2842 +            }
 53.2843 +
 53.2844 +            /**
 53.2845 +             * This "wrapper class" serves two purposes: it prevents
 53.2846 +             * the client from modifying the backing Map, by short-circuiting
 53.2847 +             * the setValue method, and it protects the backing Map against
 53.2848 +             * an ill-behaved Map.Entry that attempts to modify another
 53.2849 +             * Map.Entry when asked to perform an equality check.
 53.2850 +             */
 53.2851 +            private static class CheckedEntry<K,V,T> implements Map.Entry<K,V> {
 53.2852 +                private final Map.Entry<K, V> e;
 53.2853 +                private final Class<T> valueType;
 53.2854 +
 53.2855 +                CheckedEntry(Map.Entry<K, V> e, Class<T> valueType) {
 53.2856 +                    this.e = e;
 53.2857 +                    this.valueType = valueType;
 53.2858 +                }
 53.2859 +
 53.2860 +                public K getKey()        { return e.getKey(); }
 53.2861 +                public V getValue()      { return e.getValue(); }
 53.2862 +                public int hashCode()    { return e.hashCode(); }
 53.2863 +                public String toString() { return e.toString(); }
 53.2864 +
 53.2865 +                public V setValue(V value) {
 53.2866 +                    if (value != null && !valueType.isInstance(value))
 53.2867 +                        throw new ClassCastException(badValueMsg(value));
 53.2868 +                    return e.setValue(value);
 53.2869 +                }
 53.2870 +
 53.2871 +                private String badValueMsg(Object value) {
 53.2872 +                    return "Attempt to insert " + value.getClass() +
 53.2873 +                        " value into map with value type " + valueType;
 53.2874 +                }
 53.2875 +
 53.2876 +                public boolean equals(Object o) {
 53.2877 +                    if (o == this)
 53.2878 +                        return true;
 53.2879 +                    if (!(o instanceof Map.Entry))
 53.2880 +                        return false;
 53.2881 +                    return e.equals(new AbstractMap.SimpleImmutableEntry
 53.2882 +                                    <>((Map.Entry<?,?>)o));
 53.2883 +                }
 53.2884 +            }
 53.2885 +        }
 53.2886 +    }
 53.2887 +
 53.2888 +    /**
 53.2889 +     * Returns a dynamically typesafe view of the specified sorted map.
 53.2890 +     * Any attempt to insert a mapping whose key or value have the wrong
 53.2891 +     * type will result in an immediate {@link ClassCastException}.
 53.2892 +     * Similarly, any attempt to modify the value currently associated with
 53.2893 +     * a key will result in an immediate {@link ClassCastException},
 53.2894 +     * whether the modification is attempted directly through the map
 53.2895 +     * itself, or through a {@link Map.Entry} instance obtained from the
 53.2896 +     * map's {@link Map#entrySet() entry set} view.
 53.2897 +     *
 53.2898 +     * <p>Assuming a map contains no incorrectly typed keys or values
 53.2899 +     * prior to the time a dynamically typesafe view is generated, and
 53.2900 +     * that all subsequent access to the map takes place through the view
 53.2901 +     * (or one of its collection views), it is <i>guaranteed</i> that the
 53.2902 +     * map cannot contain an incorrectly typed key or value.
 53.2903 +     *
 53.2904 +     * <p>A discussion of the use of dynamically typesafe views may be
 53.2905 +     * found in the documentation for the {@link #checkedCollection
 53.2906 +     * checkedCollection} method.
 53.2907 +     *
 53.2908 +     * <p>The returned map will be serializable if the specified map is
 53.2909 +     * serializable.
 53.2910 +     *
 53.2911 +     * <p>Since {@code null} is considered to be a value of any reference
 53.2912 +     * type, the returned map permits insertion of null keys or values
 53.2913 +     * whenever the backing map does.
 53.2914 +     *
 53.2915 +     * @param m the map for which a dynamically typesafe view is to be
 53.2916 +     *          returned
 53.2917 +     * @param keyType the type of key that {@code m} is permitted to hold
 53.2918 +     * @param valueType the type of value that {@code m} is permitted to hold
 53.2919 +     * @return a dynamically typesafe view of the specified map
 53.2920 +     * @since 1.5
 53.2921 +     */
 53.2922 +    public static <K,V> SortedMap<K,V> checkedSortedMap(SortedMap<K, V> m,
 53.2923 +                                                        Class<K> keyType,
 53.2924 +                                                        Class<V> valueType) {
 53.2925 +        return new CheckedSortedMap<>(m, keyType, valueType);
 53.2926 +    }
 53.2927 +
 53.2928 +    /**
 53.2929 +     * @serial include
 53.2930 +     */
 53.2931 +    static class CheckedSortedMap<K,V> extends CheckedMap<K,V>
 53.2932 +        implements SortedMap<K,V>, Serializable
 53.2933 +    {
 53.2934 +        private static final long serialVersionUID = 1599671320688067438L;
 53.2935 +
 53.2936 +        private final SortedMap<K, V> sm;
 53.2937 +
 53.2938 +        CheckedSortedMap(SortedMap<K, V> m,
 53.2939 +                         Class<K> keyType, Class<V> valueType) {
 53.2940 +            super(m, keyType, valueType);
 53.2941 +            sm = m;
 53.2942 +        }
 53.2943 +
 53.2944 +        public Comparator<? super K> comparator() { return sm.comparator(); }
 53.2945 +        public K firstKey()                       { return sm.firstKey(); }
 53.2946 +        public K lastKey()                        { return sm.lastKey(); }
 53.2947 +
 53.2948 +        public SortedMap<K,V> subMap(K fromKey, K toKey) {
 53.2949 +            return checkedSortedMap(sm.subMap(fromKey, toKey),
 53.2950 +                                    keyType, valueType);
 53.2951 +        }
 53.2952 +        public SortedMap<K,V> headMap(K toKey) {
 53.2953 +            return checkedSortedMap(sm.headMap(toKey), keyType, valueType);
 53.2954 +        }
 53.2955 +        public SortedMap<K,V> tailMap(K fromKey) {
 53.2956 +            return checkedSortedMap(sm.tailMap(fromKey), keyType, valueType);
 53.2957 +        }
 53.2958 +    }
 53.2959 +
 53.2960 +    // Empty collections
 53.2961 +
 53.2962 +    /**
 53.2963 +     * Returns an iterator that has no elements.  More precisely,
 53.2964 +     *
 53.2965 +     * <ul compact>
 53.2966 +     *
 53.2967 +     * <li>{@link Iterator#hasNext hasNext} always returns {@code
 53.2968 +     * false}.
 53.2969 +     *
 53.2970 +     * <li>{@link Iterator#next next} always throws {@link
 53.2971 +     * NoSuchElementException}.
 53.2972 +     *
 53.2973 +     * <li>{@link Iterator#remove remove} always throws {@link
 53.2974 +     * IllegalStateException}.
 53.2975 +     *
 53.2976 +     * </ul>
 53.2977 +     *
 53.2978 +     * <p>Implementations of this method are permitted, but not
 53.2979 +     * required, to return the same object from multiple invocations.
 53.2980 +     *
 53.2981 +     * @return an empty iterator
 53.2982 +     * @since 1.7
 53.2983 +     */
 53.2984 +    @SuppressWarnings("unchecked")
 53.2985 +    public static <T> Iterator<T> emptyIterator() {
 53.2986 +        return (Iterator<T>) EmptyIterator.EMPTY_ITERATOR;
 53.2987 +    }
 53.2988 +
 53.2989 +    private static class EmptyIterator<E> implements Iterator<E> {
 53.2990 +        static final EmptyIterator<Object> EMPTY_ITERATOR
 53.2991 +            = new EmptyIterator<>();
 53.2992 +
 53.2993 +        public boolean hasNext() { return false; }
 53.2994 +        public E next() { throw new NoSuchElementException(); }
 53.2995 +        public void remove() { throw new IllegalStateException(); }
 53.2996 +    }
 53.2997 +
 53.2998 +    /**
 53.2999 +     * Returns a list iterator that has no elements.  More precisely,
 53.3000 +     *
 53.3001 +     * <ul compact>
 53.3002 +     *
 53.3003 +     * <li>{@link Iterator#hasNext hasNext} and {@link
 53.3004 +     * ListIterator#hasPrevious hasPrevious} always return {@code
 53.3005 +     * false}.
 53.3006 +     *
 53.3007 +     * <li>{@link Iterator#next next} and {@link ListIterator#previous
 53.3008 +     * previous} always throw {@link NoSuchElementException}.
 53.3009 +     *
 53.3010 +     * <li>{@link Iterator#remove remove} and {@link ListIterator#set
 53.3011 +     * set} always throw {@link IllegalStateException}.
 53.3012 +     *
 53.3013 +     * <li>{@link ListIterator#add add} always throws {@link
 53.3014 +     * UnsupportedOperationException}.
 53.3015 +     *
 53.3016 +     * <li>{@link ListIterator#nextIndex nextIndex} always returns
 53.3017 +     * {@code 0} .
 53.3018 +     *
 53.3019 +     * <li>{@link ListIterator#previousIndex previousIndex} always
 53.3020 +     * returns {@code -1}.
 53.3021 +     *
 53.3022 +     * </ul>
 53.3023 +     *
 53.3024 +     * <p>Implementations of this method are permitted, but not
 53.3025 +     * required, to return the same object from multiple invocations.
 53.3026 +     *
 53.3027 +     * @return an empty list iterator
 53.3028 +     * @since 1.7
 53.3029 +     */
 53.3030 +    @SuppressWarnings("unchecked")
 53.3031 +    public static <T> ListIterator<T> emptyListIterator() {
 53.3032 +        return (ListIterator<T>) EmptyListIterator.EMPTY_ITERATOR;
 53.3033 +    }
 53.3034 +
 53.3035 +    private static class EmptyListIterator<E>
 53.3036 +        extends EmptyIterator<E>
 53.3037 +        implements ListIterator<E>
 53.3038 +    {
 53.3039 +        static final EmptyListIterator<Object> EMPTY_ITERATOR
 53.3040 +            = new EmptyListIterator<>();
 53.3041 +
 53.3042 +        public boolean hasPrevious() { return false; }
 53.3043 +        public E previous() { throw new NoSuchElementException(); }
 53.3044 +        public int nextIndex()     { return 0; }
 53.3045 +        public int previousIndex() { return -1; }
 53.3046 +        public void set(E e) { throw new IllegalStateException(); }
 53.3047 +        public void add(E e) { throw new UnsupportedOperationException(); }
 53.3048 +    }
 53.3049 +
 53.3050 +    /**
 53.3051 +     * Returns an enumeration that has no elements.  More precisely,
 53.3052 +     *
 53.3053 +     * <ul compact>
 53.3054 +     *
 53.3055 +     * <li>{@link Enumeration#hasMoreElements hasMoreElements} always
 53.3056 +     * returns {@code false}.
 53.3057 +     *
 53.3058 +     * <li> {@link Enumeration#nextElement nextElement} always throws
 53.3059 +     * {@link NoSuchElementException}.
 53.3060 +     *
 53.3061 +     * </ul>
 53.3062 +     *
 53.3063 +     * <p>Implementations of this method are permitted, but not
 53.3064 +     * required, to return the same object from multiple invocations.
 53.3065 +     *
 53.3066 +     * @return an empty enumeration
 53.3067 +     * @since 1.7
 53.3068 +     */
 53.3069 +    @SuppressWarnings("unchecked")
 53.3070 +    public static <T> Enumeration<T> emptyEnumeration() {
 53.3071 +        return (Enumeration<T>) EmptyEnumeration.EMPTY_ENUMERATION;
 53.3072 +    }
 53.3073 +
 53.3074 +    private static class EmptyEnumeration<E> implements Enumeration<E> {
 53.3075 +        static final EmptyEnumeration<Object> EMPTY_ENUMERATION
 53.3076 +            = new EmptyEnumeration<>();
 53.3077 +
 53.3078 +        public boolean hasMoreElements() { return false; }
 53.3079 +        public E nextElement() { throw new NoSuchElementException(); }
 53.3080 +    }
 53.3081 +
 53.3082 +    /**
 53.3083 +     * The empty set (immutable).  This set is serializable.
 53.3084 +     *
 53.3085 +     * @see #emptySet()
 53.3086 +     */
 53.3087 +    @SuppressWarnings("unchecked")
 53.3088 +    public static final Set EMPTY_SET = new EmptySet<>();
 53.3089 +
 53.3090 +    /**
 53.3091 +     * Returns the empty set (immutable).  This set is serializable.
 53.3092 +     * Unlike the like-named field, this method is parameterized.
 53.3093 +     *
 53.3094 +     * <p>This example illustrates the type-safe way to obtain an empty set:
 53.3095 +     * <pre>
 53.3096 +     *     Set&lt;String&gt; s = Collections.emptySet();
 53.3097 +     * </pre>
 53.3098 +     * Implementation note:  Implementations of this method need not
 53.3099 +     * create a separate <tt>Set</tt> object for each call.   Using this
 53.3100 +     * method is likely to have comparable cost to using the like-named
 53.3101 +     * field.  (Unlike this method, the field does not provide type safety.)
 53.3102 +     *
 53.3103 +     * @see #EMPTY_SET
 53.3104 +     * @since 1.5
 53.3105 +     */
 53.3106 +    @SuppressWarnings("unchecked")
 53.3107 +    public static final <T> Set<T> emptySet() {
 53.3108 +        return (Set<T>) EMPTY_SET;
 53.3109 +    }
 53.3110 +
 53.3111 +    /**
 53.3112 +     * @serial include
 53.3113 +     */
 53.3114 +    private static class EmptySet<E>
 53.3115 +        extends AbstractSet<E>
 53.3116 +        implements Serializable
 53.3117 +    {
 53.3118 +        private static final long serialVersionUID = 1582296315990362920L;
 53.3119 +
 53.3120 +        public Iterator<E> iterator() { return emptyIterator(); }
 53.3121 +
 53.3122 +        public int size() {return 0;}
 53.3123 +        public boolean isEmpty() {return true;}
 53.3124 +
 53.3125 +        public boolean contains(Object obj) {return false;}
 53.3126 +        public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
 53.3127 +
 53.3128 +        public Object[] toArray() { return new Object[0]; }
 53.3129 +
 53.3130 +        public <T> T[] toArray(T[] a) {
 53.3131 +            if (a.length > 0)
 53.3132 +                a[0] = null;
 53.3133 +            return a;
 53.3134 +        }
 53.3135 +
 53.3136 +        // Preserves singleton property
 53.3137 +        private Object readResolve() {
 53.3138 +            return EMPTY_SET;
 53.3139 +        }
 53.3140 +    }
 53.3141 +
 53.3142 +    /**
 53.3143 +     * The empty list (immutable).  This list is serializable.
 53.3144 +     *
 53.3145 +     * @see #emptyList()
 53.3146 +     */
 53.3147 +    @SuppressWarnings("unchecked")
 53.3148 +    public static final List EMPTY_LIST = new EmptyList<>();
 53.3149 +
 53.3150 +    /**
 53.3151 +     * Returns the empty list (immutable).  This list is serializable.
 53.3152 +     *
 53.3153 +     * <p>This example illustrates the type-safe way to obtain an empty list:
 53.3154 +     * <pre>
 53.3155 +     *     List&lt;String&gt; s = Collections.emptyList();
 53.3156 +     * </pre>
 53.3157 +     * Implementation note:  Implementations of this method need not
 53.3158 +     * create a separate <tt>List</tt> object for each call.   Using this
 53.3159 +     * method is likely to have comparable cost to using the like-named
 53.3160 +     * field.  (Unlike this method, the field does not provide type safety.)
 53.3161 +     *
 53.3162 +     * @see #EMPTY_LIST
 53.3163 +     * @since 1.5
 53.3164 +     */
 53.3165 +    @SuppressWarnings("unchecked")
 53.3166 +    public static final <T> List<T> emptyList() {
 53.3167 +        return (List<T>) EMPTY_LIST;
 53.3168 +    }
 53.3169 +
 53.3170 +    /**
 53.3171 +     * @serial include
 53.3172 +     */
 53.3173 +    private static class EmptyList<E>
 53.3174 +        extends AbstractList<E>
 53.3175 +        implements RandomAccess, Serializable {
 53.3176 +        private static final long serialVersionUID = 8842843931221139166L;
 53.3177 +
 53.3178 +        public Iterator<E> iterator() {
 53.3179 +            return emptyIterator();
 53.3180 +        }
 53.3181 +        public ListIterator<E> listIterator() {
 53.3182 +            return emptyListIterator();
 53.3183 +        }
 53.3184 +
 53.3185 +        public int size() {return 0;}
 53.3186 +        public boolean isEmpty() {return true;}
 53.3187 +
 53.3188 +        public boolean contains(Object obj) {return false;}
 53.3189 +        public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
 53.3190 +
 53.3191 +        public Object[] toArray() { return new Object[0]; }
 53.3192 +
 53.3193 +        public <T> T[] toArray(T[] a) {
 53.3194 +            if (a.length > 0)
 53.3195 +                a[0] = null;
 53.3196 +            return a;
 53.3197 +        }
 53.3198 +
 53.3199 +        public E get(int index) {
 53.3200 +            throw new IndexOutOfBoundsException("Index: "+index);
 53.3201 +        }
 53.3202 +
 53.3203 +        public boolean equals(Object o) {
 53.3204 +            return (o instanceof List) && ((List<?>)o).isEmpty();
 53.3205 +        }
 53.3206 +
 53.3207 +        public int hashCode() { return 1; }
 53.3208 +
 53.3209 +        // Preserves singleton property
 53.3210 +        private Object readResolve() {
 53.3211 +            return EMPTY_LIST;
 53.3212 +        }
 53.3213 +    }
 53.3214 +
 53.3215 +    /**
 53.3216 +     * The empty map (immutable).  This map is serializable.
 53.3217 +     *
 53.3218 +     * @see #emptyMap()
 53.3219 +     * @since 1.3
 53.3220 +     */
 53.3221 +    @SuppressWarnings("unchecked")
 53.3222 +    public static final Map EMPTY_MAP = new EmptyMap<>();
 53.3223 +
 53.3224 +    /**
 53.3225 +     * Returns the empty map (immutable).  This map is serializable.
 53.3226 +     *
 53.3227 +     * <p>This example illustrates the type-safe way to obtain an empty set:
 53.3228 +     * <pre>
 53.3229 +     *     Map&lt;String, Date&gt; s = Collections.emptyMap();
 53.3230 +     * </pre>
 53.3231 +     * Implementation note:  Implementations of this method need not
 53.3232 +     * create a separate <tt>Map</tt> object for each call.   Using this
 53.3233 +     * method is likely to have comparable cost to using the like-named
 53.3234 +     * field.  (Unlike this method, the field does not provide type safety.)
 53.3235 +     *
 53.3236 +     * @see #EMPTY_MAP
 53.3237 +     * @since 1.5
 53.3238 +     */
 53.3239 +    @SuppressWarnings("unchecked")
 53.3240 +    public static final <K,V> Map<K,V> emptyMap() {
 53.3241 +        return (Map<K,V>) EMPTY_MAP;
 53.3242 +    }
 53.3243 +
 53.3244 +    /**
 53.3245 +     * @serial include
 53.3246 +     */
 53.3247 +    private static class EmptyMap<K,V>
 53.3248 +        extends AbstractMap<K,V>
 53.3249 +        implements Serializable
 53.3250 +    {
 53.3251 +        private static final long serialVersionUID = 6428348081105594320L;
 53.3252 +
 53.3253 +        public int size()                          {return 0;}
 53.3254 +        public boolean isEmpty()                   {return true;}
 53.3255 +        public boolean containsKey(Object key)     {return false;}
 53.3256 +        public boolean containsValue(Object value) {return false;}
 53.3257 +        public V get(Object key)                   {return null;}
 53.3258 +        public Set<K> keySet()                     {return emptySet();}
 53.3259 +        public Collection<V> values()              {return emptySet();}
 53.3260 +        public Set<Map.Entry<K,V>> entrySet()      {return emptySet();}
 53.3261 +
 53.3262 +        public boolean equals(Object o) {
 53.3263 +            return (o instanceof Map) && ((Map<?,?>)o).isEmpty();
 53.3264 +        }
 53.3265 +
 53.3266 +        public int hashCode()                      {return 0;}
 53.3267 +
 53.3268 +        // Preserves singleton property
 53.3269 +        private Object readResolve() {
 53.3270 +            return EMPTY_MAP;
 53.3271 +        }
 53.3272 +    }
 53.3273 +
 53.3274 +    // Singleton collections
 53.3275 +
 53.3276 +    /**
 53.3277 +     * Returns an immutable set containing only the specified object.
 53.3278 +     * The returned set is serializable.
 53.3279 +     *
 53.3280 +     * @param o the sole object to be stored in the returned set.
 53.3281 +     * @return an immutable set containing only the specified object.
 53.3282 +     */
 53.3283 +    public static <T> Set<T> singleton(T o) {
 53.3284 +        return new SingletonSet<>(o);
 53.3285 +    }
 53.3286 +
 53.3287 +    static <E> Iterator<E> singletonIterator(final E e) {
 53.3288 +        return new Iterator<E>() {
 53.3289 +            private boolean hasNext = true;
 53.3290 +            public boolean hasNext() {
 53.3291 +                return hasNext;
 53.3292 +            }
 53.3293 +            public E next() {
 53.3294 +                if (hasNext) {
 53.3295 +                    hasNext = false;
 53.3296 +                    return e;
 53.3297 +                }
 53.3298 +                throw new NoSuchElementException();
 53.3299 +            }
 53.3300 +            public void remove() {
 53.3301 +                throw new UnsupportedOperationException();
 53.3302 +            }
 53.3303 +        };
 53.3304 +    }
 53.3305 +
 53.3306 +    /**
 53.3307 +     * @serial include
 53.3308 +     */
 53.3309 +    private static class SingletonSet<E>
 53.3310 +        extends AbstractSet<E>
 53.3311 +        implements Serializable
 53.3312 +    {
 53.3313 +        private static final long serialVersionUID = 3193687207550431679L;
 53.3314 +
 53.3315 +        private final E element;
 53.3316 +
 53.3317 +        SingletonSet(E e) {element = e;}
 53.3318 +
 53.3319 +        public Iterator<E> iterator() {
 53.3320 +            return singletonIterator(element);
 53.3321 +        }
 53.3322 +
 53.3323 +        public int size() {return 1;}
 53.3324 +
 53.3325 +        public boolean contains(Object o) {return eq(o, element);}
 53.3326 +    }
 53.3327 +
 53.3328 +    /**
 53.3329 +     * Returns an immutable list containing only the specified object.
 53.3330 +     * The returned list is serializable.
 53.3331 +     *
 53.3332 +     * @param o the sole object to be stored in the returned list.
 53.3333 +     * @return an immutable list containing only the specified object.
 53.3334 +     * @since 1.3
 53.3335 +     */
 53.3336 +    public static <T> List<T> singletonList(T o) {
 53.3337 +        return new SingletonList<>(o);
 53.3338 +    }
 53.3339 +
 53.3340 +    /**
 53.3341 +     * @serial include
 53.3342 +     */
 53.3343 +    private static class SingletonList<E>
 53.3344 +        extends AbstractList<E>
 53.3345 +        implements RandomAccess, Serializable {
 53.3346 +
 53.3347 +        private static final long serialVersionUID = 3093736618740652951L;
 53.3348 +
 53.3349 +        private final E element;
 53.3350 +
 53.3351 +        SingletonList(E obj)                {element = obj;}
 53.3352 +
 53.3353 +        public Iterator<E> iterator() {
 53.3354 +            return singletonIterator(element);
 53.3355 +        }
 53.3356 +
 53.3357 +        public int size()                   {return 1;}
 53.3358 +
 53.3359 +        public boolean contains(Object obj) {return eq(obj, element);}
 53.3360 +
 53.3361 +        public E get(int index) {
 53.3362 +            if (index != 0)
 53.3363 +              throw new IndexOutOfBoundsException("Index: "+index+", Size: 1");
 53.3364 +            return element;
 53.3365 +        }
 53.3366 +    }
 53.3367 +
 53.3368 +    /**
 53.3369 +     * Returns an immutable map, mapping only the specified key to the
 53.3370 +     * specified value.  The returned map is serializable.
 53.3371 +     *
 53.3372 +     * @param key the sole key to be stored in the returned map.
 53.3373 +     * @param value the value to which the returned map maps <tt>key</tt>.
 53.3374 +     * @return an immutable map containing only the specified key-value
 53.3375 +     *         mapping.
 53.3376 +     * @since 1.3
 53.3377 +     */
 53.3378 +    public static <K,V> Map<K,V> singletonMap(K key, V value) {
 53.3379 +        return new SingletonMap<>(key, value);
 53.3380 +    }
 53.3381 +
 53.3382 +    /**
 53.3383 +     * @serial include
 53.3384 +     */
 53.3385 +    private static class SingletonMap<K,V>
 53.3386 +          extends AbstractMap<K,V>
 53.3387 +          implements Serializable {
 53.3388 +        private static final long serialVersionUID = -6979724477215052911L;
 53.3389 +
 53.3390 +        private final K k;
 53.3391 +        private final V v;
 53.3392 +
 53.3393 +        SingletonMap(K key, V value) {
 53.3394 +            k = key;
 53.3395 +            v = value;
 53.3396 +        }
 53.3397 +
 53.3398 +        public int size()                          {return 1;}
 53.3399 +
 53.3400 +        public boolean isEmpty()                   {return false;}
 53.3401 +
 53.3402 +        public boolean containsKey(Object key)     {return eq(key, k);}
 53.3403 +
 53.3404 +        public boolean containsValue(Object value) {return eq(value, v);}
 53.3405 +
 53.3406 +        public V get(Object key)                   {return (eq(key, k) ? v : null);}
 53.3407 +
 53.3408 +        private transient Set<K> keySet = null;
 53.3409 +        private transient Set<Map.Entry<K,V>> entrySet = null;
 53.3410 +        private transient Collection<V> values = null;
 53.3411 +
 53.3412 +        public Set<K> keySet() {
 53.3413 +            if (keySet==null)
 53.3414 +                keySet = singleton(k);
 53.3415 +            return keySet;
 53.3416 +        }
 53.3417 +
 53.3418 +        public Set<Map.Entry<K,V>> entrySet() {
 53.3419 +            if (entrySet==null)
 53.3420 +                entrySet = Collections.<Map.Entry<K,V>>singleton(
 53.3421 +                    new SimpleImmutableEntry<>(k, v));
 53.3422 +            return entrySet;
 53.3423 +        }
 53.3424 +
 53.3425 +        public Collection<V> values() {
 53.3426 +            if (values==null)
 53.3427 +                values = singleton(v);
 53.3428 +            return values;
 53.3429 +        }
 53.3430 +
 53.3431 +    }
 53.3432 +
 53.3433 +    // Miscellaneous
 53.3434 +
 53.3435 +    /**
 53.3436 +     * Returns an immutable list consisting of <tt>n</tt> copies of the
 53.3437 +     * specified object.  The newly allocated data object is tiny (it contains
 53.3438 +     * a single reference to the data object).  This method is useful in
 53.3439 +     * combination with the <tt>List.addAll</tt> method to grow lists.
 53.3440 +     * The returned list is serializable.
 53.3441 +     *
 53.3442 +     * @param  n the number of elements in the returned list.
 53.3443 +     * @param  o the element to appear repeatedly in the returned list.
 53.3444 +     * @return an immutable list consisting of <tt>n</tt> copies of the
 53.3445 +     *         specified object.
 53.3446 +     * @throws IllegalArgumentException if {@code n < 0}
 53.3447 +     * @see    List#addAll(Collection)
 53.3448 +     * @see    List#addAll(int, Collection)
 53.3449 +     */
 53.3450 +    public static <T> List<T> nCopies(int n, T o) {
 53.3451 +        if (n < 0)
 53.3452 +            throw new IllegalArgumentException("List length = " + n);
 53.3453 +        return new CopiesList<>(n, o);
 53.3454 +    }
 53.3455 +
 53.3456 +    /**
 53.3457 +     * @serial include
 53.3458 +     */
 53.3459 +    private static class CopiesList<E>
 53.3460 +        extends AbstractList<E>
 53.3461 +        implements RandomAccess, Serializable
 53.3462 +    {
 53.3463 +        private static final long serialVersionUID = 2739099268398711800L;
 53.3464 +
 53.3465 +        final int n;
 53.3466 +        final E element;
 53.3467 +
 53.3468 +        CopiesList(int n, E e) {
 53.3469 +            assert n >= 0;
 53.3470 +            this.n = n;
 53.3471 +            element = e;
 53.3472 +        }
 53.3473 +
 53.3474 +        public int size() {
 53.3475 +            return n;
 53.3476 +        }
 53.3477 +
 53.3478 +        public boolean contains(Object obj) {
 53.3479 +            return n != 0 && eq(obj, element);
 53.3480 +        }
 53.3481 +
 53.3482 +        public int indexOf(Object o) {
 53.3483 +            return contains(o) ? 0 : -1;
 53.3484 +        }
 53.3485 +
 53.3486 +        public int lastIndexOf(Object o) {
 53.3487 +            return contains(o) ? n - 1 : -1;
 53.3488 +        }
 53.3489 +
 53.3490 +        public E get(int index) {
 53.3491 +            if (index < 0 || index >= n)
 53.3492 +                throw new IndexOutOfBoundsException("Index: "+index+
 53.3493 +                                                    ", Size: "+n);
 53.3494 +            return element;
 53.3495 +        }
 53.3496 +
 53.3497 +        public Object[] toArray() {
 53.3498 +            final Object[] a = new Object[n];
 53.3499 +            if (element != null)
 53.3500 +                Arrays.fill(a, 0, n, element);
 53.3501 +            return a;
 53.3502 +        }
 53.3503 +
 53.3504 +        public <T> T[] toArray(T[] a) {
 53.3505 +            final int n = this.n;
 53.3506 +            if (a.length < n) {
 53.3507 +                a = (T[])java.lang.reflect.Array
 53.3508 +                    .newInstance(a.getClass().getComponentType(), n);
 53.3509 +                if (element != null)
 53.3510 +                    Arrays.fill(a, 0, n, element);
 53.3511 +            } else {
 53.3512 +                Arrays.fill(a, 0, n, element);
 53.3513 +                if (a.length > n)
 53.3514 +                    a[n] = null;
 53.3515 +            }
 53.3516 +            return a;
 53.3517 +        }
 53.3518 +
 53.3519 +        public List<E> subList(int fromIndex, int toIndex) {
 53.3520 +            if (fromIndex < 0)
 53.3521 +                throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
 53.3522 +            if (toIndex > n)
 53.3523 +                throw new IndexOutOfBoundsException("toIndex = " + toIndex);
 53.3524 +            if (fromIndex > toIndex)
 53.3525 +                throw new IllegalArgumentException("fromIndex(" + fromIndex +
 53.3526 +                                                   ") > toIndex(" + toIndex + ")");
 53.3527 +            return new CopiesList<>(toIndex - fromIndex, element);
 53.3528 +        }
 53.3529 +    }
 53.3530 +
 53.3531 +    /**
 53.3532 +     * Returns a comparator that imposes the reverse of the <em>natural
 53.3533 +     * ordering</em> on a collection of objects that implement the
 53.3534 +     * {@code Comparable} interface.  (The natural ordering is the ordering
 53.3535 +     * imposed by the objects' own {@code compareTo} method.)  This enables a
 53.3536 +     * simple idiom for sorting (or maintaining) collections (or arrays) of
 53.3537 +     * objects that implement the {@code Comparable} interface in
 53.3538 +     * reverse-natural-order.  For example, suppose {@code a} is an array of
 53.3539 +     * strings. Then: <pre>
 53.3540 +     *          Arrays.sort(a, Collections.reverseOrder());
 53.3541 +     * </pre> sorts the array in reverse-lexicographic (alphabetical) order.<p>
 53.3542 +     *
 53.3543 +     * The returned comparator is serializable.
 53.3544 +     *
 53.3545 +     * @return A comparator that imposes the reverse of the <i>natural
 53.3546 +     *         ordering</i> on a collection of objects that implement
 53.3547 +     *         the <tt>Comparable</tt> interface.
 53.3548 +     * @see Comparable
 53.3549 +     */
 53.3550 +    public static <T> Comparator<T> reverseOrder() {
 53.3551 +        return (Comparator<T>) ReverseComparator.REVERSE_ORDER;
 53.3552 +    }
 53.3553 +
 53.3554 +    /**
 53.3555 +     * @serial include
 53.3556 +     */
 53.3557 +    private static class ReverseComparator
 53.3558 +        implements Comparator<Comparable<Object>>, Serializable {
 53.3559 +
 53.3560 +        private static final long serialVersionUID = 7207038068494060240L;
 53.3561 +
 53.3562 +        static final ReverseComparator REVERSE_ORDER
 53.3563 +            = new ReverseComparator();
 53.3564 +
 53.3565 +        public int compare(Comparable<Object> c1, Comparable<Object> c2) {
 53.3566 +            return c2.compareTo(c1);
 53.3567 +        }
 53.3568 +
 53.3569 +        private Object readResolve() { return reverseOrder(); }
 53.3570 +    }
 53.3571 +
 53.3572 +    /**
 53.3573 +     * Returns a comparator that imposes the reverse ordering of the specified
 53.3574 +     * comparator.  If the specified comparator is {@code null}, this method is
 53.3575 +     * equivalent to {@link #reverseOrder()} (in other words, it returns a
 53.3576 +     * comparator that imposes the reverse of the <em>natural ordering</em> on
 53.3577 +     * a collection of objects that implement the Comparable interface).
 53.3578 +     *
 53.3579 +     * <p>The returned comparator is serializable (assuming the specified
 53.3580 +     * comparator is also serializable or {@code null}).
 53.3581 +     *
 53.3582 +     * @param cmp a comparator who's ordering is to be reversed by the returned
 53.3583 +     * comparator or {@code null}
 53.3584 +     * @return A comparator that imposes the reverse ordering of the
 53.3585 +     *         specified comparator.
 53.3586 +     * @since 1.5
 53.3587 +     */
 53.3588 +    public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {
 53.3589 +        if (cmp == null)
 53.3590 +            return reverseOrder();
 53.3591 +
 53.3592 +        if (cmp instanceof ReverseComparator2)
 53.3593 +            return ((ReverseComparator2<T>)cmp).cmp;
 53.3594 +
 53.3595 +        return new ReverseComparator2<>(cmp);
 53.3596 +    }
 53.3597 +
 53.3598 +    /**
 53.3599 +     * @serial include
 53.3600 +     */
 53.3601 +    private static class ReverseComparator2<T> implements Comparator<T>,
 53.3602 +        Serializable
 53.3603 +    {
 53.3604 +        private static final long serialVersionUID = 4374092139857L;
 53.3605 +
 53.3606 +        /**
 53.3607 +         * The comparator specified in the static factory.  This will never
 53.3608 +         * be null, as the static factory returns a ReverseComparator
 53.3609 +         * instance if its argument is null.
 53.3610 +         *
 53.3611 +         * @serial
 53.3612 +         */
 53.3613 +        final Comparator<T> cmp;
 53.3614 +
 53.3615 +        ReverseComparator2(Comparator<T> cmp) {
 53.3616 +            assert cmp != null;
 53.3617 +            this.cmp = cmp;
 53.3618 +        }
 53.3619 +
 53.3620 +        public int compare(T t1, T t2) {
 53.3621 +            return cmp.compare(t2, t1);
 53.3622 +        }
 53.3623 +
 53.3624 +        public boolean equals(Object o) {
 53.3625 +            return (o == this) ||
 53.3626 +                (o instanceof ReverseComparator2 &&
 53.3627 +                 cmp.equals(((ReverseComparator2)o).cmp));
 53.3628 +        }
 53.3629 +
 53.3630 +        public int hashCode() {
 53.3631 +            return cmp.hashCode() ^ Integer.MIN_VALUE;
 53.3632 +        }
 53.3633 +    }
 53.3634 +
 53.3635 +    /**
 53.3636 +     * Returns an enumeration over the specified collection.  This provides
 53.3637 +     * interoperability with legacy APIs that require an enumeration
 53.3638 +     * as input.
 53.3639 +     *
 53.3640 +     * @param c the collection for which an enumeration is to be returned.
 53.3641 +     * @return an enumeration over the specified collection.
 53.3642 +     * @see Enumeration
 53.3643 +     */
 53.3644 +    public static <T> Enumeration<T> enumeration(final Collection<T> c) {
 53.3645 +        return new Enumeration<T>() {
 53.3646 +            private final Iterator<T> i = c.iterator();
 53.3647 +
 53.3648 +            public boolean hasMoreElements() {
 53.3649 +                return i.hasNext();
 53.3650 +            }
 53.3651 +
 53.3652 +            public T nextElement() {
 53.3653 +                return i.next();
 53.3654 +            }
 53.3655 +        };
 53.3656 +    }
 53.3657 +
 53.3658 +    /**
 53.3659 +     * Returns an array list containing the elements returned by the
 53.3660 +     * specified enumeration in the order they are returned by the
 53.3661 +     * enumeration.  This method provides interoperability between
 53.3662 +     * legacy APIs that return enumerations and new APIs that require
 53.3663 +     * collections.
 53.3664 +     *
 53.3665 +     * @param e enumeration providing elements for the returned
 53.3666 +     *          array list
 53.3667 +     * @return an array list containing the elements returned
 53.3668 +     *         by the specified enumeration.
 53.3669 +     * @since 1.4
 53.3670 +     * @see Enumeration
 53.3671 +     * @see ArrayList
 53.3672 +     */
 53.3673 +    public static <T> ArrayList<T> list(Enumeration<T> e) {
 53.3674 +        ArrayList<T> l = new ArrayList<>();
 53.3675 +        while (e.hasMoreElements())
 53.3676 +            l.add(e.nextElement());
 53.3677 +        return l;
 53.3678 +    }
 53.3679 +
 53.3680 +    /**
 53.3681 +     * Returns true if the specified arguments are equal, or both null.
 53.3682 +     */
 53.3683 +    static boolean eq(Object o1, Object o2) {
 53.3684 +        return o1==null ? o2==null : o1.equals(o2);
 53.3685 +    }
 53.3686 +
 53.3687 +    /**
 53.3688 +     * Returns the number of elements in the specified collection equal to the
 53.3689 +     * specified object.  More formally, returns the number of elements
 53.3690 +     * <tt>e</tt> in the collection such that
 53.3691 +     * <tt>(o == null ? e == null : o.equals(e))</tt>.
 53.3692 +     *
 53.3693 +     * @param c the collection in which to determine the frequency
 53.3694 +     *     of <tt>o</tt>
 53.3695 +     * @param o the object whose frequency is to be determined
 53.3696 +     * @throws NullPointerException if <tt>c</tt> is null
 53.3697 +     * @since 1.5
 53.3698 +     */
 53.3699 +    public static int frequency(Collection<?> c, Object o) {
 53.3700 +        int result = 0;
 53.3701 +        if (o == null) {
 53.3702 +            for (Object e : c)
 53.3703 +                if (e == null)
 53.3704 +                    result++;
 53.3705 +        } else {
 53.3706 +            for (Object e : c)
 53.3707 +                if (o.equals(e))
 53.3708 +                    result++;
 53.3709 +        }
 53.3710 +        return result;
 53.3711 +    }
 53.3712 +
 53.3713 +    /**
 53.3714 +     * Returns {@code true} if the two specified collections have no
 53.3715 +     * elements in common.
 53.3716 +     *
 53.3717 +     * <p>Care must be exercised if this method is used on collections that
 53.3718 +     * do not comply with the general contract for {@code Collection}.
 53.3719 +     * Implementations may elect to iterate over either collection and test
 53.3720 +     * for containment in the other collection (or to perform any equivalent
 53.3721 +     * computation).  If either collection uses a nonstandard equality test
 53.3722 +     * (as does a {@link SortedSet} whose ordering is not <em>compatible with
 53.3723 +     * equals</em>, or the key set of an {@link IdentityHashMap}), both
 53.3724 +     * collections must use the same nonstandard equality test, or the
 53.3725 +     * result of this method is undefined.
 53.3726 +     *
 53.3727 +     * <p>Care must also be exercised when using collections that have
 53.3728 +     * restrictions on the elements that they may contain. Collection
 53.3729 +     * implementations are allowed to throw exceptions for any operation
 53.3730 +     * involving elements they deem ineligible. For absolute safety the
 53.3731 +     * specified collections should contain only elements which are
 53.3732 +     * eligible elements for both collections.
 53.3733 +     *
 53.3734 +     * <p>Note that it is permissible to pass the same collection in both
 53.3735 +     * parameters, in which case the method will return {@code true} if and
 53.3736 +     * only if the collection is empty.
 53.3737 +     *
 53.3738 +     * @param c1 a collection
 53.3739 +     * @param c2 a collection
 53.3740 +     * @return {@code true} if the two specified collections have no
 53.3741 +     * elements in common.
 53.3742 +     * @throws NullPointerException if either collection is {@code null}.
 53.3743 +     * @throws NullPointerException if one collection contains a {@code null}
 53.3744 +     * element and {@code null} is not an eligible element for the other collection.
 53.3745 +     * (<a href="Collection.html#optional-restrictions">optional</a>)
 53.3746 +     * @throws ClassCastException if one collection contains an element that is
 53.3747 +     * of a type which is ineligible for the other collection.
 53.3748 +     * (<a href="Collection.html#optional-restrictions">optional</a>)
 53.3749 +     * @since 1.5
 53.3750 +     */
 53.3751 +    public static boolean disjoint(Collection<?> c1, Collection<?> c2) {
 53.3752 +        // The collection to be used for contains(). Preference is given to
 53.3753 +        // the collection who's contains() has lower O() complexity.
 53.3754 +        Collection<?> contains = c2;
 53.3755 +        // The collection to be iterated. If the collections' contains() impl
 53.3756 +        // are of different O() complexity, the collection with slower
 53.3757 +        // contains() will be used for iteration. For collections who's
 53.3758 +        // contains() are of the same complexity then best performance is
 53.3759 +        // achieved by iterating the smaller collection.
 53.3760 +        Collection<?> iterate = c1;
 53.3761 +
 53.3762 +        // Performance optimization cases. The heuristics:
 53.3763 +        //   1. Generally iterate over c1.
 53.3764 +        //   2. If c1 is a Set then iterate over c2.
 53.3765 +        //   3. If either collection is empty then result is always true.
 53.3766 +        //   4. Iterate over the smaller Collection.
 53.3767 +        if (c1 instanceof Set) {
 53.3768 +            // Use c1 for contains as a Set's contains() is expected to perform
 53.3769 +            // better than O(N/2)
 53.3770 +            iterate = c2;
 53.3771 +            contains = c1;
 53.3772 +        } else if (!(c2 instanceof Set)) {
 53.3773 +            // Both are mere Collections. Iterate over smaller collection.
 53.3774 +            // Example: If c1 contains 3 elements and c2 contains 50 elements and
 53.3775 +            // assuming contains() requires ceiling(N/2) comparisons then
 53.3776 +            // checking for all c1 elements in c2 would require 75 comparisons
 53.3777 +            // (3 * ceiling(50/2)) vs. checking all c2 elements in c1 requiring
 53.3778 +            // 100 comparisons (50 * ceiling(3/2)).
 53.3779 +            int c1size = c1.size();
 53.3780 +            int c2size = c2.size();
 53.3781 +            if (c1size == 0 || c2size == 0) {
 53.3782 +                // At least one collection is empty. Nothing will match.
 53.3783 +                return true;
 53.3784 +            }
 53.3785 +
 53.3786 +            if (c1size > c2size) {
 53.3787 +                iterate = c2;
 53.3788 +                contains = c1;
 53.3789 +            }
 53.3790 +        }
 53.3791 +
 53.3792 +        for (Object e : iterate) {
 53.3793 +            if (contains.contains(e)) {
 53.3794 +               // Found a common element. Collections are not disjoint.
 53.3795 +                return false;
 53.3796 +            }
 53.3797 +        }
 53.3798 +
 53.3799 +        // No common elements were found.
 53.3800 +        return true;
 53.3801 +    }
 53.3802 +
 53.3803 +    /**
 53.3804 +     * Adds all of the specified elements to the specified collection.
 53.3805 +     * Elements to be added may be specified individually or as an array.
 53.3806 +     * The behavior of this convenience method is identical to that of
 53.3807 +     * <tt>c.addAll(Arrays.asList(elements))</tt>, but this method is likely
 53.3808 +     * to run significantly faster under most implementations.
 53.3809 +     *
 53.3810 +     * <p>When elements are specified individually, this method provides a
 53.3811 +     * convenient way to add a few elements to an existing collection:
 53.3812 +     * <pre>
 53.3813 +     *     Collections.addAll(flavors, "Peaches 'n Plutonium", "Rocky Racoon");
 53.3814 +     * </pre>
 53.3815 +     *
 53.3816 +     * @param c the collection into which <tt>elements</tt> are to be inserted
 53.3817 +     * @param elements the elements to insert into <tt>c</tt>
 53.3818 +     * @return <tt>true</tt> if the collection changed as a result of the call
 53.3819 +     * @throws UnsupportedOperationException if <tt>c</tt> does not support
 53.3820 +     *         the <tt>add</tt> operation
 53.3821 +     * @throws NullPointerException if <tt>elements</tt> contains one or more
 53.3822 +     *         null values and <tt>c</tt> does not permit null elements, or
 53.3823 +     *         if <tt>c</tt> or <tt>elements</tt> are <tt>null</tt>
 53.3824 +     * @throws IllegalArgumentException if some property of a value in
 53.3825 +     *         <tt>elements</tt> prevents it from being added to <tt>c</tt>
 53.3826 +     * @see Collection#addAll(Collection)
 53.3827 +     * @since 1.5
 53.3828 +     */
 53.3829 +    @SafeVarargs
 53.3830 +    public static <T> boolean addAll(Collection<? super T> c, T... elements) {
 53.3831 +        boolean result = false;
 53.3832 +        for (T element : elements)
 53.3833 +            result |= c.add(element);
 53.3834 +        return result;
 53.3835 +    }
 53.3836 +
 53.3837 +    /**
 53.3838 +     * Returns a set backed by the specified map.  The resulting set displays
 53.3839 +     * the same ordering, concurrency, and performance characteristics as the
 53.3840 +     * backing map.  In essence, this factory method provides a {@link Set}
 53.3841 +     * implementation corresponding to any {@link Map} implementation.  There
 53.3842 +     * is no need to use this method on a {@link Map} implementation that
 53.3843 +     * already has a corresponding {@link Set} implementation (such as {@link
 53.3844 +     * HashMap} or {@link TreeMap}).
 53.3845 +     *
 53.3846 +     * <p>Each method invocation on the set returned by this method results in
 53.3847 +     * exactly one method invocation on the backing map or its <tt>keySet</tt>
 53.3848 +     * view, with one exception.  The <tt>addAll</tt> method is implemented
 53.3849 +     * as a sequence of <tt>put</tt> invocations on the backing map.
 53.3850 +     *
 53.3851 +     * <p>The specified map must be empty at the time this method is invoked,
 53.3852 +     * and should not be accessed directly after this method returns.  These
 53.3853 +     * conditions are ensured if the map is created empty, passed directly
 53.3854 +     * to this method, and no reference to the map is retained, as illustrated
 53.3855 +     * in the following code fragment:
 53.3856 +     * <pre>
 53.3857 +     *    Set&lt;Object&gt; weakHashSet = Collections.newSetFromMap(
 53.3858 +     *        new WeakHashMap&lt;Object, Boolean&gt;());
 53.3859 +     * </pre>
 53.3860 +     *
 53.3861 +     * @param map the backing map
 53.3862 +     * @return the set backed by the map
 53.3863 +     * @throws IllegalArgumentException if <tt>map</tt> is not empty
 53.3864 +     * @since 1.6
 53.3865 +     */
 53.3866 +    public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) {
 53.3867 +        return new SetFromMap<>(map);
 53.3868 +    }
 53.3869 +
 53.3870 +    /**
 53.3871 +     * @serial include
 53.3872 +     */
 53.3873 +    private static class SetFromMap<E> extends AbstractSet<E>
 53.3874 +        implements Set<E>, Serializable
 53.3875 +    {
 53.3876 +        private final Map<E, Boolean> m;  // The backing map
 53.3877 +        private transient Set<E> s;       // Its keySet
 53.3878 +
 53.3879 +        SetFromMap(Map<E, Boolean> map) {
 53.3880 +            if (!map.isEmpty())
 53.3881 +                throw new IllegalArgumentException("Map is non-empty");
 53.3882 +            m = map;
 53.3883 +            s = map.keySet();
 53.3884 +        }
 53.3885 +
 53.3886 +        public void clear()               {        m.clear(); }
 53.3887 +        public int size()                 { return m.size(); }
 53.3888 +        public boolean isEmpty()          { return m.isEmpty(); }
 53.3889 +        public boolean contains(Object o) { return m.containsKey(o); }
 53.3890 +        public boolean remove(Object o)   { return m.remove(o) != null; }
 53.3891 +        public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; }
 53.3892 +        public Iterator<E> iterator()     { return s.iterator(); }
 53.3893 +        public Object[] toArray()         { return s.toArray(); }
 53.3894 +        public <T> T[] toArray(T[] a)     { return s.toArray(a); }
 53.3895 +        public String toString()          { return s.toString(); }
 53.3896 +        public int hashCode()             { return s.hashCode(); }
 53.3897 +        public boolean equals(Object o)   { return o == this || s.equals(o); }
 53.3898 +        public boolean containsAll(Collection<?> c) {return s.containsAll(c);}
 53.3899 +        public boolean removeAll(Collection<?> c)   {return s.removeAll(c);}
 53.3900 +        public boolean retainAll(Collection<?> c)   {return s.retainAll(c);}
 53.3901 +        // addAll is the only inherited implementation
 53.3902 +
 53.3903 +        private static final long serialVersionUID = 2454657854757543876L;
 53.3904 +
 53.3905 +    }
 53.3906 +
 53.3907 +    /**
 53.3908 +     * Returns a view of a {@link Deque} as a Last-in-first-out (Lifo)
 53.3909 +     * {@link Queue}. Method <tt>add</tt> is mapped to <tt>push</tt>,
 53.3910 +     * <tt>remove</tt> is mapped to <tt>pop</tt> and so on. This
 53.3911 +     * view can be useful when you would like to use a method
 53.3912 +     * requiring a <tt>Queue</tt> but you need Lifo ordering.
 53.3913 +     *
 53.3914 +     * <p>Each method invocation on the queue returned by this method
 53.3915 +     * results in exactly one method invocation on the backing deque, with
 53.3916 +     * one exception.  The {@link Queue#addAll addAll} method is
 53.3917 +     * implemented as a sequence of {@link Deque#addFirst addFirst}
 53.3918 +     * invocations on the backing deque.
 53.3919 +     *
 53.3920 +     * @param deque the deque
 53.3921 +     * @return the queue
 53.3922 +     * @since  1.6
 53.3923 +     */
 53.3924 +    public static <T> Queue<T> asLifoQueue(Deque<T> deque) {
 53.3925 +        return new AsLIFOQueue<>(deque);
 53.3926 +    }
 53.3927 +
 53.3928 +    /**
 53.3929 +     * @serial include
 53.3930 +     */
 53.3931 +    static class AsLIFOQueue<E> extends AbstractQueue<E>
 53.3932 +        implements Queue<E>, Serializable {
 53.3933 +        private static final long serialVersionUID = 1802017725587941708L;
 53.3934 +        private final Deque<E> q;
 53.3935 +        AsLIFOQueue(Deque<E> q)           { this.q = q; }
 53.3936 +        public boolean add(E e)           { q.addFirst(e); return true; }
 53.3937 +        public boolean offer(E e)         { return q.offerFirst(e); }
 53.3938 +        public E poll()                   { return q.pollFirst(); }
 53.3939 +        public E remove()                 { return q.removeFirst(); }
 53.3940 +        public E peek()                   { return q.peekFirst(); }
 53.3941 +        public E element()                { return q.getFirst(); }
 53.3942 +        public void clear()               {        q.clear(); }
 53.3943 +        public int size()                 { return q.size(); }
 53.3944 +        public boolean isEmpty()          { return q.isEmpty(); }
 53.3945 +        public boolean contains(Object o) { return q.contains(o); }
 53.3946 +        public boolean remove(Object o)   { return q.remove(o); }
 53.3947 +        public Iterator<E> iterator()     { return q.iterator(); }
 53.3948 +        public Object[] toArray()         { return q.toArray(); }
 53.3949 +        public <T> T[] toArray(T[] a)     { return q.toArray(a); }
 53.3950 +        public String toString()          { return q.toString(); }
 53.3951 +        public boolean containsAll(Collection<?> c) {return q.containsAll(c);}
 53.3952 +        public boolean removeAll(Collection<?> c)   {return q.removeAll(c);}
 53.3953 +        public boolean retainAll(Collection<?> c)   {return q.retainAll(c);}
 53.3954 +        // We use inherited addAll; forwarding addAll would be wrong
 53.3955 +    }
 53.3956 +}
    54.1 --- a/emul/compact/src/main/java/java/util/ComparableTimSort.java	Tue Feb 05 16:40:01 2013 +0100
    54.2 +++ b/emul/compact/src/main/java/java/util/ComparableTimSort.java	Tue Feb 05 17:04:22 2013 +0100
    54.3 @@ -25,7 +25,6 @@
    54.4  
    54.5  package java.util;
    54.6  
    54.7 -import org.apidesign.bck2brwsr.emul.lang.System;
    54.8  
    54.9  /**
   54.10   * This is a near duplicate of {@link TimSort}, modified for use with
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/emul/compact/src/main/java/java/util/Deque.java	Tue Feb 05 17:04:22 2013 +0100
    55.3 @@ -0,0 +1,584 @@
    55.4 +/*
    55.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    55.6 + *
    55.7 + * This code is free software; you can redistribute it and/or modify it
    55.8 + * under the terms of the GNU General Public License version 2 only, as
    55.9 + * published by the Free Software Foundation.  Oracle designates this
   55.10 + * particular file as subject to the "Classpath" exception as provided
   55.11 + * by Oracle in the LICENSE file that accompanied this code.
   55.12 + *
   55.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
   55.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   55.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   55.16 + * version 2 for more details (a copy is included in the LICENSE file that
   55.17 + * accompanied this code).
   55.18 + *
   55.19 + * You should have received a copy of the GNU General Public License version
   55.20 + * 2 along with this work; if not, write to the Free Software Foundation,
   55.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   55.22 + *
   55.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   55.24 + * or visit www.oracle.com if you need additional information or have any
   55.25 + * questions.
   55.26 + */
   55.27 +
   55.28 +/*
   55.29 + * This file is available under and governed by the GNU General Public
   55.30 + * License version 2 only, as published by the Free Software Foundation.
   55.31 + * However, the following notice accompanied the original version of this
   55.32 + * file:
   55.33 + *
   55.34 + * Written by Doug Lea and Josh Bloch with assistance from members of
   55.35 + * JCP JSR-166 Expert Group and released to the public domain, as explained
   55.36 + * at http://creativecommons.org/publicdomain/zero/1.0/
   55.37 + */
   55.38 +
   55.39 +package java.util;
   55.40 +
   55.41 +/**
   55.42 + * A linear collection that supports element insertion and removal at
   55.43 + * both ends.  The name <i>deque</i> is short for "double ended queue"
   55.44 + * and is usually pronounced "deck".  Most <tt>Deque</tt>
   55.45 + * implementations place no fixed limits on the number of elements
   55.46 + * they may contain, but this interface supports capacity-restricted
   55.47 + * deques as well as those with no fixed size limit.
   55.48 + *
   55.49 + * <p>This interface defines methods to access the elements at both
   55.50 + * ends of the deque.  Methods are provided to insert, remove, and
   55.51 + * examine the element.  Each of these methods exists in two forms:
   55.52 + * one throws an exception if the operation fails, the other returns a
   55.53 + * special value (either <tt>null</tt> or <tt>false</tt>, depending on
   55.54 + * the operation).  The latter form of the insert operation is
   55.55 + * designed specifically for use with capacity-restricted
   55.56 + * <tt>Deque</tt> implementations; in most implementations, insert
   55.57 + * operations cannot fail.
   55.58 + *
   55.59 + * <p>The twelve methods described above are summarized in the
   55.60 + * following table:
   55.61 + *
   55.62 + * <p>
   55.63 + * <table BORDER CELLPADDING=3 CELLSPACING=1>
   55.64 + *  <tr>
   55.65 + *    <td></td>
   55.66 + *    <td ALIGN=CENTER COLSPAN = 2> <b>First Element (Head)</b></td>
   55.67 + *    <td ALIGN=CENTER COLSPAN = 2> <b>Last Element (Tail)</b></td>
   55.68 + *  </tr>
   55.69 + *  <tr>
   55.70 + *    <td></td>
   55.71 + *    <td ALIGN=CENTER><em>Throws exception</em></td>
   55.72 + *    <td ALIGN=CENTER><em>Special value</em></td>
   55.73 + *    <td ALIGN=CENTER><em>Throws exception</em></td>
   55.74 + *    <td ALIGN=CENTER><em>Special value</em></td>
   55.75 + *  </tr>
   55.76 + *  <tr>
   55.77 + *    <td><b>Insert</b></td>
   55.78 + *    <td>{@link #addFirst addFirst(e)}</td>
   55.79 + *    <td>{@link #offerFirst offerFirst(e)}</td>
   55.80 + *    <td>{@link #addLast addLast(e)}</td>
   55.81 + *    <td>{@link #offerLast offerLast(e)}</td>
   55.82 + *  </tr>
   55.83 + *  <tr>
   55.84 + *    <td><b>Remove</b></td>
   55.85 + *    <td>{@link #removeFirst removeFirst()}</td>
   55.86 + *    <td>{@link #pollFirst pollFirst()}</td>
   55.87 + *    <td>{@link #removeLast removeLast()}</td>
   55.88 + *    <td>{@link #pollLast pollLast()}</td>
   55.89 + *  </tr>
   55.90 + *  <tr>
   55.91 + *    <td><b>Examine</b></td>
   55.92 + *    <td>{@link #getFirst getFirst()}</td>
   55.93 + *    <td>{@link #peekFirst peekFirst()}</td>
   55.94 + *    <td>{@link #getLast getLast()}</td>
   55.95 + *    <td>{@link #peekLast peekLast()}</td>
   55.96 + *  </tr>
   55.97 + * </table>
   55.98 + *
   55.99 + * <p>This interface extends the {@link Queue} interface.  When a deque is
  55.100 + * used as a queue, FIFO (First-In-First-Out) behavior results.  Elements are
  55.101 + * added at the end of the deque and removed from the beginning.  The methods
  55.102 + * inherited from the <tt>Queue</tt> interface are precisely equivalent to
  55.103 + * <tt>Deque</tt> methods as indicated in the following table:
  55.104 + *
  55.105 + * <p>
  55.106 + * <table BORDER CELLPADDING=3 CELLSPACING=1>
  55.107 + *  <tr>
  55.108 + *    <td ALIGN=CENTER> <b><tt>Queue</tt> Method</b></td>
  55.109 + *    <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td>
  55.110 + *  </tr>
  55.111 + *  <tr>
  55.112 + *    <td>{@link java.util.Queue#add add(e)}</td>
  55.113 + *    <td>{@link #addLast addLast(e)}</td>
  55.114 + *  </tr>
  55.115 + *  <tr>
  55.116 + *    <td>{@link java.util.Queue#offer offer(e)}</td>
  55.117 + *    <td>{@link #offerLast offerLast(e)}</td>
  55.118 + *  </tr>
  55.119 + *  <tr>
  55.120 + *    <td>{@link java.util.Queue#remove remove()}</td>
  55.121 + *    <td>{@link #removeFirst removeFirst()}</td>
  55.122 + *  </tr>
  55.123 + *  <tr>
  55.124 + *    <td>{@link java.util.Queue#poll poll()}</td>
  55.125 + *    <td>{@link #pollFirst pollFirst()}</td>
  55.126 + *  </tr>
  55.127 + *  <tr>
  55.128 + *    <td>{@link java.util.Queue#element element()}</td>
  55.129 + *    <td>{@link #getFirst getFirst()}</td>
  55.130 + *  </tr>
  55.131 + *  <tr>
  55.132 + *    <td>{@link java.util.Queue#peek peek()}</td>
  55.133 + *    <td>{@link #peek peekFirst()}</td>
  55.134 + *  </tr>
  55.135 + * </table>
  55.136 + *
  55.137 + * <p>Deques can also be used as LIFO (Last-In-First-Out) stacks.  This
  55.138 + * interface should be used in preference to the legacy {@link Stack} class.
  55.139 + * When a deque is used as a stack, elements are pushed and popped from the
  55.140 + * beginning of the deque.  Stack methods are precisely equivalent to
  55.141 + * <tt>Deque</tt> methods as indicated in the table below:
  55.142 + *
  55.143 + * <p>
  55.144 + * <table BORDER CELLPADDING=3 CELLSPACING=1>
  55.145 + *  <tr>
  55.146 + *    <td ALIGN=CENTER> <b>Stack Method</b></td>
  55.147 + *    <td ALIGN=CENTER> <b>Equivalent <tt>Deque</tt> Method</b></td>
  55.148 + *  </tr>
  55.149 + *  <tr>
  55.150 + *    <td>{@link #push push(e)}</td>
  55.151 + *    <td>{@link #addFirst addFirst(e)}</td>
  55.152 + *  </tr>
  55.153 + *  <tr>
  55.154 + *    <td>{@link #pop pop()}</td>
  55.155 + *    <td>{@link #removeFirst removeFirst()}</td>
  55.156 + *  </tr>
  55.157 + *  <tr>
  55.158 + *    <td>{@link #peek peek()}</td>
  55.159 + *    <td>{@link #peekFirst peekFirst()}</td>
  55.160 + *  </tr>
  55.161 + * </table>
  55.162 + *
  55.163 + * <p>Note that the {@link #peek peek} method works equally well when
  55.164 + * a deque is used as a queue or a stack; in either case, elements are
  55.165 + * drawn from the beginning of the deque.
  55.166 + *
  55.167 + * <p>This interface provides two methods to remove interior
  55.168 + * elements, {@link #removeFirstOccurrence removeFirstOccurrence} and
  55.169 + * {@link #removeLastOccurrence removeLastOccurrence}.
  55.170 + *
  55.171 + * <p>Unlike the {@link List} interface, this interface does not
  55.172 + * provide support for indexed access to elements.
  55.173 + *
  55.174 + * <p>While <tt>Deque</tt> implementations are not strictly required
  55.175 + * to prohibit the insertion of null elements, they are strongly
  55.176 + * encouraged to do so.  Users of any <tt>Deque</tt> implementations
  55.177 + * that do allow null elements are strongly encouraged <i>not</i> to
  55.178 + * take advantage of the ability to insert nulls.  This is so because
  55.179 + * <tt>null</tt> is used as a special return value by various methods
  55.180 + * to indicated that the deque is empty.
  55.181 + *
  55.182 + * <p><tt>Deque</tt> implementations generally do not define
  55.183 + * element-based versions of the <tt>equals</tt> and <tt>hashCode</tt>
  55.184 + * methods, but instead inherit the identity-based versions from class
  55.185 + * <tt>Object</tt>.
  55.186 + *
  55.187 + * <p>This interface is a member of the <a
  55.188 + * href="{@docRoot}/../technotes/guides/collections/index.html"> Java Collections
  55.189 + * Framework</a>.
  55.190 + *
  55.191 + * @author Doug Lea
  55.192 + * @author Josh Bloch
  55.193 + * @since  1.6
  55.194 + * @param <E> the type of elements held in this collection
  55.195 + */
  55.196 +
  55.197 +public interface Deque<E> extends Queue<E> {
  55.198 +    /**
  55.199 +     * Inserts the specified element at the front of this deque if it is
  55.200 +     * possible to do so immediately without violating capacity restrictions.
  55.201 +     * When using a capacity-restricted deque, it is generally preferable to
  55.202 +     * use method {@link #offerFirst}.
  55.203 +     *
  55.204 +     * @param e the element to add
  55.205 +     * @throws IllegalStateException if the element cannot be added at this
  55.206 +     *         time due to capacity restrictions
  55.207 +     * @throws ClassCastException if the class of the specified element
  55.208 +     *         prevents it from being added to this deque
  55.209 +     * @throws NullPointerException if the specified element is null and this
  55.210 +     *         deque does not permit null elements
  55.211 +     * @throws IllegalArgumentException if some property of the specified
  55.212 +     *         element prevents it from being added to this deque
  55.213 +     */
  55.214 +    void addFirst(E e);
  55.215 +
  55.216 +    /**
  55.217 +     * Inserts the specified element at the end of this deque if it is
  55.218 +     * possible to do so immediately without violating capacity restrictions.
  55.219 +     * When using a capacity-restricted deque, it is generally preferable to
  55.220 +     * use method {@link #offerLast}.
  55.221 +     *
  55.222 +     * <p>This method is equivalent to {@link #add}.
  55.223 +     *
  55.224 +     * @param e the element to add
  55.225 +     * @throws IllegalStateException if the element cannot be added at this
  55.226 +     *         time due to capacity restrictions
  55.227 +     * @throws ClassCastException if the class of the specified element
  55.228 +     *         prevents it from being added to this deque
  55.229 +     * @throws NullPointerException if the specified element is null and this
  55.230 +     *         deque does not permit null elements
  55.231 +     * @throws IllegalArgumentException if some property of the specified
  55.232 +     *         element prevents it from being added to this deque
  55.233 +     */
  55.234 +    void addLast(E e);
  55.235 +
  55.236 +    /**
  55.237 +     * Inserts the specified element at the front of this deque unless it would
  55.238 +     * violate capacity restrictions.  When using a capacity-restricted deque,
  55.239 +     * this method is generally preferable to the {@link #addFirst} method,
  55.240 +     * which can fail to insert an element only by throwing an exception.
  55.241 +     *
  55.242 +     * @param e the element to add
  55.243 +     * @return <tt>true</tt> if the element was added to this deque, else
  55.244 +     *         <tt>false</tt>
  55.245 +     * @throws ClassCastException if the class of the specified element
  55.246 +     *         prevents it from being added to this deque
  55.247 +     * @throws NullPointerException if the specified element is null and this
  55.248 +     *         deque does not permit null elements
  55.249 +     * @throws IllegalArgumentException if some property of the specified
  55.250 +     *         element prevents it from being added to this deque
  55.251 +     */
  55.252 +    boolean offerFirst(E e);
  55.253 +
  55.254 +    /**
  55.255 +     * Inserts the specified element at the end of this deque unless it would
  55.256 +     * violate capacity restrictions.  When using a capacity-restricted deque,
  55.257 +     * this method is generally preferable to the {@link #addLast} method,
  55.258 +     * which can fail to insert an element only by throwing an exception.
  55.259 +     *
  55.260 +     * @param e the element to add
  55.261 +     * @return <tt>true</tt> if the element was added to this deque, else
  55.262 +     *         <tt>false</tt>
  55.263 +     * @throws ClassCastException if the class of the specified element
  55.264 +     *         prevents it from being added to this deque
  55.265 +     * @throws NullPointerException if the specified element is null and this
  55.266 +     *         deque does not permit null elements
  55.267 +     * @throws IllegalArgumentException if some property of the specified
  55.268 +     *         element prevents it from being added to this deque
  55.269 +     */
  55.270 +    boolean offerLast(E e);
  55.271 +
  55.272 +    /**
  55.273 +     * Retrieves and removes the first element of this deque.  This method
  55.274 +     * differs from {@link #pollFirst pollFirst} only in that it throws an
  55.275 +     * exception if this deque is empty.
  55.276 +     *
  55.277 +     * @return the head of this deque
  55.278 +     * @throws NoSuchElementException if this deque is empty
  55.279 +     */
  55.280 +    E removeFirst();
  55.281 +
  55.282 +    /**
  55.283 +     * Retrieves and removes the last element of this deque.  This method
  55.284 +     * differs from {@link #pollLast pollLast} only in that it throws an
  55.285 +     * exception if this deque is empty.
  55.286 +     *
  55.287 +     * @return the tail of this deque
  55.288 +     * @throws NoSuchElementException if this deque is empty
  55.289 +     */
  55.290 +    E removeLast();
  55.291 +
  55.292 +    /**
  55.293 +     * Retrieves and removes the first element of this deque,
  55.294 +     * or returns <tt>null</tt> if this deque is empty.
  55.295 +     *
  55.296 +     * @return the head of this deque, or <tt>null</tt> if this deque is empty
  55.297 +     */
  55.298 +    E pollFirst();
  55.299 +
  55.300 +    /**
  55.301 +     * Retrieves and removes the last element of this deque,
  55.302 +     * or returns <tt>null</tt> if this deque is empty.
  55.303 +     *
  55.304 +     * @return the tail of this deque, or <tt>null</tt> if this deque is empty
  55.305 +     */
  55.306 +    E pollLast();
  55.307 +
  55.308 +    /**
  55.309 +     * Retrieves, but does not remove, the first element of this deque.
  55.310 +     *
  55.311 +     * This method differs from {@link #peekFirst peekFirst} only in that it
  55.312 +     * throws an exception if this deque is empty.
  55.313 +     *
  55.314 +     * @return the head of this deque
  55.315 +     * @throws NoSuchElementException if this deque is empty
  55.316 +     */
  55.317 +    E getFirst();
  55.318 +
  55.319 +    /**
  55.320 +     * Retrieves, but does not remove, the last element of this deque.
  55.321 +     * This method differs from {@link #peekLast peekLast} only in that it
  55.322 +     * throws an exception if this deque is empty.
  55.323 +     *
  55.324 +     * @return the tail of this deque
  55.325 +     * @throws NoSuchElementException if this deque is empty
  55.326 +     */
  55.327 +    E getLast();
  55.328 +
  55.329 +    /**
  55.330 +     * Retrieves, but does not remove, the first element of this deque,
  55.331 +     * or returns <tt>null</tt> if this deque is empty.
  55.332 +     *
  55.333 +     * @return the head of this deque, or <tt>null</tt> if this deque is empty
  55.334 +     */
  55.335 +    E peekFirst();
  55.336 +
  55.337 +    /**
  55.338 +     * Retrieves, but does not remove, the last element of this deque,
  55.339 +     * or returns <tt>null</tt> if this deque is empty.
  55.340 +     *
  55.341 +     * @return the tail of this deque, or <tt>null</tt> if this deque is empty
  55.342 +     */
  55.343 +    E peekLast();
  55.344 +
  55.345 +    /**
  55.346 +     * Removes the first occurrence of the specified element from this deque.
  55.347 +     * If the deque does not contain the element, it is unchanged.
  55.348 +     * More formally, removes the first element <tt>e</tt> such that
  55.349 +     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
  55.350 +     * (if such an element exists).
  55.351 +     * Returns <tt>true</tt> if this deque contained the specified element
  55.352 +     * (or equivalently, if this deque changed as a result of the call).
  55.353 +     *
  55.354 +     * @param o element to be removed from this deque, if present
  55.355 +     * @return <tt>true</tt> if an element was removed as a result of this call
  55.356 +     * @throws ClassCastException if the class of the specified element
  55.357 +     *         is incompatible with this deque
  55.358 +     * (<a href="Collection.html#optional-restrictions">optional</a>)
  55.359 +     * @throws NullPointerException if the specified element is null and this
  55.360 +     *         deque does not permit null elements
  55.361 +     * (<a href="Collection.html#optional-restrictions">optional</a>)
  55.362 +     */
  55.363 +    boolean removeFirstOccurrence(Object o);
  55.364 +
  55.365 +    /**
  55.366 +     * Removes the last occurrence of the specified element from this deque.
  55.367 +     * If the deque does not contain the element, it is unchanged.
  55.368 +     * More formally, removes the last element <tt>e</tt> such that
  55.369 +     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
  55.370 +     * (if such an element exists).
  55.371 +     * Returns <tt>true</tt> if this deque contained the specified element
  55.372 +     * (or equivalently, if this deque changed as a result of the call).
  55.373 +     *
  55.374 +     * @param o element to be removed from this deque, if present
  55.375 +     * @return <tt>true</tt> if an element was removed as a result of this call
  55.376 +     * @throws ClassCastException if the class of the specified element
  55.377 +     *         is incompatible with this deque
  55.378 +     * (<a href="Collection.html#optional-restrictions">optional</a>)
  55.379 +     * @throws NullPointerException if the specified element is null and this
  55.380 +     *         deque does not permit null elements
  55.381 +     * (<a href="Collection.html#optional-restrictions">optional</a>)
  55.382 +     */
  55.383 +    boolean removeLastOccurrence(Object o);
  55.384 +
  55.385 +    // *** Queue methods ***
  55.386 +
  55.387 +    /**
  55.388 +     * Inserts the specified element into the queue represented by this deque
  55.389 +     * (in other words, at the tail of this deque) if it is possible to do so
  55.390 +     * immediately without violating capacity restrictions, returning
  55.391 +     * <tt>true</tt> upon success and throwing an
  55.392 +     * <tt>IllegalStateException</tt> if no space is currently available.
  55.393 +     * When using a capacity-restricted deque, it is generally preferable to
  55.394 +     * use {@link #offer(Object) offer}.
  55.395 +     *
  55.396 +     * <p>This method is equivalent to {@link #addLast}.
  55.397 +     *
  55.398 +     * @param e the element to add
  55.399 +     * @return <tt>true</tt> (as specified by {@link Collection#add})
  55.400 +     * @throws IllegalStateException if the element cannot be added at this
  55.401 +     *         time due to capacity restrictions
  55.402 +     * @throws ClassCastException if the class of the specified element
  55.403 +     *         prevents it from being added to this deque
  55.404 +     * @throws NullPointerException if the specified element is null and this
  55.405 +     *         deque does not permit null elements
  55.406 +     * @throws IllegalArgumentException if some property of the specified
  55.407 +     *         element prevents it from being added to this deque
  55.408 +     */
  55.409 +    boolean add(E e);
  55.410 +
  55.411 +    /**
  55.412 +     * Inserts the specified element into the queue represented by this deque
  55.413 +     * (in other words, at the tail of this deque) if it is possible to do so
  55.414 +     * immediately without violating capacity restrictions, returning
  55.415 +     * <tt>true</tt> upon success and <tt>false</tt> if no space is currently
  55.416 +     * available.  When using a capacity-restricted deque, this method is
  55.417 +     * generally preferable to the {@link #add} method, which can fail to
  55.418 +     * insert an element only by throwing an exception.
  55.419 +     *
  55.420 +     * <p>This method is equivalent to {@link #offerLast}.
  55.421 +     *
  55.422 +     * @param e the element to add
  55.423 +     * @return <tt>true</tt> if the element was added to this deque, else
  55.424 +     *         <tt>false</tt>
  55.425 +     * @throws ClassCastException if the class of the specified element
  55.426 +     *         prevents it from being added to this deque
  55.427 +     * @throws NullPointerException if the specified element is null and this
  55.428 +     *         deque does not permit null elements
  55.429 +     * @throws IllegalArgumentException if some property of the specified
  55.430 +     *         element prevents it from being added to this deque
  55.431 +     */
  55.432 +    boolean offer(E e);
  55.433 +
  55.434 +    /**
  55.435 +     * Retrieves and removes the head of the queue represented by this deque
  55.436 +     * (in other words, the first element of this deque).
  55.437 +     * This method differs from {@link #poll poll} only in that it throws an
  55.438 +     * exception if this deque is empty.
  55.439 +     *
  55.440 +     * <p>This method is equivalent to {@link #removeFirst()}.
  55.441 +     *
  55.442 +     * @return the head of the queue represented by this deque
  55.443 +     * @throws NoSuchElementException if this deque is empty
  55.444 +     */
  55.445 +    E remove();
  55.446 +
  55.447 +    /**
  55.448 +     * Retrieves and removes the head of the queue represented by this deque
  55.449 +     * (in other words, the first element of this deque), or returns
  55.450 +     * <tt>null</tt> if this deque is empty.
  55.451 +     *
  55.452 +     * <p>This method is equivalent to {@link #pollFirst()}.
  55.453 +     *
  55.454 +     * @return the first element of this deque, or <tt>null</tt> if
  55.455 +     *         this deque is empty
  55.456 +     */
  55.457 +    E poll();
  55.458 +
  55.459 +    /**
  55.460 +     * Retrieves, but does not remove, the head of the queue represented by
  55.461 +     * this deque (in other words, the first element of this deque).
  55.462 +     * This method differs from {@link #peek peek} only in that it throws an
  55.463 +     * exception if this deque is empty.
  55.464 +     *
  55.465 +     * <p>This method is equivalent to {@link #getFirst()}.
  55.466 +     *
  55.467 +     * @return the head of the queue represented by this deque
  55.468 +     * @throws NoSuchElementException if this deque is empty
  55.469 +     */
  55.470 +    E element();
  55.471 +
  55.472 +    /**
  55.473 +     * Retrieves, but does not remove, the head of the queue represented by
  55.474 +     * this deque (in other words, the first element of this deque), or
  55.475 +     * returns <tt>null</tt> if this deque is empty.
  55.476 +     *
  55.477 +     * <p>This method is equivalent to {@link #peekFirst()}.
  55.478 +     *
  55.479 +     * @return the head of the queue represented by this deque, or
  55.480 +     *         <tt>null</tt> if this deque is empty
  55.481 +     */
  55.482 +    E peek();
  55.483 +
  55.484 +
  55.485 +    // *** Stack methods ***
  55.486 +
  55.487 +    /**
  55.488 +     * Pushes an element onto the stack represented by this deque (in other
  55.489 +     * words, at the head of this deque) if it is possible to do so
  55.490 +     * immediately without violating capacity restrictions, returning
  55.491 +     * <tt>true</tt> upon success and throwing an
  55.492 +     * <tt>IllegalStateException</tt> if no space is currently available.
  55.493 +     *
  55.494 +     * <p>This method is equivalent to {@link #addFirst}.
  55.495 +     *
  55.496 +     * @param e the element to push
  55.497 +     * @throws IllegalStateException if the element cannot be added at this
  55.498 +     *         time due to capacity restrictions
  55.499 +     * @throws ClassCastException if the class of the specified element
  55.500 +     *         prevents it from being added to this deque
  55.501 +     * @throws NullPointerException if the specified element is null and this
  55.502 +     *         deque does not permit null elements
  55.503 +     * @throws IllegalArgumentException if some property of the specified
  55.504 +     *         element prevents it from being added to this deque
  55.505 +     */
  55.506 +    void push(E e);
  55.507 +
  55.508 +    /**
  55.509 +     * Pops an element from the stack represented by this deque.  In other
  55.510 +     * words, removes and returns the first element of this deque.
  55.511 +     *
  55.512 +     * <p>This method is equivalent to {@link #removeFirst()}.
  55.513 +     *
  55.514 +     * @return the element at the front of this deque (which is the top
  55.515 +     *         of the stack represented by this deque)
  55.516 +     * @throws NoSuchElementException if this deque is empty
  55.517 +     */
  55.518 +    E pop();
  55.519 +
  55.520 +
  55.521 +    // *** Collection methods ***
  55.522 +
  55.523 +    /**
  55.524 +     * Removes the first occurrence of the specified element from this deque.
  55.525 +     * If the deque does not contain the element, it is unchanged.
  55.526 +     * More formally, removes the first element <tt>e</tt> such that
  55.527 +     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
  55.528 +     * (if such an element exists).
  55.529 +     * Returns <tt>true</tt> if this deque contained the specified element
  55.530 +     * (or equivalently, if this deque changed as a result of the call).
  55.531 +     *
  55.532 +     * <p>This method is equivalent to {@link #removeFirstOccurrence}.
  55.533 +     *
  55.534 +     * @param o element to be removed from this deque, if present
  55.535 +     * @return <tt>true</tt> if an element was removed as a result of this call
  55.536 +     * @throws ClassCastException if the class of the specified element
  55.537 +     *         is incompatible with this deque
  55.538 +     * (<a href="Collection.html#optional-restrictions">optional</a>)
  55.539 +     * @throws NullPointerException if the specified element is null and this
  55.540 +     *         deque does not permit null elements
  55.541 +     * (<a href="Collection.html#optional-restrictions">optional</a>)
  55.542 +     */
  55.543 +    boolean remove(Object o);
  55.544 +
  55.545 +    /**
  55.546 +     * Returns <tt>true</tt> if this deque contains the specified element.
  55.547 +     * More formally, returns <tt>true</tt> if and only if this deque contains
  55.548 +     * at least one element <tt>e</tt> such that
  55.549 +     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
  55.550 +     *
  55.551 +     * @param o element whose presence in this deque is to be tested
  55.552 +     * @return <tt>true</tt> if this deque contains the specified element
  55.553 +     * @throws ClassCastException if the type of the specified element
  55.554 +     *         is incompatible with this deque
  55.555 +     * (<a href="Collection.html#optional-restrictions">optional</a>)
  55.556 +     * @throws NullPointerException if the specified element is null and this
  55.557 +     *         deque does not permit null elements
  55.558 +     * (<a href="Collection.html#optional-restrictions">optional</a>)
  55.559 +     */
  55.560 +    boolean contains(Object o);
  55.561 +
  55.562 +    /**
  55.563 +     * Returns the number of elements in this deque.
  55.564 +     *
  55.565 +     * @return the number of elements in this deque
  55.566 +     */
  55.567 +    public int size();
  55.568 +
  55.569 +    /**
  55.570 +     * Returns an iterator over the elements in this deque in proper sequence.
  55.571 +     * The elements will be returned in order from first (head) to last (tail).
  55.572 +     *
  55.573 +     * @return an iterator over the elements in this deque in proper sequence
  55.574 +     */
  55.575 +    Iterator<E> iterator();
  55.576 +
  55.577 +    /**
  55.578 +     * Returns an iterator over the elements in this deque in reverse
  55.579 +     * sequential order.  The elements will be returned in order from
  55.580 +     * last (tail) to first (head).
  55.581 +     *
  55.582 +     * @return an iterator over the elements in this deque in reverse
  55.583 +     * sequence
  55.584 +     */
  55.585 +    Iterator<E> descendingIterator();
  55.586 +
  55.587 +}
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/emul/compact/src/main/java/java/util/Dictionary.java	Tue Feb 05 17:04:22 2013 +0100
    56.3 @@ -0,0 +1,155 @@
    56.4 +/*
    56.5 + * Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved.
    56.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    56.7 + *
    56.8 + * This code is free software; you can redistribute it and/or modify it
    56.9 + * under the terms of the GNU General Public License version 2 only, as
   56.10 + * published by the Free Software Foundation.  Oracle designates this
   56.11 + * particular file as subject to the "Classpath" exception as provided
   56.12 + * by Oracle in the LICENSE file that accompanied this code.
   56.13 + *
   56.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   56.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   56.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   56.17 + * version 2 for more details (a copy is included in the LICENSE file that
   56.18 + * accompanied this code).
   56.19 + *
   56.20 + * You should have received a copy of the GNU General Public License version
   56.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   56.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   56.23 + *
   56.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   56.25 + * or visit www.oracle.com if you need additional information or have any
   56.26 + * questions.
   56.27 + */
   56.28 +
   56.29 +package java.util;
   56.30 +
   56.31 +/**
   56.32 + * The <code>Dictionary</code> class is the abstract parent of any
   56.33 + * class, such as <code>Hashtable</code>, which maps keys to values.
   56.34 + * Every key and every value is an object. In any one <tt>Dictionary</tt>
   56.35 + * object, every key is associated with at most one value. Given a
   56.36 + * <tt>Dictionary</tt> and a key, the associated element can be looked up.
   56.37 + * Any non-<code>null</code> object can be used as a key and as a value.
   56.38 + * <p>
   56.39 + * As a rule, the <code>equals</code> method should be used by
   56.40 + * implementations of this class to decide if two keys are the same.
   56.41 + * <p>
   56.42 + * <strong>NOTE: This class is obsolete.  New implementations should
   56.43 + * implement the Map interface, rather than extending this class.</strong>
   56.44 + *
   56.45 + * @author  unascribed
   56.46 + * @see     java.util.Map
   56.47 + * @see     java.lang.Object#equals(java.lang.Object)
   56.48 + * @see     java.lang.Object#hashCode()
   56.49 + * @see     java.util.Hashtable
   56.50 + * @since   JDK1.0
   56.51 + */
   56.52 +public abstract
   56.53 +class Dictionary<K,V> {
   56.54 +    /**
   56.55 +     * Sole constructor.  (For invocation by subclass constructors, typically
   56.56 +     * implicit.)
   56.57 +     */
   56.58 +    public Dictionary() {
   56.59 +    }
   56.60 +
   56.61 +    /**
   56.62 +     * Returns the number of entries (distinct keys) in this dictionary.
   56.63 +     *
   56.64 +     * @return  the number of keys in this dictionary.
   56.65 +     */
   56.66 +    abstract public int size();
   56.67 +
   56.68 +    /**
   56.69 +     * Tests if this dictionary maps no keys to value. The general contract
   56.70 +     * for the <tt>isEmpty</tt> method is that the result is true if and only
   56.71 +     * if this dictionary contains no entries.
   56.72 +     *
   56.73 +     * @return  <code>true</code> if this dictionary maps no keys to values;
   56.74 +     *          <code>false</code> otherwise.
   56.75 +     */
   56.76 +    abstract public boolean isEmpty();
   56.77 +
   56.78 +    /**
   56.79 +     * Returns an enumeration of the keys in this dictionary. The general
   56.80 +     * contract for the keys method is that an <tt>Enumeration</tt> object
   56.81 +     * is returned that will generate all the keys for which this dictionary
   56.82 +     * contains entries.
   56.83 +     *
   56.84 +     * @return  an enumeration of the keys in this dictionary.
   56.85 +     * @see     java.util.Dictionary#elements()
   56.86 +     * @see     java.util.Enumeration
   56.87 +     */
   56.88 +    abstract public Enumeration<K> keys();
   56.89 +
   56.90 +    /**
   56.91 +     * Returns an enumeration of the values in this dictionary. The general
   56.92 +     * contract for the <tt>elements</tt> method is that an
   56.93 +     * <tt>Enumeration</tt> is returned that will generate all the elements
   56.94 +     * contained in entries in this dictionary.
   56.95 +     *
   56.96 +     * @return  an enumeration of the values in this dictionary.
   56.97 +     * @see     java.util.Dictionary#keys()
   56.98 +     * @see     java.util.Enumeration
   56.99 +     */
  56.100 +    abstract public Enumeration<V> elements();
  56.101 +
  56.102 +    /**
  56.103 +     * Returns the value to which the key is mapped in this dictionary.
  56.104 +     * The general contract for the <tt>isEmpty</tt> method is that if this
  56.105 +     * dictionary contains an entry for the specified key, the associated
  56.106 +     * value is returned; otherwise, <tt>null</tt> is returned.
  56.107 +     *
  56.108 +     * @return  the value to which the key is mapped in this dictionary;
  56.109 +     * @param   key   a key in this dictionary.
  56.110 +     *          <code>null</code> if the key is not mapped to any value in
  56.111 +     *          this dictionary.
  56.112 +     * @exception NullPointerException if the <tt>key</tt> is <tt>null</tt>.
  56.113 +     * @see     java.util.Dictionary#put(java.lang.Object, java.lang.Object)
  56.114 +     */
  56.115 +    abstract public V get(Object key);
  56.116 +
  56.117 +    /**
  56.118 +     * Maps the specified <code>key</code> to the specified
  56.119 +     * <code>value</code> in this dictionary. Neither the key nor the
  56.120 +     * value can be <code>null</code>.
  56.121 +     * <p>
  56.122 +     * If this dictionary already contains an entry for the specified
  56.123 +     * <tt>key</tt>, the value already in this dictionary for that
  56.124 +     * <tt>key</tt> is returned, after modifying the entry to contain the
  56.125 +     *  new element. <p>If this dictionary does not already have an entry
  56.126 +     *  for the specified <tt>key</tt>, an entry is created for the
  56.127 +     *  specified <tt>key</tt> and <tt>value</tt>, and <tt>null</tt> is
  56.128 +     *  returned.
  56.129 +     * <p>
  56.130 +     * The <code>value</code> can be retrieved by calling the
  56.131 +     * <code>get</code> method with a <code>key</code> that is equal to
  56.132 +     * the original <code>key</code>.
  56.133 +     *
  56.134 +     * @param      key     the hashtable key.
  56.135 +     * @param      value   the value.
  56.136 +     * @return     the previous value to which the <code>key</code> was mapped
  56.137 +     *             in this dictionary, or <code>null</code> if the key did not
  56.138 +     *             have a previous mapping.
  56.139 +     * @exception  NullPointerException  if the <code>key</code> or
  56.140 +     *               <code>value</code> is <code>null</code>.
  56.141 +     * @see        java.lang.Object#equals(java.lang.Object)
  56.142 +     * @see        java.util.Dictionary#get(java.lang.Object)
  56.143 +     */
  56.144 +    abstract public V put(K key, V value);
  56.145 +
  56.146 +    /**
  56.147 +     * Removes the <code>key</code> (and its corresponding
  56.148 +     * <code>value</code>) from this dictionary. This method does nothing
  56.149 +     * if the <code>key</code> is not in this dictionary.
  56.150 +     *
  56.151 +     * @param   key   the key that needs to be removed.
  56.152 +     * @return  the value to which the <code>key</code> had been mapped in this
  56.153 +     *          dictionary, or <code>null</code> if the key did not have a
  56.154 +     *          mapping.
  56.155 +     * @exception NullPointerException if <tt>key</tt> is <tt>null</tt>.
  56.156 +     */
  56.157 +    abstract public V remove(Object key);
  56.158 +}
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/emul/compact/src/main/java/java/util/EmptyStackException.java	Tue Feb 05 17:04:22 2013 +0100
    57.3 @@ -0,0 +1,46 @@
    57.4 +/*
    57.5 + * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
    57.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    57.7 + *
    57.8 + * This code is free software; you can redistribute it and/or modify it
    57.9 + * under the terms of the GNU General Public License version 2 only, as
   57.10 + * published by the Free Software Foundation.  Oracle designates this
   57.11 + * particular file as subject to the "Classpath" exception as provided
   57.12 + * by Oracle in the LICENSE file that accompanied this code.
   57.13 + *
   57.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   57.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   57.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   57.17 + * version 2 for more details (a copy is included in the LICENSE file that
   57.18 + * accompanied this code).
   57.19 + *
   57.20 + * You should have received a copy of the GNU General Public License version
   57.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   57.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   57.23 + *
   57.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   57.25 + * or visit www.oracle.com if you need additional information or have any
   57.26 + * questions.
   57.27 + */
   57.28 +
   57.29 +package java.util;
   57.30 +
   57.31 +/**
   57.32 + * Thrown by methods in the <code>Stack</code> class to indicate
   57.33 + * that the stack is empty.
   57.34 + *
   57.35 + * @author  Jonathan Payne
   57.36 + * @see     java.util.Stack
   57.37 + * @since   JDK1.0
   57.38 + */
   57.39 +public
   57.40 +class EmptyStackException extends RuntimeException {
   57.41 +    private static final long serialVersionUID = 5084686378493302095L;
   57.42 +
   57.43 +    /**
   57.44 +     * Constructs a new <code>EmptyStackException</code> with <tt>null</tt>
   57.45 +     * as its error message string.
   57.46 +     */
   57.47 +    public EmptyStackException() {
   57.48 +    }
   57.49 +}
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/emul/compact/src/main/java/java/util/EventListener.java	Tue Feb 05 17:04:22 2013 +0100
    58.3 @@ -0,0 +1,33 @@
    58.4 +/*
    58.5 + * Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved.
    58.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    58.7 + *
    58.8 + * This code is free software; you can redistribute it and/or modify it
    58.9 + * under the terms of the GNU General Public License version 2 only, as
   58.10 + * published by the Free Software Foundation.  Oracle designates this
   58.11 + * particular file as subject to the "Classpath" exception as provided
   58.12 + * by Oracle in the LICENSE file that accompanied this code.
   58.13 + *
   58.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   58.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   58.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   58.17 + * version 2 for more details (a copy is included in the LICENSE file that
   58.18 + * accompanied this code).
   58.19 + *
   58.20 + * You should have received a copy of the GNU General Public License version
   58.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   58.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   58.23 + *
   58.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   58.25 + * or visit www.oracle.com if you need additional information or have any
   58.26 + * questions.
   58.27 + */
   58.28 +
   58.29 +package java.util;
   58.30 +
   58.31 +/**
   58.32 + * A tagging interface that all event listener interfaces must extend.
   58.33 + * @since JDK1.1
   58.34 + */
   58.35 +public interface EventListener {
   58.36 +}
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/emul/compact/src/main/java/java/util/EventListenerProxy.java	Tue Feb 05 17:04:22 2013 +0100
    59.3 @@ -0,0 +1,75 @@
    59.4 +/*
    59.5 + * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
    59.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    59.7 + *
    59.8 + * This code is free software; you can redistribute it and/or modify it
    59.9 + * under the terms of the GNU General Public License version 2 only, as
   59.10 + * published by the Free Software Foundation.  Oracle designates this
   59.11 + * particular file as subject to the "Classpath" exception as provided
   59.12 + * by Oracle in the LICENSE file that accompanied this code.
   59.13 + *
   59.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   59.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   59.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   59.17 + * version 2 for more details (a copy is included in the LICENSE file that
   59.18 + * accompanied this code).
   59.19 + *
   59.20 + * You should have received a copy of the GNU General Public License version
   59.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   59.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   59.23 + *
   59.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   59.25 + * or visit www.oracle.com if you need additional information or have any
   59.26 + * questions.
   59.27 + */
   59.28 +
   59.29 +package java.util;
   59.30 +
   59.31 +/**
   59.32 + * An abstract wrapper class for an {@code EventListener} class
   59.33 + * which associates a set of additional parameters with the listener.
   59.34 + * Subclasses must provide the storage and accessor methods
   59.35 + * for the additional arguments or parameters.
   59.36 + * <p>
   59.37 + * For example, a bean which supports named properties
   59.38 + * would have a two argument method signature for adding
   59.39 + * a {@code PropertyChangeListener} for a property:
   59.40 + * <pre>
   59.41 + * public void addPropertyChangeListener(String propertyName,
   59.42 + *                                       PropertyChangeListener listener)
   59.43 + * </pre>
   59.44 + * If the bean also implemented the zero argument get listener method:
   59.45 + * <pre>
   59.46 + * public PropertyChangeListener[] getPropertyChangeListeners()
   59.47 + * </pre>
   59.48 + * then the array may contain inner {@code PropertyChangeListeners}
   59.49 + * which are also {@code PropertyChangeListenerProxy} objects.
   59.50 + * <p>
   59.51 + * If the calling method is interested in retrieving the named property
   59.52 + * then it would have to test the element to see if it is a proxy class.
   59.53 + *
   59.54 + * @since 1.4
   59.55 + */
   59.56 +public abstract class EventListenerProxy<T extends EventListener>
   59.57 +        implements EventListener {
   59.58 +
   59.59 +    private final T listener;
   59.60 +
   59.61 +    /**
   59.62 +     * Creates a proxy for the specified listener.
   59.63 +     *
   59.64 +     * @param listener  the listener object
   59.65 +     */
   59.66 +    public EventListenerProxy(T listener) {
   59.67 +        this.listener = listener;
   59.68 +    }
   59.69 +
   59.70 +    /**
   59.71 +     * Returns the listener associated with the proxy.
   59.72 +     *
   59.73 +     * @return  the listener associated with the proxy
   59.74 +     */
   59.75 +    public T getListener() {
   59.76 +        return this.listener;
   59.77 +    }
   59.78 +}
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/emul/compact/src/main/java/java/util/EventObject.java	Tue Feb 05 17:04:22 2013 +0100
    60.3 @@ -0,0 +1,78 @@
    60.4 +/*
    60.5 + * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
    60.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    60.7 + *
    60.8 + * This code is free software; you can redistribute it and/or modify it
    60.9 + * under the terms of the GNU General Public License version 2 only, as
   60.10 + * published by the Free Software Foundation.  Oracle designates this
   60.11 + * particular file as subject to the "Classpath" exception as provided
   60.12 + * by Oracle in the LICENSE file that accompanied this code.
   60.13 + *
   60.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   60.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   60.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   60.17 + * version 2 for more details (a copy is included in the LICENSE file that
   60.18 + * accompanied this code).
   60.19 + *
   60.20 + * You should have received a copy of the GNU General Public License version
   60.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   60.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   60.23 + *
   60.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   60.25 + * or visit www.oracle.com if you need additional information or have any
   60.26 + * questions.
   60.27 + */
   60.28 +
   60.29 +package java.util;
   60.30 +
   60.31 +/**
   60.32 + * <p>
   60.33 + * The root class from which all event state objects shall be derived.
   60.34 + * <p>
   60.35 + * All Events are constructed with a reference to the object, the "source",
   60.36 + * that is logically deemed to be the object upon which the Event in question
   60.37 + * initially occurred upon.
   60.38 + *
   60.39 + * @since JDK1.1
   60.40 + */
   60.41 +
   60.42 +public class EventObject implements java.io.Serializable {
   60.43 +
   60.44 +    private static final long serialVersionUID = 5516075349620653480L;
   60.45 +
   60.46 +    /**
   60.47 +     * The object on which the Event initially occurred.
   60.48 +     */
   60.49 +    protected transient Object  source;
   60.50 +
   60.51 +    /**
   60.52 +     * Constructs a prototypical Event.
   60.53 +     *
   60.54 +     * @param    source    The object on which the Event initially occurred.
   60.55 +     * @exception  IllegalArgumentException  if source is null.
   60.56 +     */
   60.57 +    public EventObject(Object source) {
   60.58 +        if (source == null)
   60.59 +            throw new IllegalArgumentException("null source");
   60.60 +
   60.61 +        this.source = source;
   60.62 +    }
   60.63 +
   60.64 +    /**
   60.65 +     * The object on which the Event initially occurred.
   60.66 +     *
   60.67 +     * @return   The object on which the Event initially occurred.
   60.68 +     */
   60.69 +    public Object getSource() {
   60.70 +        return source;
   60.71 +    }
   60.72 +
   60.73 +    /**
   60.74 +     * Returns a String representation of this EventObject.
   60.75 +     *
   60.76 +     * @return  A a String representation of this EventObject.
   60.77 +     */
   60.78 +    public String toString() {
   60.79 +        return getClass().getName() + "[source=" + source + "]";
   60.80 +    }
   60.81 +}
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/emul/compact/src/main/java/java/util/Hashtable.java	Tue Feb 05 17:04:22 2013 +0100
    61.3 @@ -0,0 +1,1005 @@
    61.4 +/*
    61.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
    61.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    61.7 + *
    61.8 + * This code is free software; you can redistribute it and/or modify it
    61.9 + * under the terms of the GNU General Public License version 2 only, as
   61.10 + * published by the Free Software Foundation.  Oracle designates this
   61.11 + * particular file as subject to the "Classpath" exception as provided
   61.12 + * by Oracle in the LICENSE file that accompanied this code.
   61.13 + *
   61.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   61.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   61.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   61.17 + * version 2 for more details (a copy is included in the LICENSE file that
   61.18 + * accompanied this code).
   61.19 + *
   61.20 + * You should have received a copy of the GNU General Public License version
   61.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   61.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   61.23 + *
   61.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   61.25 + * or visit www.oracle.com if you need additional information or have any
   61.26 + * questions.
   61.27 + */
   61.28 +
   61.29 +package java.util;
   61.30 +import java.io.*;
   61.31 +
   61.32 +/**
   61.33 + * This class implements a hash table, which maps keys to values. Any
   61.34 + * non-<code>null</code> object can be used as a key or as a value. <p>
   61.35 + *
   61.36 + * To successfully store and retrieve objects from a hashtable, the
   61.37 + * objects used as keys must implement the <code>hashCode</code>
   61.38 + * method and the <code>equals</code> method. <p>
   61.39 + *
   61.40 + * An instance of <code>Hashtable</code> has two parameters that affect its
   61.41 + * performance: <i>initial capacity</i> and <i>load factor</i>.  The
   61.42 + * <i>capacity</i> is the number of <i>buckets</i> in the hash table, and the
   61.43 + * <i>initial capacity</i> is simply the capacity at the time the hash table
   61.44 + * is created.  Note that the hash table is <i>open</i>: in the case of a "hash
   61.45 + * collision", a single bucket stores multiple entries, which must be searched
   61.46 + * sequentially.  The <i>load factor</i> is a measure of how full the hash
   61.47 + * table is allowed to get before its capacity is automatically increased.
   61.48 + * The initial capacity and load factor parameters are merely hints to
   61.49 + * the implementation.  The exact details as to when and whether the rehash
   61.50 + * method is invoked are implementation-dependent.<p>
   61.51 + *
   61.52 + * Generally, the default load factor (.75) offers a good tradeoff between
   61.53 + * time and space costs.  Higher values decrease the space overhead but
   61.54 + * increase the time cost to look up an entry (which is reflected in most
   61.55 + * <tt>Hashtable</tt> operations, including <tt>get</tt> and <tt>put</tt>).<p>
   61.56 + *
   61.57 + * The initial capacity controls a tradeoff between wasted space and the
   61.58 + * need for <code>rehash</code> operations, which are time-consuming.
   61.59 + * No <code>rehash</code> operations will <i>ever</i> occur if the initial
   61.60 + * capacity is greater than the maximum number of entries the
   61.61 + * <tt>Hashtable</tt> will contain divided by its load factor.  However,
   61.62 + * setting the initial capacity too high can waste space.<p>
   61.63 + *
   61.64 + * If many entries are to be made into a <code>Hashtable</code>,
   61.65 + * creating it with a sufficiently large capacity may allow the
   61.66 + * entries to be inserted more efficiently than letting it perform
   61.67 + * automatic rehashing as needed to grow the table. <p>
   61.68 + *
   61.69 + * This example creates a hashtable of numbers. It uses the names of
   61.70 + * the numbers as keys:
   61.71 + * <pre>   {@code
   61.72 + *   Hashtable<String, Integer> numbers
   61.73 + *     = new Hashtable<String, Integer>();
   61.74 + *   numbers.put("one", 1);
   61.75 + *   numbers.put("two", 2);
   61.76 + *   numbers.put("three", 3);}</pre>
   61.77 + *
   61.78 + * <p>To retrieve a number, use the following code:
   61.79 + * <pre>   {@code
   61.80 + *   Integer n = numbers.get("two");
   61.81 + *   if (n != null) {
   61.82 + *     System.out.println("two = " + n);
   61.83 + *   }}</pre>
   61.84 + *
   61.85 + * <p>The iterators returned by the <tt>iterator</tt> method of the collections
   61.86 + * returned by all of this class's "collection view methods" are
   61.87 + * <em>fail-fast</em>: if the Hashtable is structurally modified at any time
   61.88 + * after the iterator is created, in any way except through the iterator's own
   61.89 + * <tt>remove</tt> method, the iterator will throw a {@link
   61.90 + * ConcurrentModificationException}.  Thus, in the face of concurrent
   61.91 + * modification, the iterator fails quickly and cleanly, rather than risking
   61.92 + * arbitrary, non-deterministic behavior at an undetermined time in the future.
   61.93 + * The Enumerations returned by Hashtable's keys and elements methods are
   61.94 + * <em>not</em> fail-fast.
   61.95 + *
   61.96 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
   61.97 + * as it is, generally speaking, impossible to make any hard guarantees in the
   61.98 + * presence of unsynchronized concurrent modification.  Fail-fast iterators
   61.99 + * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
  61.100 + * Therefore, it would be wrong to write a program that depended on this
  61.101 + * exception for its correctness: <i>the fail-fast behavior of iterators
  61.102 + * should be used only to detect bugs.</i>
  61.103 + *
  61.104 + * <p>As of the Java 2 platform v1.2, this class was retrofitted to
  61.105 + * implement the {@link Map} interface, making it a member of the
  61.106 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
  61.107 + *
  61.108 + * Java Collections Framework</a>.  Unlike the new collection
  61.109 + * implementations, {@code Hashtable} is synchronized.  If a
  61.110 + * thread-safe implementation is not needed, it is recommended to use
  61.111 + * {@link HashMap} in place of {@code Hashtable}.  If a thread-safe
  61.112 + * highly-concurrent implementation is desired, then it is recommended
  61.113 + * to use {@link java.util.concurrent.ConcurrentHashMap} in place of
  61.114 + * {@code Hashtable}.
  61.115 + *
  61.116 + * @author  Arthur van Hoff
  61.117 + * @author  Josh Bloch
  61.118 + * @author  Neal Gafter
  61.119 + * @see     Object#equals(java.lang.Object)
  61.120 + * @see     Object#hashCode()
  61.121 + * @see     Hashtable#rehash()
  61.122 + * @see     Collection
  61.123 + * @see     Map
  61.124 + * @see     HashMap
  61.125 + * @see     TreeMap
  61.126 + * @since JDK1.0
  61.127 + */
  61.128 +public class Hashtable<K,V>
  61.129 +    extends Dictionary<K,V>
  61.130 +    implements Map<K,V>, Cloneable, java.io.Serializable {
  61.131 +
  61.132 +    /**
  61.133 +     * The hash table data.
  61.134 +     */
  61.135 +    private transient Entry[] table;
  61.136 +
  61.137 +    /**
  61.138 +     * The total number of entries in the hash table.
  61.139 +     */
  61.140 +    private transient int count;
  61.141 +
  61.142 +    /**
  61.143 +     * The table is rehashed when its size exceeds this threshold.  (The
  61.144 +     * value of this field is (int)(capacity * loadFactor).)
  61.145 +     *
  61.146 +     * @serial
  61.147 +     */
  61.148 +    private int threshold;
  61.149 +
  61.150 +    /**
  61.151 +     * The load factor for the hashtable.
  61.152 +     *
  61.153 +     * @serial
  61.154 +     */
  61.155 +    private float loadFactor;
  61.156 +
  61.157 +    /**
  61.158 +     * The number of times this Hashtable has been structurally modified
  61.159 +     * Structural modifications are those that change the number of entries in
  61.160 +     * the Hashtable or otherwise modify its internal structure (e.g.,
  61.161 +     * rehash).  This field is used to make iterators on Collection-views of
  61.162 +     * the Hashtable fail-fast.  (See ConcurrentModificationException).
  61.163 +     */
  61.164 +    private transient int modCount = 0;
  61.165 +
  61.166 +    /** use serialVersionUID from JDK 1.0.2 for interoperability */
  61.167 +    private static final long serialVersionUID = 1421746759512286392L;
  61.168 +
  61.169 +    /**
  61.170 +     * Constructs a new, empty hashtable with the specified initial
  61.171 +     * capacity and the specified load factor.
  61.172 +     *
  61.173 +     * @param      initialCapacity   the initial capacity of the hashtable.
  61.174 +     * @param      loadFactor        the load factor of the hashtable.
  61.175 +     * @exception  IllegalArgumentException  if the initial capacity is less
  61.176 +     *             than zero, or if the load factor is nonpositive.
  61.177 +     */
  61.178 +    public Hashtable(int initialCapacity, float loadFactor) {
  61.179 +        if (initialCapacity < 0)
  61.180 +            throw new IllegalArgumentException("Illegal Capacity: "+
  61.181 +                                               initialCapacity);
  61.182 +        if (loadFactor <= 0 || Float.isNaN(loadFactor))
  61.183 +            throw new IllegalArgumentException("Illegal Load: "+loadFactor);
  61.184 +
  61.185 +        if (initialCapacity==0)
  61.186 +            initialCapacity = 1;
  61.187 +        this.loadFactor = loadFactor;
  61.188 +        table = new Entry[initialCapacity];
  61.189 +        threshold = (int)(initialCapacity * loadFactor);
  61.190 +    }
  61.191 +
  61.192 +    /**
  61.193 +     * Constructs a new, empty hashtable with the specified initial capacity
  61.194 +     * and default load factor (0.75).
  61.195 +     *
  61.196 +     * @param     initialCapacity   the initial capacity of the hashtable.
  61.197 +     * @exception IllegalArgumentException if the initial capacity is less
  61.198 +     *              than zero.
  61.199 +     */
  61.200 +    public Hashtable(int initialCapacity) {
  61.201 +        this(initialCapacity, 0.75f);
  61.202 +    }
  61.203 +
  61.204 +    /**
  61.205 +     * Constructs a new, empty hashtable with a default initial capacity (11)
  61.206 +     * and load factor (0.75).
  61.207 +     */
  61.208 +    public Hashtable() {
  61.209 +        this(11, 0.75f);
  61.210 +    }
  61.211 +
  61.212 +    /**
  61.213 +     * Constructs a new hashtable with the same mappings as the given
  61.214 +     * Map.  The hashtable is created with an initial capacity sufficient to
  61.215 +     * hold the mappings in the given Map and a default load factor (0.75).
  61.216 +     *
  61.217 +     * @param t the map whose mappings are to be placed in this map.
  61.218 +     * @throws NullPointerException if the specified map is null.
  61.219 +     * @since   1.2
  61.220 +     */
  61.221 +    public Hashtable(Map<? extends K, ? extends V> t) {
  61.222 +        this(Math.max(2*t.size(), 11), 0.75f);
  61.223 +        putAll(t);
  61.224 +    }
  61.225 +
  61.226 +    /**
  61.227 +     * Returns the number of keys in this hashtable.
  61.228 +     *
  61.229 +     * @return  the number of keys in this hashtable.
  61.230 +     */
  61.231 +    public synchronized int size() {
  61.232 +        return count;
  61.233 +    }
  61.234 +
  61.235 +    /**
  61.236 +     * Tests if this hashtable maps no keys to values.
  61.237 +     *
  61.238 +     * @return  <code>true</code> if this hashtable maps no keys to values;
  61.239 +     *          <code>false</code> otherwise.
  61.240 +     */
  61.241 +    public synchronized boolean isEmpty() {
  61.242 +        return count == 0;
  61.243 +    }
  61.244 +
  61.245 +    /**
  61.246 +     * Returns an enumeration of the keys in this hashtable.
  61.247 +     *
  61.248 +     * @return  an enumeration of the keys in this hashtable.
  61.249 +     * @see     Enumeration
  61.250 +     * @see     #elements()
  61.251 +     * @see     #keySet()
  61.252 +     * @see     Map
  61.253 +     */
  61.254 +    public synchronized Enumeration<K> keys() {
  61.255 +        return this.<K>getEnumeration(KEYS);
  61.256 +    }
  61.257 +
  61.258 +    /**
  61.259 +     * Returns an enumeration of the values in this hashtable.
  61.260 +     * Use the Enumeration methods on the returned object to fetch the elements
  61.261 +     * sequentially.
  61.262 +     *
  61.263 +     * @return  an enumeration of the values in this hashtable.
  61.264 +     * @see     java.util.Enumeration
  61.265 +     * @see     #keys()
  61.266 +     * @see     #values()
  61.267 +     * @see     Map
  61.268 +     */
  61.269 +    public synchronized Enumeration<V> elements() {
  61.270 +        return this.<V>getEnumeration(VALUES);
  61.271 +    }
  61.272 +
  61.273 +    /**
  61.274 +     * Tests if some key maps into the specified value in this hashtable.
  61.275 +     * This operation is more expensive than the {@link #containsKey
  61.276 +     * containsKey} method.
  61.277 +     *
  61.278 +     * <p>Note that this method is identical in functionality to
  61.279 +     * {@link #containsValue containsValue}, (which is part of the
  61.280 +     * {@link Map} interface in the collections framework).
  61.281 +     *
  61.282 +     * @param      value   a value to search for
  61.283 +     * @return     <code>true</code> if and only if some key maps to the
  61.284 +     *             <code>value</code> argument in this hashtable as
  61.285 +     *             determined by the <tt>equals</tt> method;
  61.286 +     *             <code>false</code> otherwise.
  61.287 +     * @exception  NullPointerException  if the value is <code>null</code>
  61.288 +     */
  61.289 +    public synchronized boolean contains(Object value) {
  61.290 +        if (value == null) {
  61.291 +            throw new NullPointerException();
  61.292 +        }
  61.293 +
  61.294 +        Entry tab[] = table;
  61.295 +        for (int i = tab.length ; i-- > 0 ;) {
  61.296 +            for (Entry<K,V> e = tab[i] ; e != null ; e = e.next) {
  61.297 +                if (e.value.equals(value)) {
  61.298 +                    return true;
  61.299 +                }
  61.300 +            }
  61.301 +        }
  61.302 +        return false;
  61.303 +    }
  61.304 +
  61.305 +    /**
  61.306 +     * Returns true if this hashtable maps one or more keys to this value.
  61.307 +     *
  61.308 +     * <p>Note that this method is identical in functionality to {@link
  61.309 +     * #contains contains} (which predates the {@link Map} interface).
  61.310 +     *
  61.311 +     * @param value value whose presence in this hashtable is to be tested
  61.312 +     * @return <tt>true</tt> if this map maps one or more keys to the
  61.313 +     *         specified value
  61.314 +     * @throws NullPointerException  if the value is <code>null</code>
  61.315 +     * @since 1.2
  61.316 +     */
  61.317 +    public boolean containsValue(Object value) {
  61.318 +        return contains(value);
  61.319 +    }
  61.320 +
  61.321 +    /**
  61.322 +     * Tests if the specified object is a key in this hashtable.
  61.323 +     *
  61.324 +     * @param   key   possible key
  61.325 +     * @return  <code>true</code> if and only if the specified object
  61.326 +     *          is a key in this hashtable, as determined by the
  61.327 +     *          <tt>equals</tt> method; <code>false</code> otherwise.
  61.328 +     * @throws  NullPointerException  if the key is <code>null</code>
  61.329 +     * @see     #contains(Object)
  61.330 +     */
  61.331 +    public synchronized boolean containsKey(Object key) {
  61.332 +        Entry tab[] = table;
  61.333 +        int hash = key.hashCode();
  61.334 +        int index = (hash & 0x7FFFFFFF) % tab.length;
  61.335 +        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
  61.336 +            if ((e.hash == hash) && e.key.equals(key)) {
  61.337 +                return true;
  61.338 +            }
  61.339 +        }
  61.340 +        return false;
  61.341 +    }
  61.342 +
  61.343 +    /**
  61.344 +     * Returns the value to which the specified key is mapped,
  61.345 +     * or {@code null} if this map contains no mapping for the key.
  61.346 +     *
  61.347 +     * <p>More formally, if this map contains a mapping from a key
  61.348 +     * {@code k} to a value {@code v} such that {@code (key.equals(k))},
  61.349 +     * then this method returns {@code v}; otherwise it returns
  61.350 +     * {@code null}.  (There can be at most one such mapping.)
  61.351 +     *
  61.352 +     * @param key the key whose associated value is to be returned
  61.353 +     * @return the value to which the specified key is mapped, or
  61.354 +     *         {@code null} if this map contains no mapping for the key
  61.355 +     * @throws NullPointerException if the specified key is null
  61.356 +     * @see     #put(Object, Object)
  61.357 +     */
  61.358 +    public synchronized V get(Object key) {
  61.359 +        Entry tab[] = table;
  61.360 +        int hash = key.hashCode();
  61.361 +        int index = (hash & 0x7FFFFFFF) % tab.length;
  61.362 +        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
  61.363 +            if ((e.hash == hash) && e.key.equals(key)) {
  61.364 +                return e.value;
  61.365 +            }
  61.366 +        }
  61.367 +        return null;
  61.368 +    }
  61.369 +
  61.370 +    /**
  61.371 +     * The maximum size of array to allocate.
  61.372 +     * Some VMs reserve some header words in an array.
  61.373 +     * Attempts to allocate larger arrays may result in
  61.374 +     * OutOfMemoryError: Requested array size exceeds VM limit
  61.375 +     */
  61.376 +    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
  61.377 +
  61.378 +    /**
  61.379 +     * Increases the capacity of and internally reorganizes this
  61.380 +     * hashtable, in order to accommodate and access its entries more
  61.381 +     * efficiently.  This method is called automatically when the
  61.382 +     * number of keys in the hashtable exceeds this hashtable's capacity
  61.383 +     * and load factor.
  61.384 +     */
  61.385 +    protected void rehash() {
  61.386 +        int oldCapacity = table.length;
  61.387 +        Entry[] oldMap = table;
  61.388 +
  61.389 +        // overflow-conscious code
  61.390 +        int newCapacity = (oldCapacity << 1) + 1;
  61.391 +        if (newCapacity - MAX_ARRAY_SIZE > 0) {
  61.392 +            if (oldCapacity == MAX_ARRAY_SIZE)
  61.393 +                // Keep running with MAX_ARRAY_SIZE buckets
  61.394 +                return;
  61.395 +            newCapacity = MAX_ARRAY_SIZE;
  61.396 +        }
  61.397 +        Entry[] newMap = new Entry[newCapacity];
  61.398 +
  61.399 +        modCount++;
  61.400 +        threshold = (int)(newCapacity * loadFactor);
  61.401 +        table = newMap;
  61.402 +
  61.403 +        for (int i = oldCapacity ; i-- > 0 ;) {
  61.404 +            for (Entry<K,V> old = oldMap[i] ; old != null ; ) {
  61.405 +                Entry<K,V> e = old;
  61.406 +                old = old.next;
  61.407 +
  61.408 +                int index = (e.hash & 0x7FFFFFFF) % newCapacity;
  61.409 +                e.next = newMap[index];
  61.410 +                newMap[index] = e;
  61.411 +            }
  61.412 +        }
  61.413 +    }
  61.414 +
  61.415 +    /**
  61.416 +     * Maps the specified <code>key</code> to the specified
  61.417 +     * <code>value</code> in this hashtable. Neither the key nor the
  61.418 +     * value can be <code>null</code>. <p>
  61.419 +     *
  61.420 +     * The value can be retrieved by calling the <code>get</code> method
  61.421 +     * with a key that is equal to the original key.
  61.422 +     *
  61.423 +     * @param      key     the hashtable key
  61.424 +     * @param      value   the value
  61.425 +     * @return     the previous value of the specified key in this hashtable,
  61.426 +     *             or <code>null</code> if it did not have one
  61.427 +     * @exception  NullPointerException  if the key or value is
  61.428 +     *               <code>null</code>
  61.429 +     * @see     Object#equals(Object)
  61.430 +     * @see     #get(Object)
  61.431 +     */
  61.432 +    public synchronized V put(K key, V value) {
  61.433 +        // Make sure the value is not null
  61.434 +        if (value == null) {
  61.435 +            throw new NullPointerException();
  61.436 +        }
  61.437 +
  61.438 +        // Makes sure the key is not already in the hashtable.
  61.439 +        Entry tab[] = table;
  61.440 +        int hash = key.hashCode();
  61.441 +        int index = (hash & 0x7FFFFFFF) % tab.length;
  61.442 +        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
  61.443 +            if ((e.hash == hash) && e.key.equals(key)) {
  61.444 +                V old = e.value;
  61.445 +                e.value = value;
  61.446 +                return old;
  61.447 +            }
  61.448 +        }
  61.449 +
  61.450 +        modCount++;
  61.451 +        if (count >= threshold) {
  61.452 +            // Rehash the table if the threshold is exceeded
  61.453 +            rehash();
  61.454 +
  61.455 +            tab = table;
  61.456 +            index = (hash & 0x7FFFFFFF) % tab.length;
  61.457 +        }
  61.458 +
  61.459 +        // Creates the new entry.
  61.460 +        Entry<K,V> e = tab[index];
  61.461 +        tab[index] = new Entry<>(hash, key, value, e);
  61.462 +        count++;
  61.463 +        return null;
  61.464 +    }
  61.465 +
  61.466 +    /**
  61.467 +     * Removes the key (and its corresponding value) from this
  61.468 +     * hashtable. This method does nothing if the key is not in the hashtable.
  61.469 +     *
  61.470 +     * @param   key   the key that needs to be removed
  61.471 +     * @return  the value to which the key had been mapped in this hashtable,
  61.472 +     *          or <code>null</code> if the key did not have a mapping
  61.473 +     * @throws  NullPointerException  if the key is <code>null</code>
  61.474 +     */
  61.475 +    public synchronized V remove(Object key) {
  61.476 +        Entry tab[] = table;
  61.477 +        int hash = key.hashCode();
  61.478 +        int index = (hash & 0x7FFFFFFF) % tab.length;
  61.479 +        for (Entry<K,V> e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {
  61.480 +            if ((e.hash == hash) && e.key.equals(key)) {
  61.481 +                modCount++;
  61.482 +                if (prev != null) {
  61.483 +                    prev.next = e.next;
  61.484 +                } else {
  61.485 +                    tab[index] = e.next;
  61.486 +                }
  61.487 +                count--;
  61.488 +                V oldValue = e.value;
  61.489 +                e.value = null;
  61.490 +                return oldValue;
  61.491 +            }
  61.492 +        }
  61.493 +        return null;
  61.494 +    }
  61.495 +
  61.496 +    /**
  61.497 +     * Copies all of the mappings from the specified map to this hashtable.
  61.498 +     * These mappings will replace any mappings that this hashtable had for any
  61.499 +     * of the keys currently in the specified map.
  61.500 +     *
  61.501 +     * @param t mappings to be stored in this map
  61.502 +     * @throws NullPointerException if the specified map is null
  61.503 +     * @since 1.2
  61.504 +     */
  61.505 +    public synchronized void putAll(Map<? extends K, ? extends V> t) {
  61.506 +        for (Map.Entry<? extends K, ? extends V> e : t.entrySet())
  61.507 +            put(e.getKey(), e.getValue());
  61.508 +    }
  61.509 +
  61.510 +    /**
  61.511 +     * Clears this hashtable so that it contains no keys.
  61.512 +     */
  61.513 +    public synchronized void clear() {
  61.514 +        Entry tab[] = table;
  61.515 +        modCount++;
  61.516 +        for (int index = tab.length; --index >= 0; )
  61.517 +            tab[index] = null;
  61.518 +        count = 0;
  61.519 +    }
  61.520 +
  61.521 +    /**
  61.522 +     * Creates a shallow copy of this hashtable. All the structure of the
  61.523 +     * hashtable itself is copied, but the keys and values are not cloned.
  61.524 +     * This is a relatively expensive operation.
  61.525 +     *
  61.526 +     * @return  a clone of the hashtable
  61.527 +     */
  61.528 +    public synchronized Object clone() {
  61.529 +        try {
  61.530 +            Hashtable<K,V> t = (Hashtable<K,V>) super.clone();
  61.531 +            t.table = new Entry[table.length];
  61.532 +            for (int i = table.length ; i-- > 0 ; ) {
  61.533 +                t.table[i] = (table[i] != null)
  61.534 +                    ? (Entry<K,V>) table[i].clone() : null;
  61.535 +            }
  61.536 +            t.keySet = null;
  61.537 +            t.entrySet = null;
  61.538 +            t.values = null;
  61.539 +            t.modCount = 0;
  61.540 +            return t;
  61.541 +        } catch (CloneNotSupportedException e) {
  61.542 +            // this shouldn't happen, since we are Cloneable
  61.543 +            throw new InternalError();
  61.544 +        }
  61.545 +    }
  61.546 +
  61.547 +    /**
  61.548 +     * Returns a string representation of this <tt>Hashtable</tt> object
  61.549 +     * in the form of a set of entries, enclosed in braces and separated
  61.550 +     * by the ASCII characters "<tt>,&nbsp;</tt>" (comma and space). Each
  61.551 +     * entry is rendered as the key, an equals sign <tt>=</tt>, and the
  61.552 +     * associated element, where the <tt>toString</tt> method is used to
  61.553 +     * convert the key and element to strings.
  61.554 +     *
  61.555 +     * @return  a string representation of this hashtable
  61.556 +     */
  61.557 +    public synchronized String toString() {
  61.558 +        int max = size() - 1;
  61.559 +        if (max == -1)
  61.560 +            return "{}";
  61.561 +
  61.562 +        StringBuilder sb = new StringBuilder();
  61.563 +        Iterator<Map.Entry<K,V>> it = entrySet().iterator();
  61.564 +
  61.565 +        sb.append('{');
  61.566 +        for (int i = 0; ; i++) {
  61.567 +            Map.Entry<K,V> e = it.next();
  61.568 +            K key = e.getKey();
  61.569 +            V value = e.getValue();
  61.570 +            sb.append(key   == this ? "(this Map)" : key.toString());
  61.571 +            sb.append('=');
  61.572 +            sb.append(value == this ? "(this Map)" : value.toString());
  61.573 +
  61.574 +            if (i == max)
  61.575 +                return sb.append('}').toString();
  61.576 +            sb.append(", ");
  61.577 +        }
  61.578 +    }
  61.579 +
  61.580 +
  61.581 +    private <T> Enumeration<T> getEnumeration(int type) {
  61.582 +        if (count == 0) {
  61.583 +            return Collections.emptyEnumeration();
  61.584 +        } else {
  61.585 +            return new Enumerator<>(type, false);
  61.586 +        }
  61.587 +    }
  61.588 +
  61.589 +    private <T> Iterator<T> getIterator(int type) {
  61.590 +        if (count == 0) {
  61.591 +            return Collections.emptyIterator();
  61.592 +        } else {
  61.593 +            return new Enumerator<>(type, true);
  61.594 +        }
  61.595 +    }
  61.596 +
  61.597 +    // Views
  61.598 +
  61.599 +    /**
  61.600 +     * Each of these fields are initialized to contain an instance of the
  61.601 +     * appropriate view the first time this view is requested.  The views are
  61.602 +     * stateless, so there's no reason to create more than one of each.
  61.603 +     */
  61.604 +    private transient volatile Set<K> keySet = null;
  61.605 +    private transient volatile Set<Map.Entry<K,V>> entrySet = null;
  61.606 +    private transient volatile Collection<V> values = null;
  61.607 +
  61.608 +    /**
  61.609 +     * Returns a {@link Set} view of the keys contained in this map.
  61.610 +     * The set is backed by the map, so changes to the map are
  61.611 +     * reflected in the set, and vice-versa.  If the map is modified
  61.612 +     * while an iteration over the set is in progress (except through
  61.613 +     * the iterator's own <tt>remove</tt> operation), the results of
  61.614 +     * the iteration are undefined.  The set supports element removal,
  61.615 +     * which removes the corresponding mapping from the map, via the
  61.616 +     * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
  61.617 +     * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
  61.618 +     * operations.  It does not support the <tt>add</tt> or <tt>addAll</tt>
  61.619 +     * operations.
  61.620 +     *
  61.621 +     * @since 1.2
  61.622 +     */
  61.623 +    public Set<K> keySet() {
  61.624 +        if (keySet == null)
  61.625 +            keySet = Collections.synchronizedSet(new KeySet(), this);
  61.626 +        return keySet;
  61.627 +    }
  61.628 +
  61.629 +    private class KeySet extends AbstractSet<K> {
  61.630 +        public Iterator<K> iterator() {
  61.631 +            return getIterator(KEYS);
  61.632 +        }
  61.633 +        public int size() {
  61.634 +            return count;
  61.635 +        }
  61.636 +        public boolean contains(Object o) {
  61.637 +            return containsKey(o);
  61.638 +        }
  61.639 +        public boolean remove(Object o) {
  61.640 +            return Hashtable.this.remove(o) != null;
  61.641 +        }
  61.642 +        public void clear() {
  61.643 +            Hashtable.this.clear();
  61.644 +        }
  61.645 +    }
  61.646 +
  61.647 +    /**
  61.648 +     * Returns a {@link Set} view of the mappings contained in this map.
  61.649 +     * The set is backed by the map, so changes to the map are
  61.650 +     * reflected in the set, and vice-versa.  If the map is modified
  61.651 +     * while an iteration over the set is in progress (except through
  61.652 +     * the iterator's own <tt>remove</tt> operation, or through the
  61.653 +     * <tt>setValue</tt> operation on a map entry returned by the
  61.654 +     * iterator) the results of the iteration are undefined.  The set
  61.655 +     * supports element removal, which removes the corresponding
  61.656 +     * mapping from the map, via the <tt>Iterator.remove</tt>,
  61.657 +     * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and
  61.658 +     * <tt>clear</tt> operations.  It does not support the
  61.659 +     * <tt>add</tt> or <tt>addAll</tt> operations.
  61.660 +     *
  61.661 +     * @since 1.2
  61.662 +     */
  61.663 +    public Set<Map.Entry<K,V>> entrySet() {
  61.664 +        if (entrySet==null)
  61.665 +            entrySet = Collections.synchronizedSet(new EntrySet(), this);
  61.666 +        return entrySet;
  61.667 +    }
  61.668 +
  61.669 +    private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
  61.670 +        public Iterator<Map.Entry<K,V>> iterator() {
  61.671 +            return getIterator(ENTRIES);
  61.672 +        }
  61.673 +
  61.674 +        public boolean add(Map.Entry<K,V> o) {
  61.675 +            return super.add(o);
  61.676 +        }
  61.677 +
  61.678 +        public boolean contains(Object o) {
  61.679 +            if (!(o instanceof Map.Entry))
  61.680 +                return false;
  61.681 +            Map.Entry entry = (Map.Entry)o;
  61.682 +            Object key = entry.getKey();
  61.683 +            Entry[] tab = table;
  61.684 +            int hash = key.hashCode();
  61.685 +            int index = (hash & 0x7FFFFFFF) % tab.length;
  61.686 +
  61.687 +            for (Entry e = tab[index]; e != null; e = e.next)
  61.688 +                if (e.hash==hash && e.equals(entry))
  61.689 +                    return true;
  61.690 +            return false;
  61.691 +        }
  61.692 +
  61.693 +        public boolean remove(Object o) {
  61.694 +            if (!(o instanceof Map.Entry))
  61.695 +                return false;
  61.696 +            Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
  61.697 +            K key = entry.getKey();
  61.698 +            Entry[] tab = table;
  61.699 +            int hash = key.hashCode();
  61.700 +            int index = (hash & 0x7FFFFFFF) % tab.length;
  61.701 +
  61.702 +            for (Entry<K,V> e = tab[index], prev = null; e != null;
  61.703 +                 prev = e, e = e.next) {
  61.704 +                if (e.hash==hash && e.equals(entry)) {
  61.705 +                    modCount++;
  61.706 +                    if (prev != null)
  61.707 +                        prev.next = e.next;
  61.708 +                    else
  61.709 +                        tab[index] = e.next;
  61.710 +
  61.711 +                    count--;
  61.712 +                    e.value = null;
  61.713 +                    return true;
  61.714 +                }
  61.715 +            }
  61.716 +            return false;
  61.717 +        }
  61.718 +
  61.719 +        public int size() {
  61.720 +            return count;
  61.721 +        }
  61.722 +
  61.723 +        public void clear() {
  61.724 +            Hashtable.this.clear();
  61.725 +        }
  61.726 +    }
  61.727 +
  61.728 +    /**
  61.729 +     * Returns a {@link Collection} view of the values contained in this map.
  61.730 +     * The collection is backed by the map, so changes to the map are
  61.731 +     * reflected in the collection, and vice-versa.  If the map is
  61.732 +     * modified while an iteration over the collection is in progress
  61.733 +     * (except through the iterator's own <tt>remove</tt> operation),
  61.734 +     * the results of the iteration are undefined.  The collection
  61.735 +     * supports element removal, which removes the corresponding
  61.736 +     * mapping from the map, via the <tt>Iterator.remove</tt>,
  61.737 +     * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
  61.738 +     * <tt>retainAll</tt> and <tt>clear</tt> operations.  It does not
  61.739 +     * support the <tt>add</tt> or <tt>addAll</tt> operations.
  61.740 +     *
  61.741 +     * @since 1.2
  61.742 +     */
  61.743 +    public Collection<V> values() {
  61.744 +        if (values==null)
  61.745 +            values = Collections.synchronizedCollection(new ValueCollection(),
  61.746 +                                                        this);
  61.747 +        return values;
  61.748 +    }
  61.749 +
  61.750 +    private class ValueCollection extends AbstractCollection<V> {
  61.751 +        public Iterator<V> iterator() {
  61.752 +            return getIterator(VALUES);
  61.753 +        }
  61.754 +        public int size() {
  61.755 +            return count;
  61.756 +        }
  61.757 +        public boolean contains(Object o) {
  61.758 +            return containsValue(o);
  61.759 +        }
  61.760 +        public void clear() {
  61.761 +            Hashtable.this.clear();
  61.762 +        }
  61.763 +    }
  61.764 +
  61.765 +    // Comparison and hashing
  61.766 +
  61.767 +    /**
  61.768 +     * Compares the specified Object with this Map for equality,
  61.769 +     * as per the definition in the Map interface.
  61.770 +     *
  61.771 +     * @param  o object to be compared for equality with this hashtable
  61.772 +     * @return true if the specified Object is equal to this Map
  61.773 +     * @see Map#equals(Object)
  61.774 +     * @since 1.2
  61.775 +     */
  61.776 +    public synchronized boolean equals(Object o) {
  61.777 +        if (o == this)
  61.778 +            return true;
  61.779 +
  61.780 +        if (!(o instanceof Map))
  61.781 +            return false;
  61.782 +        Map<K,V> t = (Map<K,V>) o;
  61.783 +        if (t.size() != size())
  61.784 +            return false;
  61.785 +
  61.786 +        try {
  61.787 +            Iterator<Map.Entry<K,V>> i = entrySet().iterator();
  61.788 +            while (i.hasNext()) {
  61.789 +                Map.Entry<K,V> e = i.next();
  61.790 +                K key = e.getKey();
  61.791 +                V value = e.getValue();
  61.792 +                if (value == null) {
  61.793 +                    if (!(t.get(key)==null && t.containsKey(key)))
  61.794 +                        return false;
  61.795 +                } else {
  61.796 +                    if (!value.equals(t.get(key)))
  61.797 +                        return false;
  61.798 +                }
  61.799 +            }
  61.800 +        } catch (ClassCastException unused)   {
  61.801 +            return false;
  61.802 +        } catch (NullPointerException unused) {
  61.803 +            return false;
  61.804 +        }
  61.805 +
  61.806 +        return true;
  61.807 +    }
  61.808 +
  61.809 +    /**
  61.810 +     * Returns the hash code value for this Map as per the definition in the
  61.811 +     * Map interface.
  61.812 +     *
  61.813 +     * @see Map#hashCode()
  61.814 +     * @since 1.2
  61.815 +     */
  61.816 +    public synchronized int hashCode() {
  61.817 +        /*
  61.818 +         * This code detects the recursion caused by computing the hash code
  61.819 +         * of a self-referential hash table and prevents the stack overflow
  61.820 +         * that would otherwise result.  This allows certain 1.1-era
  61.821 +         * applets with self-referential hash tables to work.  This code
  61.822 +         * abuses the loadFactor field to do double-duty as a hashCode
  61.823 +         * in progress flag, so as not to worsen the space performance.
  61.824 +         * A negative load factor indicates that hash code computation is
  61.825 +         * in progress.
  61.826 +         */
  61.827 +        int h = 0;
  61.828 +        if (count == 0 || loadFactor < 0)
  61.829 +            return h;  // Returns zero
  61.830 +
  61.831 +        loadFactor = -loadFactor;  // Mark hashCode computation in progress
  61.832 +        Entry[] tab = table;
  61.833 +        for (int i = 0; i < tab.length; i++)
  61.834 +            for (Entry e = tab[i]; e != null; e = e.next)
  61.835 +                h += e.key.hashCode() ^ e.value.hashCode();
  61.836 +        loadFactor = -loadFactor;  // Mark hashCode computation complete
  61.837 +
  61.838 +        return h;
  61.839 +    }
  61.840 +
  61.841 +    /**
  61.842 +     * Hashtable collision list.
  61.843 +     */
  61.844 +    private static class Entry<K,V> implements Map.Entry<K,V> {
  61.845 +        int hash;
  61.846 +        K key;
  61.847 +        V value;
  61.848 +        Entry<K,V> next;
  61.849 +
  61.850 +        protected Entry(int hash, K key, V value, Entry<K,V> next) {
  61.851 +            this.hash = hash;
  61.852 +            this.key = key;
  61.853 +            this.value = value;
  61.854 +            this.next = next;
  61.855 +        }
  61.856 +
  61.857 +        protected Object clone() {
  61.858 +            return new Entry<>(hash, key, value,
  61.859 +                                  (next==null ? null : (Entry<K,V>) next.clone()));
  61.860 +        }
  61.861 +
  61.862 +        // Map.Entry Ops
  61.863 +
  61.864 +        public K getKey() {
  61.865 +            return key;
  61.866 +        }
  61.867 +
  61.868 +        public V getValue() {
  61.869 +            return value;
  61.870 +        }
  61.871 +
  61.872 +        public V setValue(V value) {
  61.873 +            if (value == null)
  61.874 +                throw new NullPointerException();
  61.875 +
  61.876 +            V oldValue = this.value;
  61.877 +            this.value = value;
  61.878 +            return oldValue;
  61.879 +        }
  61.880 +
  61.881 +        public boolean equals(Object o) {
  61.882 +            if (!(o instanceof Map.Entry))
  61.883 +                return false;
  61.884 +            Map.Entry e = (Map.Entry)o;
  61.885 +
  61.886 +            return (key==null ? e.getKey()==null : key.equals(e.getKey())) &&
  61.887 +               (value==null ? e.getValue()==null : value.equals(e.getValue()));
  61.888 +        }
  61.889 +
  61.890 +        public int hashCode() {
  61.891 +            return hash ^ (value==null ? 0 : value.hashCode());
  61.892 +        }
  61.893 +
  61.894 +        public String toString() {
  61.895 +            return key.toString()+"="+value.toString();
  61.896 +        }
  61.897 +    }
  61.898 +
  61.899 +    // Types of Enumerations/Iterations
  61.900 +    private static final int KEYS = 0;
  61.901 +    private static final int VALUES = 1;
  61.902 +    private static final int ENTRIES = 2;
  61.903 +
  61.904 +    /**
  61.905 +     * A hashtable enumerator class.  This class implements both the
  61.906 +     * Enumeration and Iterator interfaces, but individual instances
  61.907 +     * can be created with the Iterator methods disabled.  This is necessary
  61.908 +     * to avoid unintentionally increasing the capabilities granted a user
  61.909 +     * by passing an Enumeration.
  61.910 +     */
  61.911 +    private class Enumerator<T> implements Enumeration<T>, Iterator<T> {
  61.912 +        Entry[] table = Hashtable.this.table;
  61.913 +        int index = table.length;
  61.914 +        Entry<K,V> entry = null;
  61.915 +        Entry<K,V> lastReturned = null;
  61.916 +        int type;
  61.917 +
  61.918 +        /**
  61.919 +         * Indicates whether this Enumerator is serving as an Iterator
  61.920 +         * or an Enumeration.  (true -> Iterator).
  61.921 +         */
  61.922 +        boolean iterator;
  61.923 +
  61.924 +        /**
  61.925 +         * The modCount value that the iterator believes that the backing
  61.926 +         * Hashtable should have.  If this expectation is violated, the iterator
  61.927 +         * has detected concurrent modification.
  61.928 +         */
  61.929 +        protected int expectedModCount = modCount;
  61.930 +
  61.931 +        Enumerator(int type, boolean iterator) {
  61.932 +            this.type = type;
  61.933 +            this.iterator = iterator;
  61.934 +        }
  61.935 +
  61.936 +        public boolean hasMoreElements() {
  61.937 +            Entry<K,V> e = entry;
  61.938 +            int i = index;
  61.939 +            Entry[] t = table;
  61.940 +            /* Use locals for faster loop iteration */
  61.941 +            while (e == null && i > 0) {
  61.942 +                e = t[--i];
  61.943 +            }
  61.944 +            entry = e;
  61.945 +            index = i;
  61.946 +            return e != null;
  61.947 +        }
  61.948 +
  61.949 +        public T nextElement() {
  61.950 +            Entry<K,V> et = entry;
  61.951 +            int i = index;
  61.952 +            Entry[] t = table;
  61.953 +            /* Use locals for faster loop iteration */
  61.954 +            while (et == null && i > 0) {
  61.955 +                et = t[--i];
  61.956 +            }
  61.957 +            entry = et;
  61.958 +            index = i;
  61.959 +            if (et != null) {
  61.960 +                Entry<K,V> e = lastReturned = entry;
  61.961 +                entry = e.next;
  61.962 +                return type == KEYS ? (T)e.key : (type == VALUES ? (T)e.value : (T)e);
  61.963 +            }
  61.964 +            throw new NoSuchElementException("Hashtable Enumerator");
  61.965 +        }
  61.966 +
  61.967 +        // Iterator methods
  61.968 +        public boolean hasNext() {
  61.969 +            return hasMoreElements();
  61.970 +        }
  61.971 +
  61.972 +        public T next() {
  61.973 +            if (modCount != expectedModCount)
  61.974 +                throw new ConcurrentModificationException();
  61.975 +            return nextElement();
  61.976 +        }
  61.977 +
  61.978 +        public void remove() {
  61.979 +            if (!iterator)
  61.980 +                throw new UnsupportedOperationException();
  61.981 +            if (lastReturned == null)
  61.982 +                throw new IllegalStateException("Hashtable Enumerator");
  61.983 +            if (modCount != expectedModCount)
  61.984 +                throw new ConcurrentModificationException();
  61.985 +
  61.986 +            synchronized(Hashtable.this) {
  61.987 +                Entry[] tab = Hashtable.this.table;
  61.988 +                int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length;
  61.989 +
  61.990 +                for (Entry<K,V> e = tab[index], prev = null; e != null;
  61.991 +                     prev = e, e = e.next) {
  61.992 +                    if (e == lastReturned) {
  61.993 +                        modCount++;
  61.994 +                        expectedModCount++;
  61.995 +                        if (prev == null)
  61.996 +                            tab[index] = e.next;
  61.997 +                        else
  61.998 +                            prev.next = e.next;
  61.999 +                        count--;
 61.1000 +                        lastReturned = null;
 61.1001 +                        return;
 61.1002 +                    }
 61.1003 +                }
 61.1004 +                throw new ConcurrentModificationException();
 61.1005 +            }
 61.1006 +        }
 61.1007 +    }
 61.1008 +}
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/emul/compact/src/main/java/java/util/LinkedList.java	Tue Feb 05 17:04:22 2013 +0100
    62.3 @@ -0,0 +1,1100 @@
    62.4 +/*
    62.5 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
    62.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    62.7 + *
    62.8 + * This code is free software; you can redistribute it and/or modify it
    62.9 + * under the terms of the GNU General Public License version 2 only, as
   62.10 + * published by the Free Software Foundation.  Oracle designates this
   62.11 + * particular file as subject to the "Classpath" exception as provided
   62.12 + * by Oracle in the LICENSE file that accompanied this code.
   62.13 + *
   62.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   62.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   62.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   62.17 + * version 2 for more details (a copy is included in the LICENSE file that
   62.18 + * accompanied this code).
   62.19 + *
   62.20 + * You should have received a copy of the GNU General Public License version
   62.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   62.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   62.23 + *
   62.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   62.25 + * or visit www.oracle.com if you need additional information or have any
   62.26 + * questions.
   62.27 + */
   62.28 +
   62.29 +package java.util;
   62.30 +
   62.31 +/**
   62.32 + * Doubly-linked list implementation of the {@code List} and {@code Deque}
   62.33 + * interfaces.  Implements all optional list operations, and permits all
   62.34 + * elements (including {@code null}).
   62.35 + *
   62.36 + * <p>All of the operations perform as could be expected for a doubly-linked
   62.37 + * list.  Operations that index into the list will traverse the list from
   62.38 + * the beginning or the end, whichever is closer to the specified index.
   62.39 + *
   62.40 + * <p><strong>Note that this implementation is not synchronized.</strong>
   62.41 + * If multiple threads access a linked list concurrently, and at least
   62.42 + * one of the threads modifies the list structurally, it <i>must</i> be
   62.43 + * synchronized externally.  (A structural modification is any operation
   62.44 + * that adds or deletes one or more elements; merely setting the value of
   62.45 + * an element is not a structural modification.)  This is typically
   62.46 + * accomplished by synchronizing on some object that naturally
   62.47 + * encapsulates the list.
   62.48 + *
   62.49 + * If no such object exists, the list should be "wrapped" using the
   62.50 + * {@link Collections#synchronizedList Collections.synchronizedList}
   62.51 + * method.  This is best done at creation time, to prevent accidental
   62.52 + * unsynchronized access to the list:<pre>
   62.53 + *   List list = Collections.synchronizedList(new LinkedList(...));</pre>
   62.54 + *
   62.55 + * <p>The iterators returned by this class's {@code iterator} and
   62.56 + * {@code listIterator} methods are <i>fail-fast</i>: if the list is
   62.57 + * structurally modified at any time after the iterator is created, in
   62.58 + * any way except through the Iterator's own {@code remove} or
   62.59 + * {@code add} methods, the iterator will throw a {@link
   62.60 + * ConcurrentModificationException}.  Thus, in the face of concurrent
   62.61 + * modification, the iterator fails quickly and cleanly, rather than
   62.62 + * risking arbitrary, non-deterministic behavior at an undetermined
   62.63 + * time in the future.
   62.64 + *
   62.65 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
   62.66 + * as it is, generally speaking, impossible to make any hard guarantees in the
   62.67 + * presence of unsynchronized concurrent modification.  Fail-fast iterators
   62.68 + * throw {@code ConcurrentModificationException} on a best-effort basis.
   62.69 + * Therefore, it would be wrong to write a program that depended on this
   62.70 + * exception for its correctness:   <i>the fail-fast behavior of iterators
   62.71 + * should be used only to detect bugs.</i>
   62.72 + *
   62.73 + * <p>This class is a member of the
   62.74 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
   62.75 + * Java Collections Framework</a>.
   62.76 + *
   62.77 + * @author  Josh Bloch
   62.78 + * @see     List
   62.79 + * @see     ArrayList
   62.80 + * @since 1.2
   62.81 + * @param <E> the type of elements held in this collection
   62.82 + */
   62.83 +
   62.84 +public class LinkedList<E>
   62.85 +    extends AbstractSequentialList<E>
   62.86 +    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
   62.87 +{
   62.88 +    transient int size = 0;
   62.89 +
   62.90 +    /**
   62.91 +     * Pointer to first node.
   62.92 +     * Invariant: (first == null && last == null) ||
   62.93 +     *            (first.prev == null && first.item != null)
   62.94 +     */
   62.95 +    transient Node<E> first;
   62.96 +
   62.97 +    /**
   62.98 +     * Pointer to last node.
   62.99 +     * Invariant: (first == null && last == null) ||
  62.100 +     *            (last.next == null && last.item != null)
  62.101 +     */
  62.102 +    transient Node<E> last;
  62.103 +
  62.104 +    /**
  62.105 +     * Constructs an empty list.
  62.106 +     */
  62.107 +    public LinkedList() {
  62.108 +    }
  62.109 +
  62.110 +    /**
  62.111 +     * Constructs a list containing the elements of the specified
  62.112 +     * collection, in the order they are returned by the collection's
  62.113 +     * iterator.
  62.114 +     *
  62.115 +     * @param  c the collection whose elements are to be placed into this list
  62.116 +     * @throws NullPointerException if the specified collection is null
  62.117 +     */
  62.118 +    public LinkedList(Collection<? extends E> c) {
  62.119 +        this();
  62.120 +        addAll(c);
  62.121 +    }
  62.122 +
  62.123 +    /**
  62.124 +     * Links e as first element.
  62.125 +     */
  62.126 +    private void linkFirst(E e) {
  62.127 +        final Node<E> f = first;
  62.128 +        final Node<E> newNode = new Node<>(null, e, f);
  62.129 +        first = newNode;
  62.130 +        if (f == null)
  62.131 +            last = newNode;
  62.132 +        else
  62.133 +            f.prev = newNode;
  62.134 +        size++;
  62.135 +        modCount++;
  62.136 +    }
  62.137 +
  62.138 +    /**
  62.139 +     * Links e as last element.
  62.140 +     */
  62.141 +    void linkLast(E e) {
  62.142 +        final Node<E> l = last;
  62.143 +        final Node<E> newNode = new Node<>(l, e, null);
  62.144 +        last = newNode;
  62.145 +        if (l == null)
  62.146 +            first = newNode;
  62.147 +        else
  62.148 +            l.next = newNode;
  62.149 +        size++;
  62.150 +        modCount++;
  62.151 +    }
  62.152 +
  62.153 +    /**
  62.154 +     * Inserts element e before non-null Node succ.
  62.155 +     */
  62.156 +    void linkBefore(E e, Node<E> succ) {
  62.157 +        // assert succ != null;
  62.158 +        final Node<E> pred = succ.prev;
  62.159 +        final Node<E> newNode = new Node<>(pred, e, succ);
  62.160 +        succ.prev = newNode;
  62.161 +        if (pred == null)
  62.162 +            first = newNode;
  62.163 +        else
  62.164 +            pred.next = newNode;
  62.165 +        size++;
  62.166 +        modCount++;
  62.167 +    }
  62.168 +
  62.169 +    /**
  62.170 +     * Unlinks non-null first node f.
  62.171 +     */
  62.172 +    private E unlinkFirst(Node<E> f) {
  62.173 +        // assert f == first && f != null;
  62.174 +        final E element = f.item;
  62.175 +        final Node<E> next = f.next;
  62.176 +        f.item = null;
  62.177 +        f.next = null; // help GC
  62.178 +        first = next;
  62.179 +        if (next == null)
  62.180 +            last = null;
  62.181 +        else
  62.182 +            next.prev = null;
  62.183 +        size--;
  62.184 +        modCount++;
  62.185 +        return element;
  62.186 +    }
  62.187 +
  62.188 +    /**
  62.189 +     * Unlinks non-null last node l.
  62.190 +     */
  62.191 +    private E unlinkLast(Node<E> l) {
  62.192 +        // assert l == last && l != null;
  62.193 +        final E element = l.item;
  62.194 +        final Node<E> prev = l.prev;
  62.195 +        l.item = null;
  62.196 +        l.prev = null; // help GC
  62.197 +        last = prev;
  62.198 +        if (prev == null)
  62.199 +            first = null;
  62.200 +        else
  62.201 +            prev.next = null;
  62.202 +        size--;
  62.203 +        modCount++;
  62.204 +        return element;
  62.205 +    }
  62.206 +
  62.207 +    /**
  62.208 +     * Unlinks non-null node x.
  62.209 +     */
  62.210 +    E unlink(Node<E> x) {
  62.211 +        // assert x != null;
  62.212 +        final E element = x.item;
  62.213 +        final Node<E> next = x.next;
  62.214 +        final Node<E> prev = x.prev;
  62.215 +
  62.216 +        if (prev == null) {
  62.217 +            first = next;
  62.218 +        } else {
  62.219 +            prev.next = next;
  62.220 +            x.prev = null;
  62.221 +        }
  62.222 +
  62.223 +        if (next == null) {
  62.224 +            last = prev;
  62.225 +        } else {
  62.226 +            next.prev = prev;
  62.227 +            x.next = null;
  62.228 +        }
  62.229 +
  62.230 +        x.item = null;
  62.231 +        size--;
  62.232 +        modCount++;
  62.233 +        return element;
  62.234 +    }
  62.235 +
  62.236 +    /**
  62.237 +     * Returns the first element in this list.
  62.238 +     *
  62.239 +     * @return the first element in this list
  62.240 +     * @throws NoSuchElementException if this list is empty
  62.241 +     */
  62.242 +    public E getFirst() {
  62.243 +        final Node<E> f = first;
  62.244 +        if (f == null)
  62.245 +            throw new NoSuchElementException();
  62.246 +        return f.item;
  62.247 +    }
  62.248 +
  62.249 +    /**
  62.250 +     * Returns the last element in this list.
  62.251 +     *
  62.252 +     * @return the last element in this list
  62.253 +     * @throws NoSuchElementException if this list is empty
  62.254 +     */
  62.255 +    public E getLast() {
  62.256 +        final Node<E> l = last;
  62.257 +        if (l == null)
  62.258 +            throw new NoSuchElementException();
  62.259 +        return l.item;
  62.260 +    }
  62.261 +
  62.262 +    /**
  62.263 +     * Removes and returns the first element from this list.
  62.264 +     *
  62.265 +     * @return the first element from this list
  62.266 +     * @throws NoSuchElementException if this list is empty
  62.267 +     */
  62.268 +    public E removeFirst() {
  62.269 +        final Node<E> f = first;
  62.270 +        if (f == null)
  62.271 +            throw new NoSuchElementException();
  62.272 +        return unlinkFirst(f);
  62.273 +    }
  62.274 +
  62.275 +    /**
  62.276 +     * Removes and returns the last element from this list.
  62.277 +     *
  62.278 +     * @return the last element from this list
  62.279 +     * @throws NoSuchElementException if this list is empty
  62.280 +     */
  62.281 +    public E removeLast() {
  62.282 +        final Node<E> l = last;
  62.283 +        if (l == null)
  62.284 +            throw new NoSuchElementException();
  62.285 +        return unlinkLast(l);
  62.286 +    }
  62.287 +
  62.288 +    /**
  62.289 +     * Inserts the specified element at the beginning of this list.
  62.290 +     *
  62.291 +     * @param e the element to add
  62.292 +     */
  62.293 +    public void addFirst(E e) {
  62.294 +        linkFirst(e);
  62.295 +    }
  62.296 +
  62.297 +    /**
  62.298 +     * Appends the specified element to the end of this list.
  62.299 +     *
  62.300 +     * <p>This method is equivalent to {@link #add}.
  62.301 +     *
  62.302 +     * @param e the element to add
  62.303 +     */
  62.304 +    public void addLast(E e) {
  62.305 +        linkLast(e);
  62.306 +    }
  62.307 +
  62.308 +    /**
  62.309 +     * Returns {@code true} if this list contains the specified element.
  62.310 +     * More formally, returns {@code true} if and only if this list contains
  62.311 +     * at least one element {@code e} such that
  62.312 +     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
  62.313 +     *
  62.314 +     * @param o element whose presence in this list is to be tested
  62.315 +     * @return {@code true} if this list contains the specified element
  62.316 +     */
  62.317 +    public boolean contains(Object o) {
  62.318 +        return indexOf(o) != -1;
  62.319 +    }
  62.320 +
  62.321 +    /**
  62.322 +     * Returns the number of elements in this list.
  62.323 +     *
  62.324 +     * @return the number of elements in this list
  62.325 +     */
  62.326 +    public int size() {
  62.327 +        return size;
  62.328 +    }
  62.329 +
  62.330 +    /**
  62.331 +     * Appends the specified element to the end of this list.
  62.332 +     *
  62.333 +     * <p>This method is equivalent to {@link #addLast}.
  62.334 +     *
  62.335 +     * @param e element to be appended to this list
  62.336 +     * @return {@code true} (as specified by {@link Collection#add})
  62.337 +     */
  62.338 +    public boolean add(E e) {
  62.339 +        linkLast(e);
  62.340 +        return true;
  62.341 +    }
  62.342 +
  62.343 +    /**
  62.344 +     * Removes the first occurrence of the specified element from this list,
  62.345 +     * if it is present.  If this list does not contain the element, it is
  62.346 +     * unchanged.  More formally, removes the element with the lowest index
  62.347 +     * {@code i} such that
  62.348 +     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
  62.349 +     * (if such an element exists).  Returns {@code true} if this list
  62.350 +     * contained the specified element (or equivalently, if this list
  62.351 +     * changed as a result of the call).
  62.352 +     *
  62.353 +     * @param o element to be removed from this list, if present
  62.354 +     * @return {@code true} if this list contained the specified element
  62.355 +     */
  62.356 +    public boolean remove(Object o) {
  62.357 +        if (o == null) {
  62.358 +            for (Node<E> x = first; x != null; x = x.next) {
  62.359 +                if (x.item == null) {
  62.360 +                    unlink(x);
  62.361 +                    return true;
  62.362 +                }
  62.363 +            }
  62.364 +        } else {
  62.365 +            for (Node<E> x = first; x != null; x = x.next) {
  62.366 +                if (o.equals(x.item)) {
  62.367 +                    unlink(x);
  62.368 +                    return true;
  62.369 +                }
  62.370 +            }
  62.371 +        }
  62.372 +        return false;
  62.373 +    }
  62.374 +
  62.375 +    /**
  62.376 +     * Appends all of the elements in the specified collection to the end of
  62.377 +     * this list, in the order that they are returned by the specified
  62.378 +     * collection's iterator.  The behavior of this operation is undefined if
  62.379 +     * the specified collection is modified while the operation is in
  62.380 +     * progress.  (Note that this will occur if the specified collection is
  62.381 +     * this list, and it's nonempty.)
  62.382 +     *
  62.383 +     * @param c collection containing elements to be added to this list
  62.384 +     * @return {@code true} if this list changed as a result of the call
  62.385 +     * @throws NullPointerException if the specified collection is null
  62.386 +     */
  62.387 +    public boolean addAll(Collection<? extends E> c) {
  62.388 +        return addAll(size, c);
  62.389 +    }
  62.390 +
  62.391 +    /**
  62.392 +     * Inserts all of the elements in the specified collection into this
  62.393 +     * list, starting at the specified position.  Shifts the element
  62.394 +     * currently at that position (if any) and any subsequent elements to
  62.395 +     * the right (increases their indices).  The new elements will appear
  62.396 +     * in the list in the order that they are returned by the
  62.397 +     * specified collection's iterator.
  62.398 +     *
  62.399 +     * @param index index at which to insert the first element
  62.400 +     *              from the specified collection
  62.401 +     * @param c collection containing elements to be added to this list
  62.402 +     * @return {@code true} if this list changed as a result of the call
  62.403 +     * @throws IndexOutOfBoundsException {@inheritDoc}
  62.404 +     * @throws NullPointerException if the specified collection is null
  62.405 +     */
  62.406 +    public boolean addAll(int index, Collection<? extends E> c) {
  62.407 +        checkPositionIndex(index);
  62.408 +
  62.409 +        Object[] a = c.toArray();
  62.410 +        int numNew = a.length;
  62.411 +        if (numNew == 0)
  62.412 +            return false;
  62.413 +
  62.414 +        Node<E> pred, succ;
  62.415 +        if (index == size) {
  62.416 +            succ = null;
  62.417 +            pred = last;
  62.418 +        } else {
  62.419 +            succ = node(index);
  62.420 +            pred = succ.prev;
  62.421 +        }
  62.422 +
  62.423 +        for (Object o : a) {
  62.424 +            @SuppressWarnings("unchecked") E e = (E) o;
  62.425 +            Node<E> newNode = new Node<>(pred, e, null);
  62.426 +            if (pred == null)
  62.427 +                first = newNode;
  62.428 +            else
  62.429 +                pred.next = newNode;
  62.430 +            pred = newNode;
  62.431 +        }
  62.432 +
  62.433 +        if (succ == null) {
  62.434 +            last = pred;
  62.435 +        } else {
  62.436 +            pred.next = succ;
  62.437 +            succ.prev = pred;
  62.438 +        }
  62.439 +
  62.440 +        size += numNew;
  62.441 +        modCount++;
  62.442 +        return true;
  62.443 +    }
  62.444 +
  62.445 +    /**
  62.446 +     * Removes all of the elements from this list.
  62.447 +     * The list will be empty after this call returns.
  62.448 +     */
  62.449 +    public void clear() {
  62.450 +        // Clearing all of the links between nodes is "unnecessary", but:
  62.451 +        // - helps a generational GC if the discarded nodes inhabit
  62.452 +        //   more than one generation
  62.453 +        // - is sure to free memory even if there is a reachable Iterator
  62.454 +        for (Node<E> x = first; x != null; ) {
  62.455 +            Node<E> next = x.next;
  62.456 +            x.item = null;
  62.457 +            x.next = null;
  62.458 +            x.prev = null;
  62.459 +            x = next;
  62.460 +        }
  62.461 +        first = last = null;
  62.462 +        size = 0;
  62.463 +        modCount++;
  62.464 +    }
  62.465 +
  62.466 +
  62.467 +    // Positional Access Operations
  62.468 +
  62.469 +    /**
  62.470 +     * Returns the element at the specified position in this list.
  62.471 +     *
  62.472 +     * @param index index of the element to return
  62.473 +     * @return the element at the specified position in this list
  62.474 +     * @throws IndexOutOfBoundsException {@inheritDoc}
  62.475 +     */
  62.476 +    public E get(int index) {
  62.477 +        checkElementIndex(index);
  62.478 +        return node(index).item;
  62.479 +    }
  62.480 +
  62.481 +    /**
  62.482 +     * Replaces the element at the specified position in this list with the
  62.483 +     * specified element.
  62.484 +     *
  62.485 +     * @param index index of the element to replace
  62.486 +     * @param element element to be stored at the specified position
  62.487 +     * @return the element previously at the specified position
  62.488 +     * @throws IndexOutOfBoundsException {@inheritDoc}
  62.489 +     */
  62.490 +    public E set(int index, E element) {
  62.491 +        checkElementIndex(index);
  62.492 +        Node<E> x = node(index);
  62.493 +        E oldVal = x.item;
  62.494 +        x.item = element;
  62.495 +        return oldVal;
  62.496 +    }
  62.497 +
  62.498 +    /**
  62.499 +     * Inserts the specified element at the specified position in this list.
  62.500 +     * Shifts the element currently at that position (if any) and any
  62.501 +     * subsequent elements to the right (adds one to their indices).
  62.502 +     *
  62.503 +     * @param index index at which the specified element is to be inserted
  62.504 +     * @param element element to be inserted
  62.505 +     * @throws IndexOutOfBoundsException {@inheritDoc}
  62.506 +     */
  62.507 +    public void add(int index, E element) {
  62.508 +        checkPositionIndex(index);
  62.509 +
  62.510 +        if (index == size)
  62.511 +            linkLast(element);
  62.512 +        else
  62.513 +            linkBefore(element, node(index));
  62.514 +    }
  62.515 +
  62.516 +    /**
  62.517 +     * Removes the element at the specified position in this list.  Shifts any
  62.518 +     * subsequent elements to the left (subtracts one from their indices).
  62.519 +     * Returns the element that was removed from the list.
  62.520 +     *
  62.521 +     * @param index the index of the element to be removed
  62.522 +     * @return the element previously at the specified position
  62.523 +     * @throws IndexOutOfBoundsException {@inheritDoc}
  62.524 +     */
  62.525 +    public E remove(int index) {
  62.526 +        checkElementIndex(index);
  62.527 +        return unlink(node(index));
  62.528 +    }
  62.529 +
  62.530 +    /**
  62.531 +     * Tells if the argument is the index of an existing element.
  62.532 +     */
  62.533 +    private boolean isElementIndex(int index) {
  62.534 +        return index >= 0 && index < size;
  62.535 +    }
  62.536 +
  62.537 +    /**
  62.538 +     * Tells if the argument is the index of a valid position for an
  62.539 +     * iterator or an add operation.
  62.540 +     */
  62.541 +    private boolean isPositionIndex(int index) {
  62.542 +        return index >= 0 && index <= size;
  62.543 +    }
  62.544 +
  62.545 +    /**
  62.546 +     * Constructs an IndexOutOfBoundsException detail message.
  62.547 +     * Of the many possible refactorings of the error handling code,
  62.548 +     * this "outlining" performs best with both server and client VMs.
  62.549 +     */
  62.550 +    private String outOfBoundsMsg(int index) {
  62.551 +        return "Index: "+index+", Size: "+size;
  62.552 +    }
  62.553 +
  62.554 +    private void checkElementIndex(int index) {
  62.555 +        if (!isElementIndex(index))
  62.556 +            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  62.557 +    }
  62.558 +
  62.559 +    private void checkPositionIndex(int index) {
  62.560 +        if (!isPositionIndex(index))
  62.561 +            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  62.562 +    }
  62.563 +
  62.564 +    /**
  62.565 +     * Returns the (non-null) Node at the specified element index.
  62.566 +     */
  62.567 +    Node<E> node(int index) {
  62.568 +        // assert isElementIndex(index);
  62.569 +
  62.570 +        if (index < (size >> 1)) {
  62.571 +            Node<E> x = first;
  62.572 +            for (int i = 0; i < index; i++)
  62.573 +                x = x.next;
  62.574 +            return x;
  62.575 +        } else {
  62.576 +            Node<E> x = last;
  62.577 +            for (int i = size - 1; i > index; i--)
  62.578 +                x = x.prev;
  62.579 +            return x;
  62.580 +        }
  62.581 +    }
  62.582 +
  62.583 +    // Search Operations
  62.584 +
  62.585 +    /**
  62.586 +     * Returns the index of the first occurrence of the specified element
  62.587 +     * in this list, or -1 if this list does not contain the element.
  62.588 +     * More formally, returns the lowest index {@code i} such that
  62.589 +     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
  62.590 +     * or -1 if there is no such index.
  62.591 +     *
  62.592 +     * @param o element to search for
  62.593 +     * @return the index of the first occurrence of the specified element in
  62.594 +     *         this list, or -1 if this list does not contain the element
  62.595 +     */
  62.596 +    public int indexOf(Object o) {
  62.597 +        int index = 0;
  62.598 +        if (o == null) {
  62.599 +            for (Node<E> x = first; x != null; x = x.next) {
  62.600 +                if (x.item == null)
  62.601 +                    return index;
  62.602 +                index++;
  62.603 +            }
  62.604 +        } else {
  62.605 +            for (Node<E> x = first; x != null; x = x.next) {
  62.606 +                if (o.equals(x.item))
  62.607 +                    return index;
  62.608 +                index++;
  62.609 +            }
  62.610 +        }
  62.611 +        return -1;
  62.612 +    }
  62.613 +
  62.614 +    /**
  62.615 +     * Returns the index of the last occurrence of the specified element
  62.616 +     * in this list, or -1 if this list does not contain the element.
  62.617 +     * More formally, returns the highest index {@code i} such that
  62.618 +     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
  62.619 +     * or -1 if there is no such index.
  62.620 +     *
  62.621 +     * @param o element to search for
  62.622 +     * @return the index of the last occurrence of the specified element in
  62.623 +     *         this list, or -1 if this list does not contain the element
  62.624 +     */
  62.625 +    public int lastIndexOf(Object o) {
  62.626 +        int index = size;
  62.627 +        if (o == null) {
  62.628 +            for (Node<E> x = last; x != null; x = x.prev) {
  62.629 +                index--;
  62.630 +                if (x.item == null)
  62.631 +                    return index;
  62.632 +            }
  62.633 +        } else {
  62.634 +            for (Node<E> x = last; x != null; x = x.prev) {
  62.635 +                index--;
  62.636 +                if (o.equals(x.item))
  62.637 +                    return index;
  62.638 +            }
  62.639 +        }
  62.640 +        return -1;
  62.641 +    }
  62.642 +
  62.643 +    // Queue operations.
  62.644 +
  62.645 +    /**
  62.646 +     * Retrieves, but does not remove, the head (first element) of this list.
  62.647 +     *
  62.648 +     * @return the head of this list, or {@code null} if this list is empty
  62.649 +     * @since 1.5
  62.650 +     */
  62.651 +    public E peek() {
  62.652 +        final Node<E> f = first;
  62.653 +        return (f == null) ? null : f.item;
  62.654 +    }
  62.655 +
  62.656 +    /**
  62.657 +     * Retrieves, but does not remove, the head (first element) of this list.
  62.658 +     *
  62.659 +     * @return the head of this list
  62.660 +     * @throws NoSuchElementException if this list is empty
  62.661 +     * @since 1.5
  62.662 +     */
  62.663 +    public E element() {
  62.664 +        return getFirst();
  62.665 +    }
  62.666 +
  62.667 +    /**
  62.668 +     * Retrieves and removes the head (first element) of this list.
  62.669 +     *
  62.670 +     * @return the head of this list, or {@code null} if this list is empty
  62.671 +     * @since 1.5
  62.672 +     */
  62.673 +    public E poll() {
  62.674 +        final Node<E> f = first;
  62.675 +        return (f == null) ? null : unlinkFirst(f);
  62.676 +    }
  62.677 +
  62.678 +    /**
  62.679 +     * Retrieves and removes the head (first element) of this list.
  62.680 +     *
  62.681 +     * @return the head of this list
  62.682 +     * @throws NoSuchElementException if this list is empty
  62.683 +     * @since 1.5
  62.684 +     */
  62.685 +    public E remove() {
  62.686 +        return removeFirst();
  62.687 +    }
  62.688 +
  62.689 +    /**
  62.690 +     * Adds the specified element as the tail (last element) of this list.
  62.691 +     *
  62.692 +     * @param e the element to add
  62.693 +     * @return {@code true} (as specified by {@link Queue#offer})
  62.694 +     * @since 1.5
  62.695 +     */
  62.696 +    public boolean offer(E e) {
  62.697 +        return add(e);
  62.698 +    }
  62.699 +
  62.700 +    // Deque operations
  62.701 +    /**
  62.702 +     * Inserts the specified element at the front of this list.
  62.703 +     *
  62.704 +     * @param e the element to insert
  62.705 +     * @return {@code true} (as specified by {@link Deque#offerFirst})
  62.706 +     * @since 1.6
  62.707 +     */
  62.708 +    public boolean offerFirst(E e) {
  62.709 +        addFirst(e);
  62.710 +        return true;
  62.711 +    }
  62.712 +
  62.713 +    /**
  62.714 +     * Inserts the specified element at the end of this list.
  62.715 +     *
  62.716 +     * @param e the element to insert
  62.717 +     * @return {@code true} (as specified by {@link Deque#offerLast})
  62.718 +     * @since 1.6
  62.719 +     */
  62.720 +    public boolean offerLast(E e) {
  62.721 +        addLast(e);
  62.722 +        return true;
  62.723 +    }
  62.724 +
  62.725 +    /**
  62.726 +     * Retrieves, but does not remove, the first element of this list,
  62.727 +     * or returns {@code null} if this list is empty.
  62.728 +     *
  62.729 +     * @return the first element of this list, or {@code null}
  62.730 +     *         if this list is empty
  62.731 +     * @since 1.6
  62.732 +     */
  62.733 +    public E peekFirst() {
  62.734 +        final Node<E> f = first;
  62.735 +        return (f == null) ? null : f.item;
  62.736 +     }
  62.737 +
  62.738 +    /**
  62.739 +     * Retrieves, but does not remove, the last element of this list,
  62.740 +     * or returns {@code null} if this list is empty.
  62.741 +     *
  62.742 +     * @return the last element of this list, or {@code null}
  62.743 +     *         if this list is empty
  62.744 +     * @since 1.6
  62.745 +     */
  62.746 +    public E peekLast() {
  62.747 +        final Node<E> l = last;
  62.748 +        return (l == null) ? null : l.item;
  62.749 +    }
  62.750 +
  62.751 +    /**
  62.752 +     * Retrieves and removes the first element of this list,
  62.753 +     * or returns {@code null} if this list is empty.
  62.754 +     *
  62.755 +     * @return the first element of this list, or {@code null} if
  62.756 +     *     this list is empty
  62.757 +     * @since 1.6
  62.758 +     */
  62.759 +    public E pollFirst() {
  62.760 +        final Node<E> f = first;
  62.761 +        return (f == null) ? null : unlinkFirst(f);
  62.762 +    }
  62.763 +
  62.764 +    /**
  62.765 +     * Retrieves and removes the last element of this list,
  62.766 +     * or returns {@code null} if this list is empty.
  62.767 +     *
  62.768 +     * @return the last element of this list, or {@code null} if
  62.769 +     *     this list is empty
  62.770 +     * @since 1.6
  62.771 +     */
  62.772 +    public E pollLast() {
  62.773 +        final Node<E> l = last;
  62.774 +        return (l == null) ? null : unlinkLast(l);
  62.775 +    }
  62.776 +
  62.777 +    /**
  62.778 +     * Pushes an element onto the stack represented by this list.  In other
  62.779 +     * words, inserts the element at the front of this list.
  62.780 +     *
  62.781 +     * <p>This method is equivalent to {@link #addFirst}.
  62.782 +     *
  62.783 +     * @param e the element to push
  62.784 +     * @since 1.6
  62.785 +     */
  62.786 +    public void push(E e) {
  62.787 +        addFirst(e);
  62.788 +    }
  62.789 +
  62.790 +    /**
  62.791 +     * Pops an element from the stack represented by this list.  In other
  62.792 +     * words, removes and returns the first element of this list.
  62.793 +     *
  62.794 +     * <p>This method is equivalent to {@link #removeFirst()}.
  62.795 +     *
  62.796 +     * @return the element at the front of this list (which is the top
  62.797 +     *         of the stack represented by this list)
  62.798 +     * @throws NoSuchElementException if this list is empty
  62.799 +     * @since 1.6
  62.800 +     */
  62.801 +    public E pop() {
  62.802 +        return removeFirst();
  62.803 +    }
  62.804 +
  62.805 +    /**
  62.806 +     * Removes the first occurrence of the specified element in this
  62.807 +     * list (when traversing the list from head to tail).  If the list
  62.808 +     * does not contain the element, it is unchanged.
  62.809 +     *
  62.810 +     * @param o element to be removed from this list, if present
  62.811 +     * @return {@code true} if the list contained the specified element
  62.812 +     * @since 1.6
  62.813 +     */
  62.814 +    public boolean removeFirstOccurrence(Object o) {
  62.815 +        return remove(o);
  62.816 +    }
  62.817 +
  62.818 +    /**
  62.819 +     * Removes the last occurrence of the specified element in this
  62.820 +     * list (when traversing the list from head to tail).  If the list
  62.821 +     * does not contain the element, it is unchanged.
  62.822 +     *
  62.823 +     * @param o element to be removed from this list, if present
  62.824 +     * @return {@code true} if the list contained the specified element
  62.825 +     * @since 1.6
  62.826 +     */
  62.827 +    public boolean removeLastOccurrence(Object o) {
  62.828 +        if (o == null) {
  62.829 +            for (Node<E> x = last; x != null; x = x.prev) {
  62.830 +                if (x.item == null) {
  62.831 +                    unlink(x);
  62.832 +                    return true;
  62.833 +                }
  62.834 +            }
  62.835 +        } else {
  62.836 +            for (Node<E> x = last; x != null; x = x.prev) {
  62.837 +                if (o.equals(x.item)) {
  62.838 +                    unlink(x);
  62.839 +                    return true;
  62.840 +                }
  62.841 +            }
  62.842 +        }
  62.843 +        return false;
  62.844 +    }
  62.845 +
  62.846 +    /**
  62.847 +     * Returns a list-iterator of the elements in this list (in proper
  62.848 +     * sequence), starting at the specified position in the list.
  62.849 +     * Obeys the general contract of {@code List.listIterator(int)}.<p>
  62.850 +     *
  62.851 +     * The list-iterator is <i>fail-fast</i>: if the list is structurally
  62.852 +     * modified at any time after the Iterator is created, in any way except
  62.853 +     * through the list-iterator's own {@code remove} or {@code add}
  62.854 +     * methods, the list-iterator will throw a
  62.855 +     * {@code ConcurrentModificationException}.  Thus, in the face of
  62.856 +     * concurrent modification, the iterator fails quickly and cleanly, rather
  62.857 +     * than risking arbitrary, non-deterministic behavior at an undetermined
  62.858 +     * time in the future.
  62.859 +     *
  62.860 +     * @param index index of the first element to be returned from the
  62.861 +     *              list-iterator (by a call to {@code next})
  62.862 +     * @return a ListIterator of the elements in this list (in proper
  62.863 +     *         sequence), starting at the specified position in the list
  62.864 +     * @throws IndexOutOfBoundsException {@inheritDoc}
  62.865 +     * @see List#listIterator(int)
  62.866 +     */
  62.867 +    public ListIterator<E> listIterator(int index) {
  62.868 +        checkPositionIndex(index);
  62.869 +        return new ListItr(index);
  62.870 +    }
  62.871 +
  62.872 +    private class ListItr implements ListIterator<E> {
  62.873 +        private Node<E> lastReturned = null;
  62.874 +        private Node<E> next;
  62.875 +        private int nextIndex;
  62.876 +        private int expectedModCount = modCount;
  62.877 +
  62.878 +        ListItr(int index) {
  62.879 +            // assert isPositionIndex(index);
  62.880 +            next = (index == size) ? null : node(index);
  62.881 +            nextIndex = index;
  62.882 +        }
  62.883 +
  62.884 +        public boolean hasNext() {
  62.885 +            return nextIndex < size;
  62.886 +        }
  62.887 +
  62.888 +        public E next() {
  62.889 +            checkForComodification();
  62.890 +            if (!hasNext())
  62.891 +                throw new NoSuchElementException();
  62.892 +
  62.893 +            lastReturned = next;
  62.894 +            next = next.next;
  62.895 +            nextIndex++;
  62.896 +            return lastReturned.item;
  62.897 +        }
  62.898 +
  62.899 +        public boolean hasPrevious() {
  62.900 +            return nextIndex > 0;
  62.901 +        }
  62.902 +
  62.903 +        public E previous() {
  62.904 +            checkForComodification();
  62.905 +            if (!hasPrevious())
  62.906 +                throw new NoSuchElementException();
  62.907 +
  62.908 +            lastReturned = next = (next == null) ? last : next.prev;
  62.909 +            nextIndex--;
  62.910 +            return lastReturned.item;
  62.911 +        }
  62.912 +
  62.913 +        public int nextIndex() {
  62.914 +            return nextIndex;
  62.915 +        }
  62.916 +
  62.917 +        public int previousIndex() {
  62.918 +            return nextIndex - 1;
  62.919 +        }
  62.920 +
  62.921 +        public void remove() {
  62.922 +            checkForComodification();
  62.923 +            if (lastReturned == null)
  62.924 +                throw new IllegalStateException();
  62.925 +
  62.926 +            Node<E> lastNext = lastReturned.next;
  62.927 +            unlink(lastReturned);
  62.928 +            if (next == lastReturned)
  62.929 +                next = lastNext;
  62.930 +            else
  62.931 +                nextIndex--;
  62.932 +            lastReturned = null;
  62.933 +            expectedModCount++;
  62.934 +        }
  62.935 +
  62.936 +        public void set(E e) {
  62.937 +            if (lastReturned == null)
  62.938 +                throw new IllegalStateException();
  62.939 +            checkForComodification();
  62.940 +            lastReturned.item = e;
  62.941 +        }
  62.942 +
  62.943 +        public void add(E e) {
  62.944 +            checkForComodification();
  62.945 +            lastReturned = null;
  62.946 +            if (next == null)
  62.947 +                linkLast(e);
  62.948 +            else
  62.949 +                linkBefore(e, next);
  62.950 +            nextIndex++;
  62.951 +            expectedModCount++;
  62.952 +        }
  62.953 +
  62.954 +        final void checkForComodification() {
  62.955 +            if (modCount != expectedModCount)
  62.956 +                throw new ConcurrentModificationException();
  62.957 +        }
  62.958 +    }
  62.959 +
  62.960 +    private static class Node<E> {
  62.961 +        E item;
  62.962 +        Node<E> next;
  62.963 +        Node<E> prev;
  62.964 +
  62.965 +        Node(Node<E> prev, E element, Node<E> next) {
  62.966 +            this.item = element;
  62.967 +            this.next = next;
  62.968 +            this.prev = prev;
  62.969 +        }
  62.970 +    }
  62.971 +
  62.972 +    /**
  62.973 +     * @since 1.6
  62.974 +     */
  62.975 +    public Iterator<E> descendingIterator() {
  62.976 +        return new DescendingIterator();
  62.977 +    }
  62.978 +
  62.979 +    /**
  62.980 +     * Adapter to provide descending iterators via ListItr.previous
  62.981 +     */
  62.982 +    private class DescendingIterator implements Iterator<E> {
  62.983 +        private final ListItr itr = new ListItr(size());
  62.984 +        public boolean hasNext() {
  62.985 +            return itr.hasPrevious();
  62.986 +        }
  62.987 +        public E next() {
  62.988 +            return itr.previous();
  62.989 +        }
  62.990 +        public void remove() {
  62.991 +            itr.remove();
  62.992 +        }
  62.993 +    }
  62.994 +
  62.995 +    @SuppressWarnings("unchecked")
  62.996 +    private LinkedList<E> superClone() {
  62.997 +        try {
  62.998 +            return (LinkedList<E>) super.clone();
  62.999 +        } catch (CloneNotSupportedException e) {
 62.1000 +            throw new InternalError();
 62.1001 +        }
 62.1002 +    }
 62.1003 +
 62.1004 +    /**
 62.1005 +     * Returns a shallow copy of this {@code LinkedList}. (The elements
 62.1006 +     * themselves are not cloned.)
 62.1007 +     *
 62.1008 +     * @return a shallow copy of this {@code LinkedList} instance
 62.1009 +     */
 62.1010 +    public Object clone() {
 62.1011 +        LinkedList<E> clone = superClone();
 62.1012 +
 62.1013 +        // Put clone into "virgin" state
 62.1014 +        clone.first = clone.last = null;
 62.1015 +        clone.size = 0;
 62.1016 +        clone.modCount = 0;
 62.1017 +
 62.1018 +        // Initialize clone with our elements
 62.1019 +        for (Node<E> x = first; x != null; x = x.next)
 62.1020 +            clone.add(x.item);
 62.1021 +
 62.1022 +        return clone;
 62.1023 +    }
 62.1024 +
 62.1025 +    /**
 62.1026 +     * Returns an array containing all of the elements in this list
 62.1027 +     * in proper sequence (from first to last element).
 62.1028 +     *
 62.1029 +     * <p>The returned array will be "safe" in that no references to it are
 62.1030 +     * maintained by this list.  (In other words, this method must allocate
 62.1031 +     * a new array).  The caller is thus free to modify the returned array.
 62.1032 +     *
 62.1033 +     * <p>This method acts as bridge between array-based and collection-based
 62.1034 +     * APIs.
 62.1035 +     *
 62.1036 +     * @return an array containing all of the elements in this list
 62.1037 +     *         in proper sequence
 62.1038 +     */
 62.1039 +    public Object[] toArray() {
 62.1040 +        Object[] result = new Object[size];
 62.1041 +        int i = 0;
 62.1042 +        for (Node<E> x = first; x != null; x = x.next)
 62.1043 +            result[i++] = x.item;
 62.1044 +        return result;
 62.1045 +    }
 62.1046 +
 62.1047 +    /**
 62.1048 +     * Returns an array containing all of the elements in this list in
 62.1049 +     * proper sequence (from first to last element); the runtime type of
 62.1050 +     * the returned array is that of the specified array.  If the list fits
 62.1051 +     * in the specified array, it is returned therein.  Otherwise, a new
 62.1052 +     * array is allocated with the runtime type of the specified array and
 62.1053 +     * the size of this list.
 62.1054 +     *
 62.1055 +     * <p>If the list fits in the specified array with room to spare (i.e.,
 62.1056 +     * the array has more elements than the list), the element in the array
 62.1057 +     * immediately following the end of the list is set to {@code null}.
 62.1058 +     * (This is useful in determining the length of the list <i>only</i> if
 62.1059 +     * the caller knows that the list does not contain any null elements.)
 62.1060 +     *
 62.1061 +     * <p>Like the {@link #toArray()} method, this method acts as bridge between
 62.1062 +     * array-based and collection-based APIs.  Further, this method allows
 62.1063 +     * precise control over the runtime type of the output array, and may,
 62.1064 +     * under certain circumstances, be used to save allocation costs.
 62.1065 +     *
 62.1066 +     * <p>Suppose {@code x} is a list known to contain only strings.
 62.1067 +     * The following code can be used to dump the list into a newly
 62.1068 +     * allocated array of {@code String}:
 62.1069 +     *
 62.1070 +     * <pre>
 62.1071 +     *     String[] y = x.toArray(new String[0]);</pre>
 62.1072 +     *
 62.1073 +     * Note that {@code toArray(new Object[0])} is identical in function to
 62.1074 +     * {@code toArray()}.
 62.1075 +     *
 62.1076 +     * @param a the array into which the elements of the list are to
 62.1077 +     *          be stored, if it is big enough; otherwise, a new array of the
 62.1078 +     *          same runtime type is allocated for this purpose.
 62.1079 +     * @return an array containing the elements of the list
 62.1080 +     * @throws ArrayStoreException if the runtime type of the specified array
 62.1081 +     *         is not a supertype of the runtime type of every element in
 62.1082 +     *         this list
 62.1083 +     * @throws NullPointerException if the specified array is null
 62.1084 +     */
 62.1085 +    @SuppressWarnings("unchecked")
 62.1086 +    public <T> T[] toArray(T[] a) {
 62.1087 +        if (a.length < size)
 62.1088 +            a = (T[])java.lang.reflect.Array.newInstance(
 62.1089 +                                a.getClass().getComponentType(), size);
 62.1090 +        int i = 0;
 62.1091 +        Object[] result = a;
 62.1092 +        for (Node<E> x = first; x != null; x = x.next)
 62.1093 +            result[i++] = x.item;
 62.1094 +
 62.1095 +        if (a.length > size)
 62.1096 +            a[size] = null;
 62.1097 +
 62.1098 +        return a;
 62.1099 +    }
 62.1100 +
 62.1101 +    private static final long serialVersionUID = 876323262645176354L;
 62.1102 +
 62.1103 +}
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/emul/compact/src/main/java/java/util/PriorityQueue.java	Tue Feb 05 17:04:22 2013 +0100
    63.3 @@ -0,0 +1,731 @@
    63.4 +/*
    63.5 + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    63.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    63.7 + *
    63.8 + * This code is free software; you can redistribute it and/or modify it
    63.9 + * under the terms of the GNU General Public License version 2 only, as
   63.10 + * published by the Free Software Foundation.  Oracle designates this
   63.11 + * particular file as subject to the "Classpath" exception as provided
   63.12 + * by Oracle in the LICENSE file that accompanied this code.
   63.13 + *
   63.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   63.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   63.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   63.17 + * version 2 for more details (a copy is included in the LICENSE file that
   63.18 + * accompanied this code).
   63.19 + *
   63.20 + * You should have received a copy of the GNU General Public License version
   63.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   63.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   63.23 + *
   63.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   63.25 + * or visit www.oracle.com if you need additional information or have any
   63.26 + * questions.
   63.27 + */
   63.28 +
   63.29 +package java.util;
   63.30 +
   63.31 +
   63.32 +/**
   63.33 + * An unbounded priority {@linkplain Queue queue} based on a priority heap.
   63.34 + * The elements of the priority queue are ordered according to their
   63.35 + * {@linkplain Comparable natural ordering}, or by a {@link Comparator}
   63.36 + * provided at queue construction time, depending on which constructor is
   63.37 + * used.  A priority queue does not permit {@code null} elements.
   63.38 + * A priority queue relying on natural ordering also does not permit
   63.39 + * insertion of non-comparable objects (doing so may result in
   63.40 + * {@code ClassCastException}).
   63.41 + *
   63.42 + * <p>The <em>head</em> of this queue is the <em>least</em> element
   63.43 + * with respect to the specified ordering.  If multiple elements are
   63.44 + * tied for least value, the head is one of those elements -- ties are
   63.45 + * broken arbitrarily.  The queue retrieval operations {@code poll},
   63.46 + * {@code remove}, {@code peek}, and {@code element} access the
   63.47 + * element at the head of the queue.
   63.48 + *
   63.49 + * <p>A priority queue is unbounded, but has an internal
   63.50 + * <i>capacity</i> governing the size of an array used to store the
   63.51 + * elements on the queue.  It is always at least as large as the queue
   63.52 + * size.  As elements are added to a priority queue, its capacity
   63.53 + * grows automatically.  The details of the growth policy are not
   63.54 + * specified.
   63.55 + *
   63.56 + * <p>This class and its iterator implement all of the
   63.57 + * <em>optional</em> methods of the {@link Collection} and {@link
   63.58 + * Iterator} interfaces.  The Iterator provided in method {@link
   63.59 + * #iterator()} is <em>not</em> guaranteed to traverse the elements of
   63.60 + * the priority queue in any particular order. If you need ordered
   63.61 + * traversal, consider using {@code Arrays.sort(pq.toArray())}.
   63.62 + *
   63.63 + * <p> <strong>Note that this implementation is not synchronized.</strong>
   63.64 + * Multiple threads should not access a {@code PriorityQueue}
   63.65 + * instance concurrently if any of the threads modifies the queue.
   63.66 + * Instead, use the thread-safe {@link
   63.67 + * java.util.concurrent.PriorityBlockingQueue} class.
   63.68 + *
   63.69 + * <p>Implementation note: this implementation provides
   63.70 + * O(log(n)) time for the enqueing and dequeing methods
   63.71 + * ({@code offer}, {@code poll}, {@code remove()} and {@code add});
   63.72 + * linear time for the {@code remove(Object)} and {@code contains(Object)}
   63.73 + * methods; and constant time for the retrieval methods
   63.74 + * ({@code peek}, {@code element}, and {@code size}).
   63.75 + *
   63.76 + * <p>This class is a member of the
   63.77 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
   63.78 + * Java Collections Framework</a>.
   63.79 + *
   63.80 + * @since 1.5
   63.81 + * @author Josh Bloch, Doug Lea
   63.82 + * @param <E> the type of elements held in this collection
   63.83 + */
   63.84 +public class PriorityQueue<E> extends AbstractQueue<E>
   63.85 +    implements java.io.Serializable {
   63.86 +
   63.87 +    private static final long serialVersionUID = -7720805057305804111L;
   63.88 +
   63.89 +    private static final int DEFAULT_INITIAL_CAPACITY = 11;
   63.90 +
   63.91 +    /**
   63.92 +     * Priority queue represented as a balanced binary heap: the two
   63.93 +     * children of queue[n] are queue[2*n+1] and queue[2*(n+1)].  The
   63.94 +     * priority queue is ordered by comparator, or by the elements'
   63.95 +     * natural ordering, if comparator is null: For each node n in the
   63.96 +     * heap and each descendant d of n, n <= d.  The element with the
   63.97 +     * lowest value is in queue[0], assuming the queue is nonempty.
   63.98 +     */
   63.99 +    private transient Object[] queue;
  63.100 +
  63.101 +    /**
  63.102 +     * The number of elements in the priority queue.
  63.103 +     */
  63.104 +    private int size = 0;
  63.105 +
  63.106 +    /**
  63.107 +     * The comparator, or null if priority queue uses elements'
  63.108 +     * natural ordering.
  63.109 +     */
  63.110 +    private final Comparator<? super E> comparator;
  63.111 +
  63.112 +    /**
  63.113 +     * The number of times this priority queue has been
  63.114 +     * <i>structurally modified</i>.  See AbstractList for gory details.
  63.115 +     */
  63.116 +    private transient int modCount = 0;
  63.117 +
  63.118 +    /**
  63.119 +     * Creates a {@code PriorityQueue} with the default initial
  63.120 +     * capacity (11) that orders its elements according to their
  63.121 +     * {@linkplain Comparable natural ordering}.
  63.122 +     */
  63.123 +    public PriorityQueue() {
  63.124 +        this(DEFAULT_INITIAL_CAPACITY, null);
  63.125 +    }
  63.126 +
  63.127 +    /**
  63.128 +     * Creates a {@code PriorityQueue} with the specified initial
  63.129 +     * capacity that orders its elements according to their
  63.130 +     * {@linkplain Comparable natural ordering}.
  63.131 +     *
  63.132 +     * @param initialCapacity the initial capacity for this priority queue
  63.133 +     * @throws IllegalArgumentException if {@code initialCapacity} is less
  63.134 +     *         than 1
  63.135 +     */
  63.136 +    public PriorityQueue(int initialCapacity) {
  63.137 +        this(initialCapacity, null);
  63.138 +    }
  63.139 +
  63.140 +    /**
  63.141 +     * Creates a {@code PriorityQueue} with the specified initial capacity
  63.142 +     * that orders its elements according to the specified comparator.
  63.143 +     *
  63.144 +     * @param  initialCapacity the initial capacity for this priority queue
  63.145 +     * @param  comparator the comparator that will be used to order this
  63.146 +     *         priority queue.  If {@code null}, the {@linkplain Comparable
  63.147 +     *         natural ordering} of the elements will be used.
  63.148 +     * @throws IllegalArgumentException if {@code initialCapacity} is
  63.149 +     *         less than 1
  63.150 +     */
  63.151 +    public PriorityQueue(int initialCapacity,
  63.152 +                         Comparator<? super E> comparator) {
  63.153 +        // Note: This restriction of at least one is not actually needed,
  63.154 +        // but continues for 1.5 compatibility
  63.155 +        if (initialCapacity < 1)
  63.156 +            throw new IllegalArgumentException();
  63.157 +        this.queue = new Object[initialCapacity];
  63.158 +        this.comparator = comparator;
  63.159 +    }
  63.160 +
  63.161 +    /**
  63.162 +     * Creates a {@code PriorityQueue} containing the elements in the
  63.163 +     * specified collection.  If the specified collection is an instance of
  63.164 +     * a {@link SortedSet} or is another {@code PriorityQueue}, this
  63.165 +     * priority queue will be ordered according to the same ordering.
  63.166 +     * Otherwise, this priority queue will be ordered according to the
  63.167 +     * {@linkplain Comparable natural ordering} of its elements.
  63.168 +     *
  63.169 +     * @param  c the collection whose elements are to be placed
  63.170 +     *         into this priority queue
  63.171 +     * @throws ClassCastException if elements of the specified collection
  63.172 +     *         cannot be compared to one another according to the priority
  63.173 +     *         queue's ordering
  63.174 +     * @throws NullPointerException if the specified collection or any
  63.175 +     *         of its elements are null
  63.176 +     */
  63.177 +    @SuppressWarnings("unchecked")
  63.178 +    public PriorityQueue(Collection<? extends E> c) {
  63.179 +        if (c instanceof SortedSet<?>) {
  63.180 +            SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
  63.181 +            this.comparator = (Comparator<? super E>) ss.comparator();
  63.182 +            initElementsFromCollection(ss);
  63.183 +        }
  63.184 +        else if (c instanceof PriorityQueue<?>) {
  63.185 +            PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
  63.186 +            this.comparator = (Comparator<? super E>) pq.comparator();
  63.187 +            initFromPriorityQueue(pq);
  63.188 +        }
  63.189 +        else {
  63.190 +            this.comparator = null;
  63.191 +            initFromCollection(c);
  63.192 +        }
  63.193 +    }
  63.194 +
  63.195 +    /**
  63.196 +     * Creates a {@code PriorityQueue} containing the elements in the
  63.197 +     * specified priority queue.  This priority queue will be
  63.198 +     * ordered according to the same ordering as the given priority
  63.199 +     * queue.
  63.200 +     *
  63.201 +     * @param  c the priority queue whose elements are to be placed
  63.202 +     *         into this priority queue
  63.203 +     * @throws ClassCastException if elements of {@code c} cannot be
  63.204 +     *         compared to one another according to {@code c}'s
  63.205 +     *         ordering
  63.206 +     * @throws NullPointerException if the specified priority queue or any
  63.207 +     *         of its elements are null
  63.208 +     */
  63.209 +    @SuppressWarnings("unchecked")
  63.210 +    public PriorityQueue(PriorityQueue<? extends E> c) {
  63.211 +        this.comparator = (Comparator<? super E>) c.comparator();
  63.212 +        initFromPriorityQueue(c);
  63.213 +    }
  63.214 +
  63.215 +    /**
  63.216 +     * Creates a {@code PriorityQueue} containing the elements in the
  63.217 +     * specified sorted set.   This priority queue will be ordered
  63.218 +     * according to the same ordering as the given sorted set.
  63.219 +     *
  63.220 +     * @param  c the sorted set whose elements are to be placed
  63.221 +     *         into this priority queue
  63.222 +     * @throws ClassCastException if elements of the specified sorted
  63.223 +     *         set cannot be compared to one another according to the
  63.224 +     *         sorted set's ordering
  63.225 +     * @throws NullPointerException if the specified sorted set or any
  63.226 +     *         of its elements are null
  63.227 +     */
  63.228 +    @SuppressWarnings("unchecked")
  63.229 +    public PriorityQueue(SortedSet<? extends E> c) {
  63.230 +        this.comparator = (Comparator<? super E>) c.comparator();
  63.231 +        initElementsFromCollection(c);
  63.232 +    }
  63.233 +
  63.234 +    private void initFromPriorityQueue(PriorityQueue<? extends E> c) {
  63.235 +        if (c.getClass() == PriorityQueue.class) {
  63.236 +            this.queue = c.toArray();
  63.237 +            this.size = c.size();
  63.238 +        } else {
  63.239 +            initFromCollection(c);
  63.240 +        }
  63.241 +    }
  63.242 +
  63.243 +    private void initElementsFromCollection(Collection<? extends E> c) {
  63.244 +        Object[] a = c.toArray();
  63.245 +        // If c.toArray incorrectly doesn't return Object[], copy it.
  63.246 +        if (a.getClass() != Object[].class)
  63.247 +            a = Arrays.copyOf(a, a.length, Object[].class);
  63.248 +        int len = a.length;
  63.249 +        if (len == 1 || this.comparator != null)
  63.250 +            for (int i = 0; i < len; i++)
  63.251 +                if (a[i] == null)
  63.252 +                    throw new NullPointerException();
  63.253 +        this.queue = a;
  63.254 +        this.size = a.length;
  63.255 +    }
  63.256 +
  63.257 +    /**
  63.258 +     * Initializes queue array with elements from the given Collection.
  63.259 +     *
  63.260 +     * @param c the collection
  63.261 +     */
  63.262 +    private void initFromCollection(Collection<? extends E> c) {
  63.263 +        initElementsFromCollection(c);
  63.264 +        heapify();
  63.265 +    }
  63.266 +
  63.267 +    /**
  63.268 +     * The maximum size of array to allocate.
  63.269 +     * Some VMs reserve some header words in an array.
  63.270 +     * Attempts to allocate larger arrays may result in
  63.271 +     * OutOfMemoryError: Requested array size exceeds VM limit
  63.272 +     */
  63.273 +    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
  63.274 +
  63.275 +    /**
  63.276 +     * Increases the capacity of the array.
  63.277 +     *
  63.278 +     * @param minCapacity the desired minimum capacity
  63.279 +     */
  63.280 +    private void grow(int minCapacity) {
  63.281 +        int oldCapacity = queue.length;
  63.282 +        // Double size if small; else grow by 50%
  63.283 +        int newCapacity = oldCapacity + ((oldCapacity < 64) ?
  63.284 +                                         (oldCapacity + 2) :
  63.285 +                                         (oldCapacity >> 1));
  63.286 +        // overflow-conscious code
  63.287 +        if (newCapacity - MAX_ARRAY_SIZE > 0)
  63.288 +            newCapacity = hugeCapacity(minCapacity);
  63.289 +        queue = Arrays.copyOf(queue, newCapacity);
  63.290 +    }
  63.291 +
  63.292 +    private static int hugeCapacity(int minCapacity) {
  63.293 +        if (minCapacity < 0) // overflow
  63.294 +            throw new OutOfMemoryError();
  63.295 +        return (minCapacity > MAX_ARRAY_SIZE) ?
  63.296 +            Integer.MAX_VALUE :
  63.297 +            MAX_ARRAY_SIZE;
  63.298 +    }
  63.299 +
  63.300 +    /**
  63.301 +     * Inserts the specified element into this priority queue.
  63.302 +     *
  63.303 +     * @return {@code true} (as specified by {@link Collection#add})
  63.304 +     * @throws ClassCastException if the specified element cannot be
  63.305 +     *         compared with elements currently in this priority queue
  63.306 +     *         according to the priority queue's ordering
  63.307 +     * @throws NullPointerException if the specified element is null
  63.308 +     */
  63.309 +    public boolean add(E e) {
  63.310 +        return offer(e);
  63.311 +    }
  63.312 +
  63.313 +    /**
  63.314 +     * Inserts the specified element into this priority queue.
  63.315 +     *
  63.316 +     * @return {@code true} (as specified by {@link Queue#offer})
  63.317 +     * @throws ClassCastException if the specified element cannot be
  63.318 +     *         compared with elements currently in this priority queue
  63.319 +     *         according to the priority queue's ordering
  63.320 +     * @throws NullPointerException if the specified element is null
  63.321 +     */
  63.322 +    public boolean offer(E e) {
  63.323 +        if (e == null)
  63.324 +            throw new NullPointerException();
  63.325 +        modCount++;
  63.326 +        int i = size;
  63.327 +        if (i >= queue.length)
  63.328 +            grow(i + 1);
  63.329 +        size = i + 1;
  63.330 +        if (i == 0)
  63.331 +            queue[0] = e;
  63.332 +        else
  63.333 +            siftUp(i, e);
  63.334 +        return true;
  63.335 +    }
  63.336 +
  63.337 +    public E peek() {
  63.338 +        if (size == 0)
  63.339 +            return null;
  63.340 +        return (E) queue[0];
  63.341 +    }
  63.342 +
  63.343 +    private int indexOf(Object o) {
  63.344 +        if (o != null) {
  63.345 +            for (int i = 0; i < size; i++)
  63.346 +                if (o.equals(queue[i]))
  63.347 +                    return i;
  63.348 +        }
  63.349 +        return -1;
  63.350 +    }
  63.351 +
  63.352 +    /**
  63.353 +     * Removes a single instance of the specified element from this queue,
  63.354 +     * if it is present.  More formally, removes an element {@code e} such
  63.355 +     * that {@code o.equals(e)}, if this queue contains one or more such
  63.356 +     * elements.  Returns {@code true} if and only if this queue contained
  63.357 +     * the specified element (or equivalently, if this queue changed as a
  63.358 +     * result of the call).
  63.359 +     *
  63.360 +     * @param o element to be removed from this queue, if present
  63.361 +     * @return {@code true} if this queue changed as a result of the call
  63.362 +     */
  63.363 +    public boolean remove(Object o) {
  63.364 +        int i = indexOf(o);
  63.365 +        if (i == -1)
  63.366 +            return false;
  63.367 +        else {
  63.368 +            removeAt(i);
  63.369 +            return true;
  63.370 +        }
  63.371 +    }
  63.372 +
  63.373 +    /**
  63.374 +     * Version of remove using reference equality, not equals.
  63.375 +     * Needed by iterator.remove.
  63.376 +     *
  63.377 +     * @param o element to be removed from this queue, if present
  63.378 +     * @return {@code true} if removed
  63.379 +     */
  63.380 +    boolean removeEq(Object o) {
  63.381 +        for (int i = 0; i < size; i++) {
  63.382 +            if (o == queue[i]) {
  63.383 +                removeAt(i);
  63.384 +                return true;
  63.385 +            }
  63.386 +        }
  63.387 +        return false;
  63.388 +    }
  63.389 +
  63.390 +    /**
  63.391 +     * Returns {@code true} if this queue contains the specified element.
  63.392 +     * More formally, returns {@code true} if and only if this queue contains
  63.393 +     * at least one element {@code e} such that {@code o.equals(e)}.
  63.394 +     *
  63.395 +     * @param o object to be checked for containment in this queue
  63.396 +     * @return {@code true} if this queue contains the specified element
  63.397 +     */
  63.398 +    public boolean contains(Object o) {
  63.399 +        return indexOf(o) != -1;
  63.400 +    }
  63.401 +
  63.402 +    /**
  63.403 +     * Returns an array containing all of the elements in this queue.
  63.404 +     * The elements are in no particular order.
  63.405 +     *
  63.406 +     * <p>The returned array will be "safe" in that no references to it are
  63.407 +     * maintained by this queue.  (In other words, this method must allocate
  63.408 +     * a new array).  The caller is thus free to modify the returned array.
  63.409 +     *
  63.410 +     * <p>This method acts as bridge between array-based and collection-based
  63.411 +     * APIs.
  63.412 +     *
  63.413 +     * @return an array containing all of the elements in this queue
  63.414 +     */
  63.415 +    public Object[] toArray() {
  63.416 +        return Arrays.copyOf(queue, size);
  63.417 +    }
  63.418 +
  63.419 +    /**
  63.420 +     * Returns an array containing all of the elements in this queue; the
  63.421 +     * runtime type of the returned array is that of the specified array.
  63.422 +     * The returned array elements are in no particular order.
  63.423 +     * If the queue fits in the specified array, it is returned therein.
  63.424 +     * Otherwise, a new array is allocated with the runtime type of the
  63.425 +     * specified array and the size of this queue.
  63.426 +     *
  63.427 +     * <p>If the queue fits in the specified array with room to spare
  63.428 +     * (i.e., the array has more elements than the queue), the element in
  63.429 +     * the array immediately following the end of the collection is set to
  63.430 +     * {@code null}.
  63.431 +     *
  63.432 +     * <p>Like the {@link #toArray()} method, this method acts as bridge between
  63.433 +     * array-based and collection-based APIs.  Further, this method allows
  63.434 +     * precise control over the runtime type of the output array, and may,
  63.435 +     * under certain circumstances, be used to save allocation costs.
  63.436 +     *
  63.437 +     * <p>Suppose <tt>x</tt> is a queue known to contain only strings.
  63.438 +     * The following code can be used to dump the queue into a newly
  63.439 +     * allocated array of <tt>String</tt>:
  63.440 +     *
  63.441 +     * <pre>
  63.442 +     *     String[] y = x.toArray(new String[0]);</pre>
  63.443 +     *
  63.444 +     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
  63.445 +     * <tt>toArray()</tt>.
  63.446 +     *
  63.447 +     * @param a the array into which the elements of the queue are to
  63.448 +     *          be stored, if it is big enough; otherwise, a new array of the
  63.449 +     *          same runtime type is allocated for this purpose.
  63.450 +     * @return an array containing all of the elements in this queue
  63.451 +     * @throws ArrayStoreException if the runtime type of the specified array
  63.452 +     *         is not a supertype of the runtime type of every element in
  63.453 +     *         this queue
  63.454 +     * @throws NullPointerException if the specified array is null
  63.455 +     */
  63.456 +    public <T> T[] toArray(T[] a) {
  63.457 +        if (a.length < size)
  63.458 +            // Make a new array of a's runtime type, but my contents:
  63.459 +            return (T[]) Arrays.copyOf(queue, size, a.getClass());
  63.460 +        System.arraycopy(queue, 0, a, 0, size);
  63.461 +        if (a.length > size)
  63.462 +            a[size] = null;
  63.463 +        return a;
  63.464 +    }
  63.465 +
  63.466 +    /**
  63.467 +     * Returns an iterator over the elements in this queue. The iterator
  63.468 +     * does not return the elements in any particular order.
  63.469 +     *
  63.470 +     * @return an iterator over the elements in this queue
  63.471 +     */
  63.472 +    public Iterator<E> iterator() {
  63.473 +        return new Itr();
  63.474 +    }
  63.475 +
  63.476 +    private final class Itr implements Iterator<E> {
  63.477 +        /**
  63.478 +         * Index (into queue array) of element to be returned by
  63.479 +         * subsequent call to next.
  63.480 +         */
  63.481 +        private int cursor = 0;
  63.482 +
  63.483 +        /**
  63.484 +         * Index of element returned by most recent call to next,
  63.485 +         * unless that element came from the forgetMeNot list.
  63.486 +         * Set to -1 if element is deleted by a call to remove.
  63.487 +         */
  63.488 +        private int lastRet = -1;
  63.489 +
  63.490 +        /**
  63.491 +         * A queue of elements that were moved from the unvisited portion of
  63.492 +         * the heap into the visited portion as a result of "unlucky" element
  63.493 +         * removals during the iteration.  (Unlucky element removals are those
  63.494 +         * that require a siftup instead of a siftdown.)  We must visit all of
  63.495 +         * the elements in this list to complete the iteration.  We do this
  63.496 +         * after we've completed the "normal" iteration.
  63.497 +         *
  63.498 +         * We expect that most iterations, even those involving removals,
  63.499 +         * will not need to store elements in this field.
  63.500 +         */
  63.501 +        private ArrayDeque<E> forgetMeNot = null;
  63.502 +
  63.503 +        /**
  63.504 +         * Element returned by the most recent call to next iff that
  63.505 +         * element was drawn from the forgetMeNot list.
  63.506 +         */
  63.507 +        private E lastRetElt = null;
  63.508 +
  63.509 +        /**
  63.510 +         * The modCount value that the iterator believes that the backing
  63.511 +         * Queue should have.  If this expectation is violated, the iterator
  63.512 +         * has detected concurrent modification.
  63.513 +         */
  63.514 +        private int expectedModCount = modCount;
  63.515 +
  63.516 +        public boolean hasNext() {
  63.517 +            return cursor < size ||
  63.518 +                (forgetMeNot != null && !forgetMeNot.isEmpty());
  63.519 +        }
  63.520 +
  63.521 +        public E next() {
  63.522 +            if (expectedModCount != modCount)
  63.523 +                throw new ConcurrentModificationException();
  63.524 +            if (cursor < size)
  63.525 +                return (E) queue[lastRet = cursor++];
  63.526 +            if (forgetMeNot != null) {
  63.527 +                lastRet = -1;
  63.528 +                lastRetElt = forgetMeNot.poll();
  63.529 +                if (lastRetElt != null)
  63.530 +                    return lastRetElt;
  63.531 +            }
  63.532 +            throw new NoSuchElementException();
  63.533 +        }
  63.534 +
  63.535 +        public void remove() {
  63.536 +            if (expectedModCount != modCount)
  63.537 +                throw new ConcurrentModificationException();
  63.538 +            if (lastRet != -1) {
  63.539 +                E moved = PriorityQueue.this.removeAt(lastRet);
  63.540 +                lastRet = -1;
  63.541 +                if (moved == null)
  63.542 +                    cursor--;
  63.543 +                else {
  63.544 +                    if (forgetMeNot == null)
  63.545 +                        forgetMeNot = new ArrayDeque<>();
  63.546 +                    forgetMeNot.add(moved);
  63.547 +                }
  63.548 +            } else if (lastRetElt != null) {
  63.549 +                PriorityQueue.this.removeEq(lastRetElt);
  63.550 +                lastRetElt = null;
  63.551 +            } else {
  63.552 +                throw new IllegalStateException();
  63.553 +            }
  63.554 +            expectedModCount = modCount;
  63.555 +        }
  63.556 +    }
  63.557 +
  63.558 +    public int size() {
  63.559 +        return size;
  63.560 +    }
  63.561 +
  63.562 +    /**
  63.563 +     * Removes all of the elements from this priority queue.
  63.564 +     * The queue will be empty after this call returns.
  63.565 +     */
  63.566 +    public void clear() {
  63.567 +        modCount++;
  63.568 +        for (int i = 0; i < size; i++)
  63.569 +            queue[i] = null;
  63.570 +        size = 0;
  63.571 +    }
  63.572 +
  63.573 +    public E poll() {
  63.574 +        if (size == 0)
  63.575 +            return null;
  63.576 +        int s = --size;
  63.577 +        modCount++;
  63.578 +        E result = (E) queue[0];
  63.579 +        E x = (E) queue[s];
  63.580 +        queue[s] = null;
  63.581 +        if (s != 0)
  63.582 +            siftDown(0, x);
  63.583 +        return result;
  63.584 +    }
  63.585 +
  63.586 +    /**
  63.587 +     * Removes the ith element from queue.
  63.588 +     *
  63.589 +     * Normally this method leaves the elements at up to i-1,
  63.590 +     * inclusive, untouched.  Under these circumstances, it returns
  63.591 +     * null.  Occasionally, in order to maintain the heap invariant,
  63.592 +     * it must swap a later element of the list with one earlier than
  63.593 +     * i.  Under these circumstances, this method returns the element
  63.594 +     * that was previously at the end of the list and is now at some
  63.595 +     * position before i. This fact is used by iterator.remove so as to
  63.596 +     * avoid missing traversing elements.
  63.597 +     */
  63.598 +    private E removeAt(int i) {
  63.599 +        assert i >= 0 && i < size;
  63.600 +        modCount++;
  63.601 +        int s = --size;
  63.602 +        if (s == i) // removed last element
  63.603 +            queue[i] = null;
  63.604 +        else {
  63.605 +            E moved = (E) queue[s];
  63.606 +            queue[s] = null;
  63.607 +            siftDown(i, moved);
  63.608 +            if (queue[i] == moved) {
  63.609 +                siftUp(i, moved);
  63.610 +                if (queue[i] != moved)
  63.611 +                    return moved;
  63.612 +            }
  63.613 +        }
  63.614 +        return null;
  63.615 +    }
  63.616 +
  63.617 +    /**
  63.618 +     * Inserts item x at position k, maintaining heap invariant by
  63.619 +     * promoting x up the tree until it is greater than or equal to
  63.620 +     * its parent, or is the root.
  63.621 +     *
  63.622 +     * To simplify and speed up coercions and comparisons. the
  63.623 +     * Comparable and Comparator versions are separated into different
  63.624 +     * methods that are otherwise identical. (Similarly for siftDown.)
  63.625 +     *
  63.626 +     * @param k the position to fill
  63.627 +     * @param x the item to insert
  63.628 +     */
  63.629 +    private void siftUp(int k, E x) {
  63.630 +        if (comparator != null)
  63.631 +            siftUpUsingComparator(k, x);
  63.632 +        else
  63.633 +            siftUpComparable(k, x);
  63.634 +    }
  63.635 +
  63.636 +    private void siftUpComparable(int k, E x) {
  63.637 +        Comparable<? super E> key = (Comparable<? super E>) x;
  63.638 +        while (k > 0) {
  63.639 +            int parent = (k - 1) >>> 1;
  63.640 +            Object e = queue[parent];
  63.641 +            if (key.compareTo((E) e) >= 0)
  63.642 +                break;
  63.643 +            queue[k] = e;
  63.644 +            k = parent;
  63.645 +        }
  63.646 +        queue[k] = key;
  63.647 +    }
  63.648 +
  63.649 +    private void siftUpUsingComparator(int k, E x) {
  63.650 +        while (k > 0) {
  63.651 +            int parent = (k - 1) >>> 1;
  63.652 +            Object e = queue[parent];
  63.653 +            if (comparator.compare(x, (E) e) >= 0)
  63.654 +                break;
  63.655 +            queue[k] = e;
  63.656 +            k = parent;
  63.657 +        }
  63.658 +        queue[k] = x;
  63.659 +    }
  63.660 +
  63.661 +    /**
  63.662 +     * Inserts item x at position k, maintaining heap invariant by
  63.663 +     * demoting x down the tree repeatedly until it is less than or
  63.664 +     * equal to its children or is a leaf.
  63.665 +     *
  63.666 +     * @param k the position to fill
  63.667 +     * @param x the item to insert
  63.668 +     */
  63.669 +    private void siftDown(int k, E x) {
  63.670 +        if (comparator != null)
  63.671 +            siftDownUsingComparator(k, x);
  63.672 +        else
  63.673 +            siftDownComparable(k, x);
  63.674 +    }
  63.675 +
  63.676 +    private void siftDownComparable(int k, E x) {
  63.677 +        Comparable<? super E> key = (Comparable<? super E>)x;
  63.678 +        int half = size >>> 1;        // loop while a non-leaf
  63.679 +        while (k < half) {
  63.680 +            int child = (k << 1) + 1; // assume left child is least
  63.681 +            Object c = queue[child];
  63.682 +            int right = child + 1;
  63.683 +            if (right < size &&
  63.684 +                ((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
  63.685 +                c = queue[child = right];
  63.686 +            if (key.compareTo((E) c) <= 0)
  63.687 +                break;
  63.688 +            queue[k] = c;
  63.689 +            k = child;
  63.690 +        }
  63.691 +        queue[k] = key;
  63.692 +    }
  63.693 +
  63.694 +    private void siftDownUsingComparator(int k, E x) {
  63.695 +        int half = size >>> 1;
  63.696 +        while (k < half) {
  63.697 +            int child = (k << 1) + 1;
  63.698 +            Object c = queue[child];
  63.699 +            int right = child + 1;
  63.700 +            if (right < size &&
  63.701 +                comparator.compare((E) c, (E) queue[right]) > 0)
  63.702 +                c = queue[child = right];
  63.703 +            if (comparator.compare(x, (E) c) <= 0)
  63.704 +                break;
  63.705 +            queue[k] = c;
  63.706 +            k = child;
  63.707 +        }
  63.708 +        queue[k] = x;
  63.709 +    }
  63.710 +
  63.711 +    /**
  63.712 +     * Establishes the heap invariant (described above) in the entire tree,
  63.713 +     * assuming nothing about the order of the elements prior to the call.
  63.714 +     */
  63.715 +    private void heapify() {
  63.716 +        for (int i = (size >>> 1) - 1; i >= 0; i--)
  63.717 +            siftDown(i, (E) queue[i]);
  63.718 +    }
  63.719 +
  63.720 +    /**
  63.721 +     * Returns the comparator used to order the elements in this
  63.722 +     * queue, or {@code null} if this queue is sorted according to
  63.723 +     * the {@linkplain Comparable natural ordering} of its elements.
  63.724 +     *
  63.725 +     * @return the comparator used to order this queue, or
  63.726 +     *         {@code null} if this queue is sorted according to the
  63.727 +     *         natural ordering of its elements
  63.728 +     */
  63.729 +    public Comparator<? super E> comparator() {
  63.730 +        return comparator;
  63.731 +    }
  63.732 +
  63.733 +
  63.734 +}
    64.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.2 +++ b/emul/compact/src/main/java/java/util/Queue.java	Tue Feb 05 17:04:22 2013 +0100
    64.3 @@ -0,0 +1,218 @@
    64.4 +/*
    64.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    64.6 + *
    64.7 + * This code is free software; you can redistribute it and/or modify it
    64.8 + * under the terms of the GNU General Public License version 2 only, as
    64.9 + * published by the Free Software Foundation.  Oracle designates this
   64.10 + * particular file as subject to the "Classpath" exception as provided
   64.11 + * by Oracle in the LICENSE file that accompanied this code.
   64.12 + *
   64.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
   64.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   64.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   64.16 + * version 2 for more details (a copy is included in the LICENSE file that
   64.17 + * accompanied this code).
   64.18 + *
   64.19 + * You should have received a copy of the GNU General Public License version
   64.20 + * 2 along with this work; if not, write to the Free Software Foundation,
   64.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   64.22 + *
   64.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   64.24 + * or visit www.oracle.com if you need additional information or have any
   64.25 + * questions.
   64.26 + */
   64.27 +
   64.28 +/*
   64.29 + * This file is available under and governed by the GNU General Public
   64.30 + * License version 2 only, as published by the Free Software Foundation.
   64.31 + * However, the following notice accompanied the original version of this
   64.32 + * file:
   64.33 + *
   64.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
   64.35 + * Expert Group and released to the public domain, as explained at
   64.36 + * http://creativecommons.org/publicdomain/zero/1.0/
   64.37 + */
   64.38 +
   64.39 +package java.util;
   64.40 +
   64.41 +/**
   64.42 + * A collection designed for holding elements prior to processing.
   64.43 + * Besides basic {@link java.util.Collection Collection} operations,
   64.44 + * queues provide additional insertion, extraction, and inspection
   64.45 + * operations.  Each of these methods exists in two forms: one throws
   64.46 + * an exception if the operation fails, the other returns a special
   64.47 + * value (either <tt>null</tt> or <tt>false</tt>, depending on the
   64.48 + * operation).  The latter form of the insert operation is designed
   64.49 + * specifically for use with capacity-restricted <tt>Queue</tt>
   64.50 + * implementations; in most implementations, insert operations cannot
   64.51 + * fail.
   64.52 + *
   64.53 + * <p>
   64.54 + * <table BORDER CELLPADDING=3 CELLSPACING=1>
   64.55 + *  <tr>
   64.56 + *    <td></td>
   64.57 + *    <td ALIGN=CENTER><em>Throws exception</em></td>
   64.58 + *    <td ALIGN=CENTER><em>Returns special value</em></td>
   64.59 + *  </tr>
   64.60 + *  <tr>
   64.61 + *    <td><b>Insert</b></td>
   64.62 + *    <td>{@link #add add(e)}</td>
   64.63 + *    <td>{@link #offer offer(e)}</td>
   64.64 + *  </tr>
   64.65 + *  <tr>
   64.66 + *    <td><b>Remove</b></td>
   64.67 + *    <td>{@link #remove remove()}</td>
   64.68 + *    <td>{@link #poll poll()}</td>
   64.69 + *  </tr>
   64.70 + *  <tr>
   64.71 + *    <td><b>Examine</b></td>
   64.72 + *    <td>{@link #element element()}</td>
   64.73 + *    <td>{@link #peek peek()}</td>
   64.74 + *  </tr>
   64.75 + * </table>
   64.76 + *
   64.77 + * <p>Queues typically, but do not necessarily, order elements in a
   64.78 + * FIFO (first-in-first-out) manner.  Among the exceptions are
   64.79 + * priority queues, which order elements according to a supplied
   64.80 + * comparator, or the elements' natural ordering, and LIFO queues (or
   64.81 + * stacks) which order the elements LIFO (last-in-first-out).
   64.82 + * Whatever the ordering used, the <em>head</em> of the queue is that
   64.83 + * element which would be removed by a call to {@link #remove() } or
   64.84 + * {@link #poll()}.  In a FIFO queue, all new elements are inserted at
   64.85 + * the <em> tail</em> of the queue. Other kinds of queues may use
   64.86 + * different placement rules.  Every <tt>Queue</tt> implementation
   64.87 + * must specify its ordering properties.
   64.88 + *
   64.89 + * <p>The {@link #offer offer} method inserts an element if possible,
   64.90 + * otherwise returning <tt>false</tt>.  This differs from the {@link
   64.91 + * java.util.Collection#add Collection.add} method, which can fail to
   64.92 + * add an element only by throwing an unchecked exception.  The
   64.93 + * <tt>offer</tt> method is designed for use when failure is a normal,
   64.94 + * rather than exceptional occurrence, for example, in fixed-capacity
   64.95 + * (or &quot;bounded&quot;) queues.
   64.96 + *
   64.97 + * <p>The {@link #remove()} and {@link #poll()} methods remove and
   64.98 + * return the head of the queue.
   64.99 + * Exactly which element is removed from the queue is a
  64.100 + * function of the queue's ordering policy, which differs from
  64.101 + * implementation to implementation. The <tt>remove()</tt> and
  64.102 + * <tt>poll()</tt> methods differ only in their behavior when the
  64.103 + * queue is empty: the <tt>remove()</tt> method throws an exception,
  64.104 + * while the <tt>poll()</tt> method returns <tt>null</tt>.
  64.105 + *
  64.106 + * <p>The {@link #element()} and {@link #peek()} methods return, but do
  64.107 + * not remove, the head of the queue.
  64.108 + *
  64.109 + * <p>The <tt>Queue</tt> interface does not define the <i>blocking queue
  64.110 + * methods</i>, which are common in concurrent programming.  These methods,
  64.111 + * which wait for elements to appear or for space to become available, are
  64.112 + * defined in the {@link java.util.concurrent.BlockingQueue} interface, which
  64.113 + * extends this interface.
  64.114 + *
  64.115 + * <p><tt>Queue</tt> implementations generally do not allow insertion
  64.116 + * of <tt>null</tt> elements, although some implementations, such as
  64.117 + * {@link LinkedList}, do not prohibit insertion of <tt>null</tt>.
  64.118 + * Even in the implementations that permit it, <tt>null</tt> should
  64.119 + * not be inserted into a <tt>Queue</tt>, as <tt>null</tt> is also
  64.120 + * used as a special return value by the <tt>poll</tt> method to
  64.121 + * indicate that the queue contains no elements.
  64.122 + *
  64.123 + * <p><tt>Queue</tt> implementations generally do not define
  64.124 + * element-based versions of methods <tt>equals</tt> and
  64.125 + * <tt>hashCode</tt> but instead inherit the identity based versions
  64.126 + * from class <tt>Object</tt>, because element-based equality is not
  64.127 + * always well-defined for queues with the same elements but different
  64.128 + * ordering properties.
  64.129 + *
  64.130 + *
  64.131 + * <p>This interface is a member of the
  64.132 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
  64.133 + * Java Collections Framework</a>.
  64.134 + *
  64.135 + * @see java.util.Collection
  64.136 + * @see LinkedList
  64.137 + * @see PriorityQueue
  64.138 + * @see java.util.concurrent.LinkedBlockingQueue
  64.139 + * @see java.util.concurrent.BlockingQueue
  64.140 + * @see java.util.concurrent.ArrayBlockingQueue
  64.141 + * @see java.util.concurrent.LinkedBlockingQueue
  64.142 + * @see java.util.concurrent.PriorityBlockingQueue
  64.143 + * @since 1.5
  64.144 + * @author Doug Lea
  64.145 + * @param <E> the type of elements held in this collection
  64.146 + */
  64.147 +public interface Queue<E> extends Collection<E> {
  64.148 +    /**
  64.149 +     * Inserts the specified element into this queue if it is possible to do so
  64.150 +     * immediately without violating capacity restrictions, returning
  64.151 +     * <tt>true</tt> upon success and throwing an <tt>IllegalStateException</tt>
  64.152 +     * if no space is currently available.
  64.153 +     *
  64.154 +     * @param e the element to add
  64.155 +     * @return <tt>true</tt> (as specified by {@link Collection#add})
  64.156 +     * @throws IllegalStateException if the element cannot be added at this
  64.157 +     *         time due to capacity restrictions
  64.158 +     * @throws ClassCastException if the class of the specified element
  64.159 +     *         prevents it from being added to this queue
  64.160 +     * @throws NullPointerException if the specified element is null and
  64.161 +     *         this queue does not permit null elements
  64.162 +     * @throws IllegalArgumentException if some property of this element
  64.163 +     *         prevents it from being added to this queue
  64.164 +     */
  64.165 +    boolean add(E e);
  64.166 +
  64.167 +    /**
  64.168 +     * Inserts the specified element into this queue if it is possible to do
  64.169 +     * so immediately without violating capacity restrictions.
  64.170 +     * When using a capacity-restricted queue, this method is generally
  64.171 +     * preferable to {@link #add}, which can fail to insert an element only
  64.172 +     * by throwing an exception.
  64.173 +     *
  64.174 +     * @param e the element to add
  64.175 +     * @return <tt>true</tt> if the element was added to this queue, else
  64.176 +     *         <tt>false</tt>
  64.177 +     * @throws ClassCastException if the class of the specified element
  64.178 +     *         prevents it from being added to this queue
  64.179 +     * @throws NullPointerException if the specified element is null and
  64.180 +     *         this queue does not permit null elements
  64.181 +     * @throws IllegalArgumentException if some property of this element
  64.182 +     *         prevents it from being added to this queue
  64.183 +     */
  64.184 +    boolean offer(E e);
  64.185 +
  64.186 +    /**
  64.187 +     * Retrieves and removes the head of this queue.  This method differs
  64.188 +     * from {@link #poll poll} only in that it throws an exception if this
  64.189 +     * queue is empty.
  64.190 +     *
  64.191 +     * @return the head of this queue
  64.192 +     * @throws NoSuchElementException if this queue is empty
  64.193 +     */
  64.194 +    E remove();
  64.195 +
  64.196 +    /**
  64.197 +     * Retrieves and removes the head of this queue,
  64.198 +     * or returns <tt>null</tt> if this queue is empty.
  64.199 +     *
  64.200 +     * @return the head of this queue, or <tt>null</tt> if this queue is empty
  64.201 +     */
  64.202 +    E poll();
  64.203 +
  64.204 +    /**
  64.205 +     * Retrieves, but does not remove, the head of this queue.  This method
  64.206 +     * differs from {@link #peek peek} only in that it throws an exception
  64.207 +     * if this queue is empty.
  64.208 +     *
  64.209 +     * @return the head of this queue
  64.210 +     * @throws NoSuchElementException if this queue is empty
  64.211 +     */
  64.212 +    E element();
  64.213 +
  64.214 +    /**
  64.215 +     * Retrieves, but does not remove, the head of this queue,
  64.216 +     * or returns <tt>null</tt> if this queue is empty.
  64.217 +     *
  64.218 +     * @return the head of this queue, or <tt>null</tt> if this queue is empty
  64.219 +     */
  64.220 +    E peek();
  64.221 +}
    65.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.2 +++ b/emul/compact/src/main/java/java/util/Random.java	Tue Feb 05 17:04:22 2013 +0100
    65.3 @@ -0,0 +1,503 @@
    65.4 +/*
    65.5 + * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
    65.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    65.7 + *
    65.8 + * This code is free software; you can redistribute it and/or modify it
    65.9 + * under the terms of the GNU General Public License version 2 only, as
   65.10 + * published by the Free Software Foundation.  Oracle designates this
   65.11 + * particular file as subject to the "Classpath" exception as provided
   65.12 + * by Oracle in the LICENSE file that accompanied this code.
   65.13 + *
   65.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   65.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   65.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   65.17 + * version 2 for more details (a copy is included in the LICENSE file that
   65.18 + * accompanied this code).
   65.19 + *
   65.20 + * You should have received a copy of the GNU General Public License version
   65.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   65.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   65.23 + *
   65.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   65.25 + * or visit www.oracle.com if you need additional information or have any
   65.26 + * questions.
   65.27 + */
   65.28 +
   65.29 +package java.util;
   65.30 +
   65.31 +import org.apidesign.bck2brwsr.emul.lang.System;
   65.32 +
   65.33 +/**
   65.34 + * An instance of this class is used to generate a stream of
   65.35 + * pseudorandom numbers. The class uses a 48-bit seed, which is
   65.36 + * modified using a linear congruential formula. (See Donald Knuth,
   65.37 + * <i>The Art of Computer Programming, Volume 2</i>, Section 3.2.1.)
   65.38 + * <p>
   65.39 + * If two instances of {@code Random} are created with the same
   65.40 + * seed, and the same sequence of method calls is made for each, they
   65.41 + * will generate and return identical sequences of numbers. In order to
   65.42 + * guarantee this property, particular algorithms are specified for the
   65.43 + * class {@code Random}. Java implementations must use all the algorithms
   65.44 + * shown here for the class {@code Random}, for the sake of absolute
   65.45 + * portability of Java code. However, subclasses of class {@code Random}
   65.46 + * are permitted to use other algorithms, so long as they adhere to the
   65.47 + * general contracts for all the methods.
   65.48 + * <p>
   65.49 + * The algorithms implemented by class {@code Random} use a
   65.50 + * {@code protected} utility method that on each invocation can supply
   65.51 + * up to 32 pseudorandomly generated bits.
   65.52 + * <p>
   65.53 + * Many applications will find the method {@link Math#random} simpler to use.
   65.54 + *
   65.55 + * <p>Instances of {@code java.util.Random} are threadsafe.
   65.56 + * However, the concurrent use of the same {@code java.util.Random}
   65.57 + * instance across threads may encounter contention and consequent
   65.58 + * poor performance. Consider instead using
   65.59 + * {@link java.util.concurrent.ThreadLocalRandom} in multithreaded
   65.60 + * designs.
   65.61 + *
   65.62 + * <p>Instances of {@code java.util.Random} are not cryptographically
   65.63 + * secure.  Consider instead using {@link java.security.SecureRandom} to
   65.64 + * get a cryptographically secure pseudo-random number generator for use
   65.65 + * by security-sensitive applications.
   65.66 + *
   65.67 + * @author  Frank Yellin
   65.68 + * @since   1.0
   65.69 + */
   65.70 +public
   65.71 +class Random implements java.io.Serializable {
   65.72 +    /** use serialVersionUID from JDK 1.1 for interoperability */
   65.73 +    static final long serialVersionUID = 3905348978240129619L;
   65.74 +
   65.75 +    /**
   65.76 +     * The internal state associated with this pseudorandom number generator.
   65.77 +     * (The specs for the methods in this class describe the ongoing
   65.78 +     * computation of this value.)
   65.79 +     */
   65.80 +    private long seed;
   65.81 +
   65.82 +    private static final long multiplier = 0x5DEECE66DL;
   65.83 +    private static final long addend = 0xBL;
   65.84 +    private static final long mask = (1L << 48) - 1;
   65.85 +
   65.86 +    /**
   65.87 +     * Creates a new random number generator. This constructor sets
   65.88 +     * the seed of the random number generator to a value very likely
   65.89 +     * to be distinct from any other invocation of this constructor.
   65.90 +     */
   65.91 +    public Random() {
   65.92 +        this(seedUniquifier() ^ System.nanoTime());
   65.93 +    }
   65.94 +    
   65.95 +    private static synchronized long seedUniquifier() {
   65.96 +        // L'Ecuyer, "Tables of Linear Congruential Generators of
   65.97 +        // Different Sizes and Good Lattice Structure", 1999
   65.98 +        long current = seedUniquifier;
   65.99 +        long next = current * 181783497276652981L;
  65.100 +        seedUniquifier = next;
  65.101 +        return next;
  65.102 +    }
  65.103 +
  65.104 +    private static long seedUniquifier = 8682522807148012L;
  65.105 +
  65.106 +    /**
  65.107 +     * Creates a new random number generator using a single {@code long} seed.
  65.108 +     * The seed is the initial value of the internal state of the pseudorandom
  65.109 +     * number generator which is maintained by method {@link #next}.
  65.110 +     *
  65.111 +     * <p>The invocation {@code new Random(seed)} is equivalent to:
  65.112 +     *  <pre> {@code
  65.113 +     * Random rnd = new Random();
  65.114 +     * rnd.setSeed(seed);}</pre>
  65.115 +     *
  65.116 +     * @param seed the initial seed
  65.117 +     * @see   #setSeed(long)
  65.118 +     */
  65.119 +    public Random(long seed) {
  65.120 +        this.seed = initialScramble(seed);
  65.121 +    }
  65.122 +
  65.123 +    private static long initialScramble(long seed) {
  65.124 +        return (seed ^ multiplier) & mask;
  65.125 +    }
  65.126 +
  65.127 +    /**
  65.128 +     * Sets the seed of this random number generator using a single
  65.129 +     * {@code long} seed. The general contract of {@code setSeed} is
  65.130 +     * that it alters the state of this random number generator object
  65.131 +     * so as to be in exactly the same state as if it had just been
  65.132 +     * created with the argument {@code seed} as a seed. The method
  65.133 +     * {@code setSeed} is implemented by class {@code Random} by
  65.134 +     * atomically updating the seed to
  65.135 +     *  <pre>{@code (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1)}</pre>
  65.136 +     * and clearing the {@code haveNextNextGaussian} flag used by {@link
  65.137 +     * #nextGaussian}.
  65.138 +     *
  65.139 +     * <p>The implementation of {@code setSeed} by class {@code Random}
  65.140 +     * happens to use only 48 bits of the given seed. In general, however,
  65.141 +     * an overriding method may use all 64 bits of the {@code long}
  65.142 +     * argument as a seed value.
  65.143 +     *
  65.144 +     * @param seed the initial seed
  65.145 +     */
  65.146 +    synchronized public void setSeed(long seed) {
  65.147 +        this.seed = initialScramble(seed);
  65.148 +        haveNextNextGaussian = false;
  65.149 +    }
  65.150 +
  65.151 +    /**
  65.152 +     * Generates the next pseudorandom number. Subclasses should
  65.153 +     * override this, as this is used by all other methods.
  65.154 +     *
  65.155 +     * <p>The general contract of {@code next} is that it returns an
  65.156 +     * {@code int} value and if the argument {@code bits} is between
  65.157 +     * {@code 1} and {@code 32} (inclusive), then that many low-order
  65.158 +     * bits of the returned value will be (approximately) independently
  65.159 +     * chosen bit values, each of which is (approximately) equally
  65.160 +     * likely to be {@code 0} or {@code 1}. The method {@code next} is
  65.161 +     * implemented by class {@code Random} by atomically updating the seed to
  65.162 +     *  <pre>{@code (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)}</pre>
  65.163 +     * and returning
  65.164 +     *  <pre>{@code (int)(seed >>> (48 - bits))}.</pre>
  65.165 +     *
  65.166 +     * This is a linear congruential pseudorandom number generator, as
  65.167 +     * defined by D. H. Lehmer and described by Donald E. Knuth in
  65.168 +     * <i>The Art of Computer Programming,</i> Volume 3:
  65.169 +     * <i>Seminumerical Algorithms</i>, section 3.2.1.
  65.170 +     *
  65.171 +     * @param  bits random bits
  65.172 +     * @return the next pseudorandom value from this random number
  65.173 +     *         generator's sequence
  65.174 +     * @since  1.1
  65.175 +     */
  65.176 +    protected synchronized int next(int bits) {
  65.177 +        long oldseed, nextseed;
  65.178 +        long seed = this.seed;
  65.179 +        oldseed = seed;
  65.180 +        nextseed = (oldseed * multiplier + addend) & mask;
  65.181 +        this.seed = nextseed;
  65.182 +        return (int)(nextseed >>> (48 - bits));
  65.183 +    }
  65.184 +
  65.185 +    /**
  65.186 +     * Generates random bytes and places them into a user-supplied
  65.187 +     * byte array.  The number of random bytes produced is equal to
  65.188 +     * the length of the byte array.
  65.189 +     *
  65.190 +     * <p>The method {@code nextBytes} is implemented by class {@code Random}
  65.191 +     * as if by:
  65.192 +     *  <pre> {@code
  65.193 +     * public void nextBytes(byte[] bytes) {
  65.194 +     *   for (int i = 0; i < bytes.length; )
  65.195 +     *     for (int rnd = nextInt(), n = Math.min(bytes.length - i, 4);
  65.196 +     *          n-- > 0; rnd >>= 8)
  65.197 +     *       bytes[i++] = (byte)rnd;
  65.198 +     * }}</pre>
  65.199 +     *
  65.200 +     * @param  bytes the byte array to fill with random bytes
  65.201 +     * @throws NullPointerException if the byte array is null
  65.202 +     * @since  1.1
  65.203 +     */
  65.204 +    public void nextBytes(byte[] bytes) {
  65.205 +        for (int i = 0, len = bytes.length; i < len; )
  65.206 +            for (int rnd = nextInt(),
  65.207 +                     n = Math.min(len - i, Integer.SIZE/Byte.SIZE);
  65.208 +                 n-- > 0; rnd >>= Byte.SIZE)
  65.209 +                bytes[i++] = (byte)rnd;
  65.210 +    }
  65.211 +
  65.212 +    /**
  65.213 +     * Returns the next pseudorandom, uniformly distributed {@code int}
  65.214 +     * value from this random number generator's sequence. The general
  65.215 +     * contract of {@code nextInt} is that one {@code int} value is
  65.216 +     * pseudorandomly generated and returned. All 2<font size="-1"><sup>32
  65.217 +     * </sup></font> possible {@code int} values are produced with
  65.218 +     * (approximately) equal probability.
  65.219 +     *
  65.220 +     * <p>The method {@code nextInt} is implemented by class {@code Random}
  65.221 +     * as if by:
  65.222 +     *  <pre> {@code
  65.223 +     * public int nextInt() {
  65.224 +     *   return next(32);
  65.225 +     * }}</pre>
  65.226 +     *
  65.227 +     * @return the next pseudorandom, uniformly distributed {@code int}
  65.228 +     *         value from this random number generator's sequence
  65.229 +     */
  65.230 +    public int nextInt() {
  65.231 +        return next(32);
  65.232 +    }
  65.233 +
  65.234 +    /**
  65.235 +     * Returns a pseudorandom, uniformly distributed {@code int} value
  65.236 +     * between 0 (inclusive) and the specified value (exclusive), drawn from
  65.237 +     * this random number generator's sequence.  The general contract of
  65.238 +     * {@code nextInt} is that one {@code int} value in the specified range
  65.239 +     * is pseudorandomly generated and returned.  All {@code n} possible
  65.240 +     * {@code int} values are produced with (approximately) equal
  65.241 +     * probability.  The method {@code nextInt(int n)} is implemented by
  65.242 +     * class {@code Random} as if by:
  65.243 +     *  <pre> {@code
  65.244 +     * public int nextInt(int n) {
  65.245 +     *   if (n <= 0)
  65.246 +     *     throw new IllegalArgumentException("n must be positive");
  65.247 +     *
  65.248 +     *   if ((n & -n) == n)  // i.e., n is a power of 2
  65.249 +     *     return (int)((n * (long)next(31)) >> 31);
  65.250 +     *
  65.251 +     *   int bits, val;
  65.252 +     *   do {
  65.253 +     *       bits = next(31);
  65.254 +     *       val = bits % n;
  65.255 +     *   } while (bits - val + (n-1) < 0);
  65.256 +     *   return val;
  65.257 +     * }}</pre>
  65.258 +     *
  65.259 +     * <p>The hedge "approximately" is used in the foregoing description only
  65.260 +     * because the next method is only approximately an unbiased source of
  65.261 +     * independently chosen bits.  If it were a perfect source of randomly
  65.262 +     * chosen bits, then the algorithm shown would choose {@code int}
  65.263 +     * values from the stated range with perfect uniformity.
  65.264 +     * <p>
  65.265 +     * The algorithm is slightly tricky.  It rejects values that would result
  65.266 +     * in an uneven distribution (due to the fact that 2^31 is not divisible
  65.267 +     * by n). The probability of a value being rejected depends on n.  The
  65.268 +     * worst case is n=2^30+1, for which the probability of a reject is 1/2,
  65.269 +     * and the expected number of iterations before the loop terminates is 2.
  65.270 +     * <p>
  65.271 +     * The algorithm treats the case where n is a power of two specially: it
  65.272 +     * returns the correct number of high-order bits from the underlying
  65.273 +     * pseudo-random number generator.  In the absence of special treatment,
  65.274 +     * the correct number of <i>low-order</i> bits would be returned.  Linear
  65.275 +     * congruential pseudo-random number generators such as the one
  65.276 +     * implemented by this class are known to have short periods in the
  65.277 +     * sequence of values of their low-order bits.  Thus, this special case
  65.278 +     * greatly increases the length of the sequence of values returned by
  65.279 +     * successive calls to this method if n is a small power of two.
  65.280 +     *
  65.281 +     * @param n the bound on the random number to be returned.  Must be
  65.282 +     *        positive.
  65.283 +     * @return the next pseudorandom, uniformly distributed {@code int}
  65.284 +     *         value between {@code 0} (inclusive) and {@code n} (exclusive)
  65.285 +     *         from this random number generator's sequence
  65.286 +     * @throws IllegalArgumentException if n is not positive
  65.287 +     * @since 1.2
  65.288 +     */
  65.289 +
  65.290 +    public int nextInt(int n) {
  65.291 +        if (n <= 0)
  65.292 +            throw new IllegalArgumentException("n must be positive");
  65.293 +
  65.294 +        if ((n & -n) == n)  // i.e., n is a power of 2
  65.295 +            return (int)((n * (long)next(31)) >> 31);
  65.296 +
  65.297 +        int bits, val;
  65.298 +        do {
  65.299 +            bits = next(31);
  65.300 +            val = bits % n;
  65.301 +        } while (bits - val + (n-1) < 0);
  65.302 +        return val;
  65.303 +    }
  65.304 +
  65.305 +    /**
  65.306 +     * Returns the next pseudorandom, uniformly distributed {@code long}
  65.307 +     * value from this random number generator's sequence. The general
  65.308 +     * contract of {@code nextLong} is that one {@code long} value is
  65.309 +     * pseudorandomly generated and returned.
  65.310 +     *
  65.311 +     * <p>The method {@code nextLong} is implemented by class {@code Random}
  65.312 +     * as if by:
  65.313 +     *  <pre> {@code
  65.314 +     * public long nextLong() {
  65.315 +     *   return ((long)next(32) << 32) + next(32);
  65.316 +     * }}</pre>
  65.317 +     *
  65.318 +     * Because class {@code Random} uses a seed with only 48 bits,
  65.319 +     * this algorithm will not return all possible {@code long} values.
  65.320 +     *
  65.321 +     * @return the next pseudorandom, uniformly distributed {@code long}
  65.322 +     *         value from this random number generator's sequence
  65.323 +     */
  65.324 +    public long nextLong() {
  65.325 +        // it's okay that the bottom word remains signed.
  65.326 +        return ((long)(next(32)) << 32) + next(32);
  65.327 +    }
  65.328 +
  65.329 +    /**
  65.330 +     * Returns the next pseudorandom, uniformly distributed
  65.331 +     * {@code boolean} value from this random number generator's
  65.332 +     * sequence. The general contract of {@code nextBoolean} is that one
  65.333 +     * {@code boolean} value is pseudorandomly generated and returned.  The
  65.334 +     * values {@code true} and {@code false} are produced with
  65.335 +     * (approximately) equal probability.
  65.336 +     *
  65.337 +     * <p>The method {@code nextBoolean} is implemented by class {@code Random}
  65.338 +     * as if by:
  65.339 +     *  <pre> {@code
  65.340 +     * public boolean nextBoolean() {
  65.341 +     *   return next(1) != 0;
  65.342 +     * }}</pre>
  65.343 +     *
  65.344 +     * @return the next pseudorandom, uniformly distributed
  65.345 +     *         {@code boolean} value from this random number generator's
  65.346 +     *         sequence
  65.347 +     * @since 1.2
  65.348 +     */
  65.349 +    public boolean nextBoolean() {
  65.350 +        return next(1) != 0;
  65.351 +    }
  65.352 +
  65.353 +    /**
  65.354 +     * Returns the next pseudorandom, uniformly distributed {@code float}
  65.355 +     * value between {@code 0.0} and {@code 1.0} from this random
  65.356 +     * number generator's sequence.
  65.357 +     *
  65.358 +     * <p>The general contract of {@code nextFloat} is that one
  65.359 +     * {@code float} value, chosen (approximately) uniformly from the
  65.360 +     * range {@code 0.0f} (inclusive) to {@code 1.0f} (exclusive), is
  65.361 +     * pseudorandomly generated and returned. All 2<font
  65.362 +     * size="-1"><sup>24</sup></font> possible {@code float} values
  65.363 +     * of the form <i>m&nbsp;x&nbsp</i>2<font
  65.364 +     * size="-1"><sup>-24</sup></font>, where <i>m</i> is a positive
  65.365 +     * integer less than 2<font size="-1"><sup>24</sup> </font>, are
  65.366 +     * produced with (approximately) equal probability.
  65.367 +     *
  65.368 +     * <p>The method {@code nextFloat} is implemented by class {@code Random}
  65.369 +     * as if by:
  65.370 +     *  <pre> {@code
  65.371 +     * public float nextFloat() {
  65.372 +     *   return next(24) / ((float)(1 << 24));
  65.373 +     * }}</pre>
  65.374 +     *
  65.375 +     * <p>The hedge "approximately" is used in the foregoing description only
  65.376 +     * because the next method is only approximately an unbiased source of
  65.377 +     * independently chosen bits. If it were a perfect source of randomly
  65.378 +     * chosen bits, then the algorithm shown would choose {@code float}
  65.379 +     * values from the stated range with perfect uniformity.<p>
  65.380 +     * [In early versions of Java, the result was incorrectly calculated as:
  65.381 +     *  <pre> {@code
  65.382 +     *   return next(30) / ((float)(1 << 30));}</pre>
  65.383 +     * This might seem to be equivalent, if not better, but in fact it
  65.384 +     * introduced a slight nonuniformity because of the bias in the rounding
  65.385 +     * of floating-point numbers: it was slightly more likely that the
  65.386 +     * low-order bit of the significand would be 0 than that it would be 1.]
  65.387 +     *
  65.388 +     * @return the next pseudorandom, uniformly distributed {@code float}
  65.389 +     *         value between {@code 0.0} and {@code 1.0} from this
  65.390 +     *         random number generator's sequence
  65.391 +     */
  65.392 +    public float nextFloat() {
  65.393 +        return next(24) / ((float)(1 << 24));
  65.394 +    }
  65.395 +
  65.396 +    /**
  65.397 +     * Returns the next pseudorandom, uniformly distributed
  65.398 +     * {@code double} value between {@code 0.0} and
  65.399 +     * {@code 1.0} from this random number generator's sequence.
  65.400 +     *
  65.401 +     * <p>The general contract of {@code nextDouble} is that one
  65.402 +     * {@code double} value, chosen (approximately) uniformly from the
  65.403 +     * range {@code 0.0d} (inclusive) to {@code 1.0d} (exclusive), is
  65.404 +     * pseudorandomly generated and returned.
  65.405 +     *
  65.406 +     * <p>The method {@code nextDouble} is implemented by class {@code Random}
  65.407 +     * as if by:
  65.408 +     *  <pre> {@code
  65.409 +     * public double nextDouble() {
  65.410 +     *   return (((long)next(26) << 27) + next(27))
  65.411 +     *     / (double)(1L << 53);
  65.412 +     * }}</pre>
  65.413 +     *
  65.414 +     * <p>The hedge "approximately" is used in the foregoing description only
  65.415 +     * because the {@code next} method is only approximately an unbiased
  65.416 +     * source of independently chosen bits. If it were a perfect source of
  65.417 +     * randomly chosen bits, then the algorithm shown would choose
  65.418 +     * {@code double} values from the stated range with perfect uniformity.
  65.419 +     * <p>[In early versions of Java, the result was incorrectly calculated as:
  65.420 +     *  <pre> {@code
  65.421 +     *   return (((long)next(27) << 27) + next(27))
  65.422 +     *     / (double)(1L << 54);}</pre>
  65.423 +     * This might seem to be equivalent, if not better, but in fact it
  65.424 +     * introduced a large nonuniformity because of the bias in the rounding
  65.425 +     * of floating-point numbers: it was three times as likely that the
  65.426 +     * low-order bit of the significand would be 0 than that it would be 1!
  65.427 +     * This nonuniformity probably doesn't matter much in practice, but we
  65.428 +     * strive for perfection.]
  65.429 +     *
  65.430 +     * @return the next pseudorandom, uniformly distributed {@code double}
  65.431 +     *         value between {@code 0.0} and {@code 1.0} from this
  65.432 +     *         random number generator's sequence
  65.433 +     * @see Math#random
  65.434 +     */
  65.435 +    public double nextDouble() {
  65.436 +        return (((long)(next(26)) << 27) + next(27))
  65.437 +            / (double)(1L << 53);
  65.438 +    }
  65.439 +
  65.440 +    private double nextNextGaussian;
  65.441 +    private boolean haveNextNextGaussian = false;
  65.442 +
  65.443 +    /**
  65.444 +     * Returns the next pseudorandom, Gaussian ("normally") distributed
  65.445 +     * {@code double} value with mean {@code 0.0} and standard
  65.446 +     * deviation {@code 1.0} from this random number generator's sequence.
  65.447 +     * <p>
  65.448 +     * The general contract of {@code nextGaussian} is that one
  65.449 +     * {@code double} value, chosen from (approximately) the usual
  65.450 +     * normal distribution with mean {@code 0.0} and standard deviation
  65.451 +     * {@code 1.0}, is pseudorandomly generated and returned.
  65.452 +     *
  65.453 +     * <p>The method {@code nextGaussian} is implemented by class
  65.454 +     * {@code Random} as if by a threadsafe version of the following:
  65.455 +     *  <pre> {@code
  65.456 +     * private double nextNextGaussian;
  65.457 +     * private boolean haveNextNextGaussian = false;
  65.458 +     *
  65.459 +     * public double nextGaussian() {
  65.460 +     *   if (haveNextNextGaussian) {
  65.461 +     *     haveNextNextGaussian = false;
  65.462 +     *     return nextNextGaussian;
  65.463 +     *   } else {
  65.464 +     *     double v1, v2, s;
  65.465 +     *     do {
  65.466 +     *       v1 = 2 * nextDouble() - 1;   // between -1.0 and 1.0
  65.467 +     *       v2 = 2 * nextDouble() - 1;   // between -1.0 and 1.0
  65.468 +     *       s = v1 * v1 + v2 * v2;
  65.469 +     *     } while (s >= 1 || s == 0);
  65.470 +     *     double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
  65.471 +     *     nextNextGaussian = v2 * multiplier;
  65.472 +     *     haveNextNextGaussian = true;
  65.473 +     *     return v1 * multiplier;
  65.474 +     *   }
  65.475 +     * }}</pre>
  65.476 +     * This uses the <i>polar method</i> of G. E. P. Box, M. E. Muller, and
  65.477 +     * G. Marsaglia, as described by Donald E. Knuth in <i>The Art of
  65.478 +     * Computer Programming</i>, Volume 3: <i>Seminumerical Algorithms</i>,
  65.479 +     * section 3.4.1, subsection C, algorithm P. Note that it generates two
  65.480 +     * independent values at the cost of only one call to {@code StrictMath.log}
  65.481 +     * and one call to {@code StrictMath.sqrt}.
  65.482 +     *
  65.483 +     * @return the next pseudorandom, Gaussian ("normally") distributed
  65.484 +     *         {@code double} value with mean {@code 0.0} and
  65.485 +     *         standard deviation {@code 1.0} from this random number
  65.486 +     *         generator's sequence
  65.487 +     */
  65.488 +    synchronized public double nextGaussian() {
  65.489 +        // See Knuth, ACP, Section 3.4.1 Algorithm C.
  65.490 +        if (haveNextNextGaussian) {
  65.491 +            haveNextNextGaussian = false;
  65.492 +            return nextNextGaussian;
  65.493 +        } else {
  65.494 +            double v1, v2, s;
  65.495 +            do {
  65.496 +                v1 = 2 * nextDouble() - 1; // between -1 and 1
  65.497 +                v2 = 2 * nextDouble() - 1; // between -1 and 1
  65.498 +                s = v1 * v1 + v2 * v2;
  65.499 +            } while (s >= 1 || s == 0);
  65.500 +            double multiplier = Math.sqrt(-2 * Math.log(s)/s);
  65.501 +            nextNextGaussian = v2 * multiplier;
  65.502 +            haveNextNextGaussian = true;
  65.503 +            return v1 * multiplier;
  65.504 +        }
  65.505 +    }
  65.506 +}
    66.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.2 +++ b/emul/compact/src/main/java/java/util/SortedMap.java	Tue Feb 05 17:04:22 2013 +0100
    66.3 @@ -0,0 +1,284 @@
    66.4 +/*
    66.5 + * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
    66.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    66.7 + *
    66.8 + * This code is free software; you can redistribute it and/or modify it
    66.9 + * under the terms of the GNU General Public License version 2 only, as
   66.10 + * published by the Free Software Foundation.  Oracle designates this
   66.11 + * particular file as subject to the "Classpath" exception as provided
   66.12 + * by Oracle in the LICENSE file that accompanied this code.
   66.13 + *
   66.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   66.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   66.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   66.17 + * version 2 for more details (a copy is included in the LICENSE file that
   66.18 + * accompanied this code).
   66.19 + *
   66.20 + * You should have received a copy of the GNU General Public License version
   66.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   66.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   66.23 + *
   66.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   66.25 + * or visit www.oracle.com if you need additional information or have any
   66.26 + * questions.
   66.27 + */
   66.28 +
   66.29 +package java.util;
   66.30 +
   66.31 +/**
   66.32 + * A {@link Map} that further provides a <em>total ordering</em> on its keys.
   66.33 + * The map is ordered according to the {@linkplain Comparable natural
   66.34 + * ordering} of its keys, or by a {@link Comparator} typically
   66.35 + * provided at sorted map creation time.  This order is reflected when
   66.36 + * iterating over the sorted map's collection views (returned by the
   66.37 + * {@code entrySet}, {@code keySet} and {@code values} methods).
   66.38 + * Several additional operations are provided to take advantage of the
   66.39 + * ordering.  (This interface is the map analogue of {@link SortedSet}.)
   66.40 + *
   66.41 + * <p>All keys inserted into a sorted map must implement the {@code Comparable}
   66.42 + * interface (or be accepted by the specified comparator).  Furthermore, all
   66.43 + * such keys must be <em>mutually comparable</em>: {@code k1.compareTo(k2)} (or
   66.44 + * {@code comparator.compare(k1, k2)}) must not throw a
   66.45 + * {@code ClassCastException} for any keys {@code k1} and {@code k2} in
   66.46 + * the sorted map.  Attempts to violate this restriction will cause the
   66.47 + * offending method or constructor invocation to throw a
   66.48 + * {@code ClassCastException}.
   66.49 + *
   66.50 + * <p>Note that the ordering maintained by a sorted map (whether or not an
   66.51 + * explicit comparator is provided) must be <em>consistent with equals</em> if
   66.52 + * the sorted map is to correctly implement the {@code Map} interface.  (See
   66.53 + * the {@code Comparable} interface or {@code Comparator} interface for a
   66.54 + * precise definition of <em>consistent with equals</em>.)  This is so because
   66.55 + * the {@code Map} interface is defined in terms of the {@code equals}
   66.56 + * operation, but a sorted map performs all key comparisons using its
   66.57 + * {@code compareTo} (or {@code compare}) method, so two keys that are
   66.58 + * deemed equal by this method are, from the standpoint of the sorted map,
   66.59 + * equal.  The behavior of a tree map <em>is</em> well-defined even if its
   66.60 + * ordering is inconsistent with equals; it just fails to obey the general
   66.61 + * contract of the {@code Map} interface.
   66.62 + *
   66.63 + * <p>All general-purpose sorted map implementation classes should provide four
   66.64 + * "standard" constructors. It is not possible to enforce this recommendation
   66.65 + * though as required constructors cannot be specified by interfaces. The
   66.66 + * expected "standard" constructors for all sorted map implementations are:
   66.67 + * <ol>
   66.68 + *   <li>A void (no arguments) constructor, which creates an empty sorted map
   66.69 + *   sorted according to the natural ordering of its keys.</li>
   66.70 + *   <li>A constructor with a single argument of type {@code Comparator}, which
   66.71 + *   creates an empty sorted map sorted according to the specified comparator.</li>
   66.72 + *   <li>A constructor with a single argument of type {@code Map}, which creates
   66.73 + *   a new map with the same key-value mappings as its argument, sorted
   66.74 + *   according to the keys' natural ordering.</li>
   66.75 + *   <li>A constructor with a single argument of type {@code SortedMap}, which
   66.76 + *   creates a new sorted map with the same key-value mappings and the same
   66.77 + *   ordering as the input sorted map.</li>
   66.78 + * </ol>
   66.79 + *
   66.80 + * <p><strong>Note</strong>: several methods return submaps with restricted key
   66.81 + * ranges. Such ranges are <em>half-open</em>, that is, they include their low
   66.82 + * endpoint but not their high endpoint (where applicable).  If you need a
   66.83 + * <em>closed range</em> (which includes both endpoints), and the key type
   66.84 + * allows for calculation of the successor of a given key, merely request
   66.85 + * the subrange from {@code lowEndpoint} to
   66.86 + * {@code successor(highEndpoint)}.  For example, suppose that {@code m}
   66.87 + * is a map whose keys are strings.  The following idiom obtains a view
   66.88 + * containing all of the key-value mappings in {@code m} whose keys are
   66.89 + * between {@code low} and {@code high}, inclusive:<pre>
   66.90 + *   SortedMap&lt;String, V&gt; sub = m.subMap(low, high+"\0");</pre>
   66.91 + *
   66.92 + * A similar technique can be used to generate an <em>open range</em>
   66.93 + * (which contains neither endpoint).  The following idiom obtains a
   66.94 + * view containing all of the key-value mappings in {@code m} whose keys
   66.95 + * are between {@code low} and {@code high}, exclusive:<pre>
   66.96 + *   SortedMap&lt;String, V&gt; sub = m.subMap(low+"\0", high);</pre>
   66.97 + *
   66.98 + * <p>This interface is a member of the
   66.99 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
  66.100 + * Java Collections Framework</a>.
  66.101 + *
  66.102 + * @param <K> the type of keys maintained by this map
  66.103 + * @param <V> the type of mapped values
  66.104 + *
  66.105 + * @author  Josh Bloch
  66.106 + * @see Map
  66.107 + * @see TreeMap
  66.108 + * @see SortedSet
  66.109 + * @see Comparator
  66.110 + * @see Comparable
  66.111 + * @see Collection
  66.112 + * @see ClassCastException
  66.113 + * @since 1.2
  66.114 + */
  66.115 +
  66.116 +public interface SortedMap<K,V> extends Map<K,V> {
  66.117 +    /**
  66.118 +     * Returns the comparator used to order the keys in this map, or
  66.119 +     * {@code null} if this map uses the {@linkplain Comparable
  66.120 +     * natural ordering} of its keys.
  66.121 +     *
  66.122 +     * @return the comparator used to order the keys in this map,
  66.123 +     *         or {@code null} if this map uses the natural ordering
  66.124 +     *         of its keys
  66.125 +     */
  66.126 +    Comparator<? super K> comparator();
  66.127 +
  66.128 +    /**
  66.129 +     * Returns a view of the portion of this map whose keys range from
  66.130 +     * {@code fromKey}, inclusive, to {@code toKey}, exclusive.  (If
  66.131 +     * {@code fromKey} and {@code toKey} are equal, the returned map
  66.132 +     * is empty.)  The returned map is backed by this map, so changes
  66.133 +     * in the returned map are reflected in this map, and vice-versa.
  66.134 +     * The returned map supports all optional map operations that this
  66.135 +     * map supports.
  66.136 +     *
  66.137 +     * <p>The returned map will throw an {@code IllegalArgumentException}
  66.138 +     * on an attempt to insert a key outside its range.
  66.139 +     *
  66.140 +     * @param fromKey low endpoint (inclusive) of the keys in the returned map
  66.141 +     * @param toKey high endpoint (exclusive) of the keys in the returned map
  66.142 +     * @return a view of the portion of this map whose keys range from
  66.143 +     *         {@code fromKey}, inclusive, to {@code toKey}, exclusive
  66.144 +     * @throws ClassCastException if {@code fromKey} and {@code toKey}
  66.145 +     *         cannot be compared to one another using this map's comparator
  66.146 +     *         (or, if the map has no comparator, using natural ordering).
  66.147 +     *         Implementations may, but are not required to, throw this
  66.148 +     *         exception if {@code fromKey} or {@code toKey}
  66.149 +     *         cannot be compared to keys currently in the map.
  66.150 +     * @throws NullPointerException if {@code fromKey} or {@code toKey}
  66.151 +     *         is null and this map does not permit null keys
  66.152 +     * @throws IllegalArgumentException if {@code fromKey} is greater than
  66.153 +     *         {@code toKey}; or if this map itself has a restricted
  66.154 +     *         range, and {@code fromKey} or {@code toKey} lies
  66.155 +     *         outside the bounds of the range
  66.156 +     */
  66.157 +    SortedMap<K,V> subMap(K fromKey, K toKey);
  66.158 +
  66.159 +    /**
  66.160 +     * Returns a view of the portion of this map whose keys are
  66.161 +     * strictly less than {@code toKey}.  The returned map is backed
  66.162 +     * by this map, so changes in the returned map are reflected in
  66.163 +     * this map, and vice-versa.  The returned map supports all
  66.164 +     * optional map operations that this map supports.
  66.165 +     *
  66.166 +     * <p>The returned map will throw an {@code IllegalArgumentException}
  66.167 +     * on an attempt to insert a key outside its range.
  66.168 +     *
  66.169 +     * @param toKey high endpoint (exclusive) of the keys in the returned map
  66.170 +     * @return a view of the portion of this map whose keys are strictly
  66.171 +     *         less than {@code toKey}
  66.172 +     * @throws ClassCastException if {@code toKey} is not compatible
  66.173 +     *         with this map's comparator (or, if the map has no comparator,
  66.174 +     *         if {@code toKey} does not implement {@link Comparable}).
  66.175 +     *         Implementations may, but are not required to, throw this
  66.176 +     *         exception if {@code toKey} cannot be compared to keys
  66.177 +     *         currently in the map.
  66.178 +     * @throws NullPointerException if {@code toKey} is null and
  66.179 +     *         this map does not permit null keys
  66.180 +     * @throws IllegalArgumentException if this map itself has a
  66.181 +     *         restricted range, and {@code toKey} lies outside the
  66.182 +     *         bounds of the range
  66.183 +     */
  66.184 +    SortedMap<K,V> headMap(K toKey);
  66.185 +
  66.186 +    /**
  66.187 +     * Returns a view of the portion of this map whose keys are
  66.188 +     * greater than or equal to {@code fromKey}.  The returned map is
  66.189 +     * backed by this map, so changes in the returned map are
  66.190 +     * reflected in this map, and vice-versa.  The returned map
  66.191 +     * supports all optional map operations that this map supports.
  66.192 +     *
  66.193 +     * <p>The returned map will throw an {@code IllegalArgumentException}
  66.194 +     * on an attempt to insert a key outside its range.
  66.195 +     *
  66.196 +     * @param fromKey low endpoint (inclusive) of the keys in the returned map
  66.197 +     * @return a view of the portion of this map whose keys are greater
  66.198 +     *         than or equal to {@code fromKey}
  66.199 +     * @throws ClassCastException if {@code fromKey} is not compatible
  66.200 +     *         with this map's comparator (or, if the map has no comparator,
  66.201 +     *         if {@code fromKey} does not implement {@link Comparable}).
  66.202 +     *         Implementations may, but are not required to, throw this
  66.203 +     *         exception if {@code fromKey} cannot be compared to keys
  66.204 +     *         currently in the map.
  66.205 +     * @throws NullPointerException if {@code fromKey} is null and
  66.206 +     *         this map does not permit null keys
  66.207 +     * @throws IllegalArgumentException if this map itself has a
  66.208 +     *         restricted range, and {@code fromKey} lies outside the
  66.209 +     *         bounds of the range
  66.210 +     */
  66.211 +    SortedMap<K,V> tailMap(K fromKey);
  66.212 +
  66.213 +    /**
  66.214 +     * Returns the first (lowest) key currently in this map.
  66.215 +     *
  66.216 +     * @return the first (lowest) key currently in this map
  66.217 +     * @throws NoSuchElementException if this map is empty
  66.218 +     */
  66.219 +    K firstKey();
  66.220 +
  66.221 +    /**
  66.222 +     * Returns the last (highest) key currently in this map.
  66.223 +     *
  66.224 +     * @return the last (highest) key currently in this map
  66.225 +     * @throws NoSuchElementException if this map is empty
  66.226 +     */
  66.227 +    K lastKey();
  66.228 +
  66.229 +    /**
  66.230 +     * Returns a {@link Set} view of the keys contained in this map.
  66.231 +     * The set's iterator returns the keys in ascending order.
  66.232 +     * The set is backed by the map, so changes to the map are
  66.233 +     * reflected in the set, and vice-versa.  If the map is modified
  66.234 +     * while an iteration over the set is in progress (except through
  66.235 +     * the iterator's own {@code remove} operation), the results of
  66.236 +     * the iteration are undefined.  The set supports element removal,
  66.237 +     * which removes the corresponding mapping from the map, via the
  66.238 +     * {@code Iterator.remove}, {@code Set.remove},
  66.239 +     * {@code removeAll}, {@code retainAll}, and {@code clear}
  66.240 +     * operations.  It does not support the {@code add} or {@code addAll}
  66.241 +     * operations.
  66.242 +     *
  66.243 +     * @return a set view of the keys contained in this map, sorted in
  66.244 +     *         ascending order
  66.245 +     */
  66.246 +    Set<K> keySet();
  66.247 +
  66.248 +    /**
  66.249 +     * Returns a {@link Collection} view of the values contained in this map.
  66.250 +     * The collection's iterator returns the values in ascending order
  66.251 +     * of the corresponding keys.
  66.252 +     * The collection is backed by the map, so changes to the map are
  66.253 +     * reflected in the collection, and vice-versa.  If the map is
  66.254 +     * modified while an iteration over the collection is in progress
  66.255 +     * (except through the iterator's own {@code remove} operation),
  66.256 +     * the results of the iteration are undefined.  The collection
  66.257 +     * supports element removal, which removes the corresponding
  66.258 +     * mapping from the map, via the {@code Iterator.remove},
  66.259 +     * {@code Collection.remove}, {@code removeAll},
  66.260 +     * {@code retainAll} and {@code clear} operations.  It does not
  66.261 +     * support the {@code add} or {@code addAll} operations.
  66.262 +     *
  66.263 +     * @return a collection view of the values contained in this map,
  66.264 +     *         sorted in ascending key order
  66.265 +     */
  66.266 +    Collection<V> values();
  66.267 +
  66.268 +    /**
  66.269 +     * Returns a {@link Set} view of the mappings contained in this map.
  66.270 +     * The set's iterator returns the entries in ascending key order.
  66.271 +     * The set is backed by the map, so changes to the map are
  66.272 +     * reflected in the set, and vice-versa.  If the map is modified
  66.273 +     * while an iteration over the set is in progress (except through
  66.274 +     * the iterator's own {@code remove} operation, or through the
  66.275 +     * {@code setValue} operation on a map entry returned by the
  66.276 +     * iterator) the results of the iteration are undefined.  The set
  66.277 +     * supports element removal, which removes the corresponding
  66.278 +     * mapping from the map, via the {@code Iterator.remove},
  66.279 +     * {@code Set.remove}, {@code removeAll}, {@code retainAll} and
  66.280 +     * {@code clear} operations.  It does not support the
  66.281 +     * {@code add} or {@code addAll} operations.
  66.282 +     *
  66.283 +     * @return a set view of the mappings contained in this map,
  66.284 +     *         sorted in ascending key order
  66.285 +     */
  66.286 +    Set<Map.Entry<K, V>> entrySet();
  66.287 +}
    67.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.2 +++ b/emul/compact/src/main/java/java/util/SortedSet.java	Tue Feb 05 17:04:22 2013 +0100
    67.3 @@ -0,0 +1,222 @@
    67.4 +/*
    67.5 + * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
    67.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    67.7 + *
    67.8 + * This code is free software; you can redistribute it and/or modify it
    67.9 + * under the terms of the GNU General Public License version 2 only, as
   67.10 + * published by the Free Software Foundation.  Oracle designates this
   67.11 + * particular file as subject to the "Classpath" exception as provided
   67.12 + * by Oracle in the LICENSE file that accompanied this code.
   67.13 + *
   67.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   67.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   67.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   67.17 + * version 2 for more details (a copy is included in the LICENSE file that
   67.18 + * accompanied this code).
   67.19 + *
   67.20 + * You should have received a copy of the GNU General Public License version
   67.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   67.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   67.23 + *
   67.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   67.25 + * or visit www.oracle.com if you need additional information or have any
   67.26 + * questions.
   67.27 + */
   67.28 +
   67.29 +package java.util;
   67.30 +
   67.31 +/**
   67.32 + * A {@link Set} that further provides a <i>total ordering</i> on its elements.
   67.33 + * The elements are ordered using their {@linkplain Comparable natural
   67.34 + * ordering}, or by a {@link Comparator} typically provided at sorted
   67.35 + * set creation time.  The set's iterator will traverse the set in
   67.36 + * ascending element order. Several additional operations are provided
   67.37 + * to take advantage of the ordering.  (This interface is the set
   67.38 + * analogue of {@link SortedMap}.)
   67.39 + *
   67.40 + * <p>All elements inserted into a sorted set must implement the <tt>Comparable</tt>
   67.41 + * interface (or be accepted by the specified comparator).  Furthermore, all
   67.42 + * such elements must be <i>mutually comparable</i>: <tt>e1.compareTo(e2)</tt>
   67.43 + * (or <tt>comparator.compare(e1, e2)</tt>) must not throw a
   67.44 + * <tt>ClassCastException</tt> for any elements <tt>e1</tt> and <tt>e2</tt> in
   67.45 + * the sorted set.  Attempts to violate this restriction will cause the
   67.46 + * offending method or constructor invocation to throw a
   67.47 + * <tt>ClassCastException</tt>.
   67.48 + *
   67.49 + * <p>Note that the ordering maintained by a sorted set (whether or not an
   67.50 + * explicit comparator is provided) must be <i>consistent with equals</i> if
   67.51 + * the sorted set is to correctly implement the <tt>Set</tt> interface.  (See
   67.52 + * the <tt>Comparable</tt> interface or <tt>Comparator</tt> interface for a
   67.53 + * precise definition of <i>consistent with equals</i>.)  This is so because
   67.54 + * the <tt>Set</tt> interface is defined in terms of the <tt>equals</tt>
   67.55 + * operation, but a sorted set performs all element comparisons using its
   67.56 + * <tt>compareTo</tt> (or <tt>compare</tt>) method, so two elements that are
   67.57 + * deemed equal by this method are, from the standpoint of the sorted set,
   67.58 + * equal.  The behavior of a sorted set <i>is</i> well-defined even if its
   67.59 + * ordering is inconsistent with equals; it just fails to obey the general
   67.60 + * contract of the <tt>Set</tt> interface.
   67.61 + *
   67.62 + * <p>All general-purpose sorted set implementation classes should
   67.63 + * provide four "standard" constructors: 1) A void (no arguments)
   67.64 + * constructor, which creates an empty sorted set sorted according to
   67.65 + * the natural ordering of its elements.  2) A constructor with a
   67.66 + * single argument of type <tt>Comparator</tt>, which creates an empty
   67.67 + * sorted set sorted according to the specified comparator.  3) A
   67.68 + * constructor with a single argument of type <tt>Collection</tt>,
   67.69 + * which creates a new sorted set with the same elements as its
   67.70 + * argument, sorted according to the natural ordering of the elements.
   67.71 + * 4) A constructor with a single argument of type <tt>SortedSet</tt>,
   67.72 + * which creates a new sorted set with the same elements and the same
   67.73 + * ordering as the input sorted set.  There is no way to enforce this
   67.74 + * recommendation, as interfaces cannot contain constructors.
   67.75 + *
   67.76 + * <p>Note: several methods return subsets with restricted ranges.
   67.77 + * Such ranges are <i>half-open</i>, that is, they include their low
   67.78 + * endpoint but not their high endpoint (where applicable).
   67.79 + * If you need a <i>closed range</i> (which includes both endpoints), and
   67.80 + * the element type allows for calculation of the successor of a given
   67.81 + * value, merely request the subrange from <tt>lowEndpoint</tt> to
   67.82 + * <tt>successor(highEndpoint)</tt>.  For example, suppose that <tt>s</tt>
   67.83 + * is a sorted set of strings.  The following idiom obtains a view
   67.84 + * containing all of the strings in <tt>s</tt> from <tt>low</tt> to
   67.85 + * <tt>high</tt>, inclusive:<pre>
   67.86 + *   SortedSet&lt;String&gt; sub = s.subSet(low, high+"\0");</pre>
   67.87 + *
   67.88 + * A similar technique can be used to generate an <i>open range</i> (which
   67.89 + * contains neither endpoint).  The following idiom obtains a view
   67.90 + * containing all of the Strings in <tt>s</tt> from <tt>low</tt> to
   67.91 + * <tt>high</tt>, exclusive:<pre>
   67.92 + *   SortedSet&lt;String&gt; sub = s.subSet(low+"\0", high);</pre>
   67.93 + *
   67.94 + * <p>This interface is a member of the
   67.95 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
   67.96 + * Java Collections Framework</a>.
   67.97 + *
   67.98 + * @param <E> the type of elements maintained by this set
   67.99 + *
  67.100 + * @author  Josh Bloch
  67.101 + * @see Set
  67.102 + * @see TreeSet
  67.103 + * @see SortedMap
  67.104 + * @see Collection
  67.105 + * @see Comparable
  67.106 + * @see Comparator
  67.107 + * @see ClassCastException
  67.108 + * @since 1.2
  67.109 + */
  67.110 +
  67.111 +public interface SortedSet<E> extends Set<E> {
  67.112 +    /**
  67.113 +     * Returns the comparator used to order the elements in this set,
  67.114 +     * or <tt>null</tt> if this set uses the {@linkplain Comparable
  67.115 +     * natural ordering} of its elements.
  67.116 +     *
  67.117 +     * @return the comparator used to order the elements in this set,
  67.118 +     *         or <tt>null</tt> if this set uses the natural ordering
  67.119 +     *         of its elements
  67.120 +     */
  67.121 +    Comparator<? super E> comparator();
  67.122 +
  67.123 +    /**
  67.124 +     * Returns a view of the portion of this set whose elements range
  67.125 +     * from <tt>fromElement</tt>, inclusive, to <tt>toElement</tt>,
  67.126 +     * exclusive.  (If <tt>fromElement</tt> and <tt>toElement</tt> are
  67.127 +     * equal, the returned set is empty.)  The returned set is backed
  67.128 +     * by this set, so changes in the returned set are reflected in
  67.129 +     * this set, and vice-versa.  The returned set supports all
  67.130 +     * optional set operations that this set supports.
  67.131 +     *
  67.132 +     * <p>The returned set will throw an <tt>IllegalArgumentException</tt>
  67.133 +     * on an attempt to insert an element outside its range.
  67.134 +     *
  67.135 +     * @param fromElement low endpoint (inclusive) of the returned set
  67.136 +     * @param toElement high endpoint (exclusive) of the returned set
  67.137 +     * @return a view of the portion of this set whose elements range from
  67.138 +     *         <tt>fromElement</tt>, inclusive, to <tt>toElement</tt>, exclusive
  67.139 +     * @throws ClassCastException if <tt>fromElement</tt> and
  67.140 +     *         <tt>toElement</tt> cannot be compared to one another using this
  67.141 +     *         set's comparator (or, if the set has no comparator, using
  67.142 +     *         natural ordering).  Implementations may, but are not required
  67.143 +     *         to, throw this exception if <tt>fromElement</tt> or
  67.144 +     *         <tt>toElement</tt> cannot be compared to elements currently in
  67.145 +     *         the set.
  67.146 +     * @throws NullPointerException if <tt>fromElement</tt> or
  67.147 +     *         <tt>toElement</tt> is null and this set does not permit null
  67.148 +     *         elements
  67.149 +     * @throws IllegalArgumentException if <tt>fromElement</tt> is
  67.150 +     *         greater than <tt>toElement</tt>; or if this set itself
  67.151 +     *         has a restricted range, and <tt>fromElement</tt> or
  67.152 +     *         <tt>toElement</tt> lies outside the bounds of the range
  67.153 +     */
  67.154 +    SortedSet<E> subSet(E fromElement, E toElement);
  67.155 +
  67.156 +    /**
  67.157 +     * Returns a view of the portion of this set whose elements are
  67.158 +     * strictly less than <tt>toElement</tt>.  The returned set is
  67.159 +     * backed by this set, so changes in the returned set are
  67.160 +     * reflected in this set, and vice-versa.  The returned set
  67.161 +     * supports all optional set operations that this set supports.
  67.162 +     *
  67.163 +     * <p>The returned set will throw an <tt>IllegalArgumentException</tt>
  67.164 +     * on an attempt to insert an element outside its range.
  67.165 +     *
  67.166 +     * @param toElement high endpoint (exclusive) of the returned set
  67.167 +     * @return a view of the portion of this set whose elements are strictly
  67.168 +     *         less than <tt>toElement</tt>
  67.169 +     * @throws ClassCastException if <tt>toElement</tt> is not compatible
  67.170 +     *         with this set's comparator (or, if the set has no comparator,
  67.171 +     *         if <tt>toElement</tt> does not implement {@link Comparable}).
  67.172 +     *         Implementations may, but are not required to, throw this
  67.173 +     *         exception if <tt>toElement</tt> cannot be compared to elements
  67.174 +     *         currently in the set.
  67.175 +     * @throws NullPointerException if <tt>toElement</tt> is null and
  67.176 +     *         this set does not permit null elements
  67.177 +     * @throws IllegalArgumentException if this set itself has a
  67.178 +     *         restricted range, and <tt>toElement</tt> lies outside the
  67.179 +     *         bounds of the range
  67.180 +     */
  67.181 +    SortedSet<E> headSet(E toElement);
  67.182 +
  67.183 +    /**
  67.184 +     * Returns a view of the portion of this set whose elements are
  67.185 +     * greater than or equal to <tt>fromElement</tt>.  The returned
  67.186 +     * set is backed by this set, so changes in the returned set are
  67.187 +     * reflected in this set, and vice-versa.  The returned set
  67.188 +     * supports all optional set operations that this set supports.
  67.189 +     *
  67.190 +     * <p>The returned set will throw an <tt>IllegalArgumentException</tt>
  67.191 +     * on an attempt to insert an element outside its range.
  67.192 +     *
  67.193 +     * @param fromElement low endpoint (inclusive) of the returned set
  67.194 +     * @return a view of the portion of this set whose elements are greater
  67.195 +     *         than or equal to <tt>fromElement</tt>
  67.196 +     * @throws ClassCastException if <tt>fromElement</tt> is not compatible
  67.197 +     *         with this set's comparator (or, if the set has no comparator,
  67.198 +     *         if <tt>fromElement</tt> does not implement {@link Comparable}).
  67.199 +     *         Implementations may, but are not required to, throw this
  67.200 +     *         exception if <tt>fromElement</tt> cannot be compared to elements
  67.201 +     *         currently in the set.
  67.202 +     * @throws NullPointerException if <tt>fromElement</tt> is null
  67.203 +     *         and this set does not permit null elements
  67.204 +     * @throws IllegalArgumentException if this set itself has a
  67.205 +     *         restricted range, and <tt>fromElement</tt> lies outside the
  67.206 +     *         bounds of the range
  67.207 +     */
  67.208 +    SortedSet<E> tailSet(E fromElement);
  67.209 +
  67.210 +    /**
  67.211 +     * Returns the first (lowest) element currently in this set.
  67.212 +     *
  67.213 +     * @return the first (lowest) element currently in this set
  67.214 +     * @throws NoSuchElementException if this set is empty
  67.215 +     */
  67.216 +    E first();
  67.217 +
  67.218 +    /**
  67.219 +     * Returns the last (highest) element currently in this set.
  67.220 +     *
  67.221 +     * @return the last (highest) element currently in this set
  67.222 +     * @throws NoSuchElementException if this set is empty
  67.223 +     */
  67.224 +    E last();
  67.225 +}
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/emul/compact/src/main/java/java/util/Stack.java	Tue Feb 05 17:04:22 2013 +0100
    68.3 @@ -0,0 +1,141 @@
    68.4 +/*
    68.5 + * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
    68.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    68.7 + *
    68.8 + * This code is free software; you can redistribute it and/or modify it
    68.9 + * under the terms of the GNU General Public License version 2 only, as
   68.10 + * published by the Free Software Foundation.  Oracle designates this
   68.11 + * particular file as subject to the "Classpath" exception as provided
   68.12 + * by Oracle in the LICENSE file that accompanied this code.
   68.13 + *
   68.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   68.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   68.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   68.17 + * version 2 for more details (a copy is included in the LICENSE file that
   68.18 + * accompanied this code).
   68.19 + *
   68.20 + * You should have received a copy of the GNU General Public License version
   68.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   68.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   68.23 + *
   68.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   68.25 + * or visit www.oracle.com if you need additional information or have any
   68.26 + * questions.
   68.27 + */
   68.28 +
   68.29 +package java.util;
   68.30 +
   68.31 +/**
   68.32 + * The <code>Stack</code> class represents a last-in-first-out
   68.33 + * (LIFO) stack of objects. It extends class <tt>Vector</tt> with five
   68.34 + * operations that allow a vector to be treated as a stack. The usual
   68.35 + * <tt>push</tt> and <tt>pop</tt> operations are provided, as well as a
   68.36 + * method to <tt>peek</tt> at the top item on the stack, a method to test
   68.37 + * for whether the stack is <tt>empty</tt>, and a method to <tt>search</tt>
   68.38 + * the stack for an item and discover how far it is from the top.
   68.39 + * <p>
   68.40 + * When a stack is first created, it contains no items.
   68.41 + *
   68.42 + * <p>A more complete and consistent set of LIFO stack operations is
   68.43 + * provided by the {@link Deque} interface and its implementations, which
   68.44 + * should be used in preference to this class.  For example:
   68.45 + * <pre>   {@code
   68.46 + *   Deque<Integer> stack = new ArrayDeque<Integer>();}</pre>
   68.47 + *
   68.48 + * @author  Jonathan Payne
   68.49 + * @since   JDK1.0
   68.50 + */
   68.51 +public
   68.52 +class Stack<E> extends Vector<E> {
   68.53 +    /**
   68.54 +     * Creates an empty Stack.
   68.55 +     */
   68.56 +    public Stack() {
   68.57 +    }
   68.58 +
   68.59 +    /**
   68.60 +     * Pushes an item onto the top of this stack. This has exactly
   68.61 +     * the same effect as:
   68.62 +     * <blockquote><pre>
   68.63 +     * addElement(item)</pre></blockquote>
   68.64 +     *
   68.65 +     * @param   item   the item to be pushed onto this stack.
   68.66 +     * @return  the <code>item</code> argument.
   68.67 +     * @see     java.util.Vector#addElement
   68.68 +     */
   68.69 +    public E push(E item) {
   68.70 +        addElement(item);
   68.71 +
   68.72 +        return item;
   68.73 +    }
   68.74 +
   68.75 +    /**
   68.76 +     * Removes the object at the top of this stack and returns that
   68.77 +     * object as the value of this function.
   68.78 +     *
   68.79 +     * @return  The object at the top of this stack (the last item
   68.80 +     *          of the <tt>Vector</tt> object).
   68.81 +     * @throws  EmptyStackException  if this stack is empty.
   68.82 +     */
   68.83 +    public synchronized E pop() {
   68.84 +        E       obj;
   68.85 +        int     len = size();
   68.86 +
   68.87 +        obj = peek();
   68.88 +        removeElementAt(len - 1);
   68.89 +
   68.90 +        return obj;
   68.91 +    }
   68.92 +
   68.93 +    /**
   68.94 +     * Looks at the object at the top of this stack without removing it
   68.95 +     * from the stack.
   68.96 +     *
   68.97 +     * @return  the object at the top of this stack (the last item
   68.98 +     *          of the <tt>Vector</tt> object).
   68.99 +     * @throws  EmptyStackException  if this stack is empty.
  68.100 +     */
  68.101 +    public synchronized E peek() {
  68.102 +        int     len = size();
  68.103 +
  68.104 +        if (len == 0)
  68.105 +            throw new EmptyStackException();
  68.106 +        return elementAt(len - 1);
  68.107 +    }
  68.108 +
  68.109 +    /**
  68.110 +     * Tests if this stack is empty.
  68.111 +     *
  68.112 +     * @return  <code>true</code> if and only if this stack contains
  68.113 +     *          no items; <code>false</code> otherwise.
  68.114 +     */
  68.115 +    public boolean empty() {
  68.116 +        return size() == 0;
  68.117 +    }
  68.118 +
  68.119 +    /**
  68.120 +     * Returns the 1-based position where an object is on this stack.
  68.121 +     * If the object <tt>o</tt> occurs as an item in this stack, this
  68.122 +     * method returns the distance from the top of the stack of the
  68.123 +     * occurrence nearest the top of the stack; the topmost item on the
  68.124 +     * stack is considered to be at distance <tt>1</tt>. The <tt>equals</tt>
  68.125 +     * method is used to compare <tt>o</tt> to the
  68.126 +     * items in this stack.
  68.127 +     *
  68.128 +     * @param   o   the desired object.
  68.129 +     * @return  the 1-based position from the top of the stack where
  68.130 +     *          the object is located; the return value <code>-1</code>
  68.131 +     *          indicates that the object is not on the stack.
  68.132 +     */
  68.133 +    public synchronized int search(Object o) {
  68.134 +        int i = lastIndexOf(o);
  68.135 +
  68.136 +        if (i >= 0) {
  68.137 +            return size() - i;
  68.138 +        }
  68.139 +        return -1;
  68.140 +    }
  68.141 +
  68.142 +    /** use serialVersionUID from JDK 1.0.2 for interoperability */
  68.143 +    private static final long serialVersionUID = 1224463164541339165L;
  68.144 +}
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/emul/compact/src/main/java/java/util/StringTokenizer.java	Tue Feb 05 17:04:22 2013 +0100
    69.3 @@ -0,0 +1,431 @@
    69.4 +/*
    69.5 + * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
    69.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    69.7 + *
    69.8 + * This code is free software; you can redistribute it and/or modify it
    69.9 + * under the terms of the GNU General Public License version 2 only, as
   69.10 + * published by the Free Software Foundation.  Oracle designates this
   69.11 + * particular file as subject to the "Classpath" exception as provided
   69.12 + * by Oracle in the LICENSE file that accompanied this code.
   69.13 + *
   69.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   69.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   69.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   69.17 + * version 2 for more details (a copy is included in the LICENSE file that
   69.18 + * accompanied this code).
   69.19 + *
   69.20 + * You should have received a copy of the GNU General Public License version
   69.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   69.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   69.23 + *
   69.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   69.25 + * or visit www.oracle.com if you need additional information or have any
   69.26 + * questions.
   69.27 + */
   69.28 +
   69.29 +package java.util;
   69.30 +
   69.31 +import java.lang.*;
   69.32 +
   69.33 +/**
   69.34 + * The string tokenizer class allows an application to break a
   69.35 + * string into tokens. The tokenization method is much simpler than
   69.36 + * the one used by the <code>StreamTokenizer</code> class. The
   69.37 + * <code>StringTokenizer</code> methods do not distinguish among
   69.38 + * identifiers, numbers, and quoted strings, nor do they recognize
   69.39 + * and skip comments.
   69.40 + * <p>
   69.41 + * The set of delimiters (the characters that separate tokens) may
   69.42 + * be specified either at creation time or on a per-token basis.
   69.43 + * <p>
   69.44 + * An instance of <code>StringTokenizer</code> behaves in one of two
   69.45 + * ways, depending on whether it was created with the
   69.46 + * <code>returnDelims</code> flag having the value <code>true</code>
   69.47 + * or <code>false</code>:
   69.48 + * <ul>
   69.49 + * <li>If the flag is <code>false</code>, delimiter characters serve to
   69.50 + *     separate tokens. A token is a maximal sequence of consecutive
   69.51 + *     characters that are not delimiters.
   69.52 + * <li>If the flag is <code>true</code>, delimiter characters are themselves
   69.53 + *     considered to be tokens. A token is thus either one delimiter
   69.54 + *     character, or a maximal sequence of consecutive characters that are
   69.55 + *     not delimiters.
   69.56 + * </ul><p>
   69.57 + * A <tt>StringTokenizer</tt> object internally maintains a current
   69.58 + * position within the string to be tokenized. Some operations advance this
   69.59 + * current position past the characters processed.<p>
   69.60 + * A token is returned by taking a substring of the string that was used to
   69.61 + * create the <tt>StringTokenizer</tt> object.
   69.62 + * <p>
   69.63 + * The following is one example of the use of the tokenizer. The code:
   69.64 + * <blockquote><pre>
   69.65 + *     StringTokenizer st = new StringTokenizer("this is a test");
   69.66 + *     while (st.hasMoreTokens()) {
   69.67 + *         System.out.println(st.nextToken());
   69.68 + *     }
   69.69 + * </pre></blockquote>
   69.70 + * <p>
   69.71 + * prints the following output:
   69.72 + * <blockquote><pre>
   69.73 + *     this
   69.74 + *     is
   69.75 + *     a
   69.76 + *     test
   69.77 + * </pre></blockquote>
   69.78 + *
   69.79 + * <p>
   69.80 + * <tt>StringTokenizer</tt> is a legacy class that is retained for
   69.81 + * compatibility reasons although its use is discouraged in new code. It is
   69.82 + * recommended that anyone seeking this functionality use the <tt>split</tt>
   69.83 + * method of <tt>String</tt> or the java.util.regex package instead.
   69.84 + * <p>
   69.85 + * The following example illustrates how the <tt>String.split</tt>
   69.86 + * method can be used to break up a string into its basic tokens:
   69.87 + * <blockquote><pre>
   69.88 + *     String[] result = "this is a test".split("\\s");
   69.89 + *     for (int x=0; x&lt;result.length; x++)
   69.90 + *         System.out.println(result[x]);
   69.91 + * </pre></blockquote>
   69.92 + * <p>
   69.93 + * prints the following output:
   69.94 + * <blockquote><pre>
   69.95 + *     this
   69.96 + *     is
   69.97 + *     a
   69.98 + *     test
   69.99 + * </pre></blockquote>
  69.100 + *
  69.101 + * @author  unascribed
  69.102 + * @see     java.io.StreamTokenizer
  69.103 + * @since   JDK1.0
  69.104 + */
  69.105 +public
  69.106 +class StringTokenizer implements Enumeration<Object> {
  69.107 +    private int currentPosition;
  69.108 +    private int newPosition;
  69.109 +    private int maxPosition;
  69.110 +    private String str;
  69.111 +    private String delimiters;
  69.112 +    private boolean retDelims;
  69.113 +    private boolean delimsChanged;
  69.114 +
  69.115 +    /**
  69.116 +     * maxDelimCodePoint stores the value of the delimiter character with the
  69.117 +     * highest value. It is used to optimize the detection of delimiter
  69.118 +     * characters.
  69.119 +     *
  69.120 +     * It is unlikely to provide any optimization benefit in the
  69.121 +     * hasSurrogates case because most string characters will be
  69.122 +     * smaller than the limit, but we keep it so that the two code
  69.123 +     * paths remain similar.
  69.124 +     */
  69.125 +    private int maxDelimCodePoint;
  69.126 +
  69.127 +    /**
  69.128 +     * If delimiters include any surrogates (including surrogate
  69.129 +     * pairs), hasSurrogates is true and the tokenizer uses the
  69.130 +     * different code path. This is because String.indexOf(int)
  69.131 +     * doesn't handle unpaired surrogates as a single character.
  69.132 +     */
  69.133 +    private boolean hasSurrogates = false;
  69.134 +
  69.135 +    /**
  69.136 +     * When hasSurrogates is true, delimiters are converted to code
  69.137 +     * points and isDelimiter(int) is used to determine if the given
  69.138 +     * codepoint is a delimiter.
  69.139 +     */
  69.140 +    private int[] delimiterCodePoints;
  69.141 +
  69.142 +    /**
  69.143 +     * Set maxDelimCodePoint to the highest char in the delimiter set.
  69.144 +     */
  69.145 +    private void setMaxDelimCodePoint() {
  69.146 +        if (delimiters == null) {
  69.147 +            maxDelimCodePoint = 0;
  69.148 +            return;
  69.149 +        }
  69.150 +
  69.151 +        int m = 0;
  69.152 +        int c;
  69.153 +        int count = 0;
  69.154 +        for (int i = 0; i < delimiters.length(); i += Character.charCount(c)) {
  69.155 +            c = delimiters.charAt(i);
  69.156 +            if (c >= Character.MIN_HIGH_SURROGATE && c <= Character.MAX_LOW_SURROGATE) {
  69.157 +                c = delimiters.codePointAt(i);
  69.158 +                hasSurrogates = true;
  69.159 +            }
  69.160 +            if (m < c)
  69.161 +                m = c;
  69.162 +            count++;
  69.163 +        }
  69.164 +        maxDelimCodePoint = m;
  69.165 +
  69.166 +        if (hasSurrogates) {
  69.167 +            delimiterCodePoints = new int[count];
  69.168 +            for (int i = 0, j = 0; i < count; i++, j += Character.charCount(c)) {
  69.169 +                c = delimiters.codePointAt(j);
  69.170 +                delimiterCodePoints[i] = c;
  69.171 +            }
  69.172 +        }
  69.173 +    }
  69.174 +
  69.175 +    /**
  69.176 +     * Constructs a string tokenizer for the specified string. All
  69.177 +     * characters in the <code>delim</code> argument are the delimiters
  69.178 +     * for separating tokens.
  69.179 +     * <p>
  69.180 +     * If the <code>returnDelims</code> flag is <code>true</code>, then
  69.181 +     * the delimiter characters are also returned as tokens. Each
  69.182 +     * delimiter is returned as a string of length one. If the flag is
  69.183 +     * <code>false</code>, the delimiter characters are skipped and only
  69.184 +     * serve as separators between tokens.
  69.185 +     * <p>
  69.186 +     * Note that if <tt>delim</tt> is <tt>null</tt>, this constructor does
  69.187 +     * not throw an exception. However, trying to invoke other methods on the
  69.188 +     * resulting <tt>StringTokenizer</tt> may result in a
  69.189 +     * <tt>NullPointerException</tt>.
  69.190 +     *
  69.191 +     * @param   str            a string to be parsed.
  69.192 +     * @param   delim          the delimiters.
  69.193 +     * @param   returnDelims   flag indicating whether to return the delimiters
  69.194 +     *                         as tokens.
  69.195 +     * @exception NullPointerException if str is <CODE>null</CODE>
  69.196 +     */
  69.197 +    public StringTokenizer(String str, String delim, boolean returnDelims) {
  69.198 +        currentPosition = 0;
  69.199 +        newPosition = -1;
  69.200 +        delimsChanged = false;
  69.201 +        this.str = str;
  69.202 +        maxPosition = str.length();
  69.203 +        delimiters = delim;
  69.204 +        retDelims = returnDelims;
  69.205 +        setMaxDelimCodePoint();
  69.206 +    }
  69.207 +
  69.208 +    /**
  69.209 +     * Constructs a string tokenizer for the specified string. The
  69.210 +     * characters in the <code>delim</code> argument are the delimiters
  69.211 +     * for separating tokens. Delimiter characters themselves will not
  69.212 +     * be treated as tokens.
  69.213 +     * <p>
  69.214 +     * Note that if <tt>delim</tt> is <tt>null</tt>, this constructor does
  69.215 +     * not throw an exception. However, trying to invoke other methods on the
  69.216 +     * resulting <tt>StringTokenizer</tt> may result in a
  69.217 +     * <tt>NullPointerException</tt>.
  69.218 +     *
  69.219 +     * @param   str     a string to be parsed.
  69.220 +     * @param   delim   the delimiters.
  69.221 +     * @exception NullPointerException if str is <CODE>null</CODE>
  69.222 +     */
  69.223 +    public StringTokenizer(String str, String delim) {
  69.224 +        this(str, delim, false);
  69.225 +    }
  69.226 +
  69.227 +    /**
  69.228 +     * Constructs a string tokenizer for the specified string. The
  69.229 +     * tokenizer uses the default delimiter set, which is
  69.230 +     * <code>"&nbsp;&#92;t&#92;n&#92;r&#92;f"</code>: the space character,
  69.231 +     * the tab character, the newline character, the carriage-return character,
  69.232 +     * and the form-feed character. Delimiter characters themselves will
  69.233 +     * not be treated as tokens.
  69.234 +     *
  69.235 +     * @param   str   a string to be parsed.
  69.236 +     * @exception NullPointerException if str is <CODE>null</CODE>
  69.237 +     */
  69.238 +    public StringTokenizer(String str) {
  69.239 +        this(str, " \t\n\r\f", false);
  69.240 +    }
  69.241 +
  69.242 +    /**
  69.243 +     * Skips delimiters starting from the specified position. If retDelims
  69.244 +     * is false, returns the index of the first non-delimiter character at or
  69.245 +     * after startPos. If retDelims is true, startPos is returned.
  69.246 +     */
  69.247 +    private int skipDelimiters(int startPos) {
  69.248 +        if (delimiters == null)
  69.249 +            throw new NullPointerException();
  69.250 +
  69.251 +        int position = startPos;
  69.252 +        while (!retDelims && position < maxPosition) {
  69.253 +            if (!hasSurrogates) {
  69.254 +                char c = str.charAt(position);
  69.255 +                if ((c > maxDelimCodePoint) || (delimiters.indexOf(c) < 0))
  69.256 +                    break;
  69.257 +                position++;
  69.258 +            } else {
  69.259 +                int c = str.codePointAt(position);
  69.260 +                if ((c > maxDelimCodePoint) || !isDelimiter(c)) {
  69.261 +                    break;
  69.262 +                }
  69.263 +                position += Character.charCount(c);
  69.264 +            }
  69.265 +        }
  69.266 +        return position;
  69.267 +    }
  69.268 +
  69.269 +    /**
  69.270 +     * Skips ahead from startPos and returns the index of the next delimiter
  69.271 +     * character encountered, or maxPosition if no such delimiter is found.
  69.272 +     */
  69.273 +    private int scanToken(int startPos) {
  69.274 +        int position = startPos;
  69.275 +        while (position < maxPosition) {
  69.276 +            if (!hasSurrogates) {
  69.277 +                char c = str.charAt(position);
  69.278 +                if ((c <= maxDelimCodePoint) && (delimiters.indexOf(c) >= 0))
  69.279 +                    break;
  69.280 +                position++;
  69.281 +            } else {
  69.282 +                int c = str.codePointAt(position);
  69.283 +                if ((c <= maxDelimCodePoint) && isDelimiter(c))
  69.284 +                    break;
  69.285 +                position += Character.charCount(c);
  69.286 +            }
  69.287 +        }
  69.288 +        if (retDelims && (startPos == position)) {
  69.289 +            if (!hasSurrogates) {
  69.290 +                char c = str.charAt(position);
  69.291 +                if ((c <= maxDelimCodePoint) && (delimiters.indexOf(c) >= 0))
  69.292 +                    position++;
  69.293 +            } else {
  69.294 +                int c = str.codePointAt(position);
  69.295 +                if ((c <= maxDelimCodePoint) && isDelimiter(c))
  69.296 +                    position += Character.charCount(c);
  69.297 +            }
  69.298 +        }
  69.299 +        return position;
  69.300 +    }
  69.301 +
  69.302 +    private boolean isDelimiter(int codePoint) {
  69.303 +        for (int i = 0; i < delimiterCodePoints.length; i++) {
  69.304 +            if (delimiterCodePoints[i] == codePoint) {
  69.305 +                return true;
  69.306 +            }
  69.307 +        }
  69.308 +        return false;
  69.309 +    }
  69.310 +
  69.311 +    /**
  69.312 +     * Tests if there are more tokens available from this tokenizer's string.
  69.313 +     * If this method returns <tt>true</tt>, then a subsequent call to
  69.314 +     * <tt>nextToken</tt> with no argument will successfully return a token.
  69.315 +     *
  69.316 +     * @return  <code>true</code> if and only if there is at least one token
  69.317 +     *          in the string after the current position; <code>false</code>
  69.318 +     *          otherwise.
  69.319 +     */
  69.320 +    public boolean hasMoreTokens() {
  69.321 +        /*
  69.322 +         * Temporarily store this position and use it in the following
  69.323 +         * nextToken() method only if the delimiters haven't been changed in
  69.324 +         * that nextToken() invocation.
  69.325 +         */
  69.326 +        newPosition = skipDelimiters(currentPosition);
  69.327 +        return (newPosition < maxPosition);
  69.328 +    }
  69.329 +
  69.330 +    /**
  69.331 +     * Returns the next token from this string tokenizer.
  69.332 +     *
  69.333 +     * @return     the next token from this string tokenizer.
  69.334 +     * @exception  NoSuchElementException  if there are no more tokens in this
  69.335 +     *               tokenizer's string.
  69.336 +     */
  69.337 +    public String nextToken() {
  69.338 +        /*
  69.339 +         * If next position already computed in hasMoreElements() and
  69.340 +         * delimiters have changed between the computation and this invocation,
  69.341 +         * then use the computed value.
  69.342 +         */
  69.343 +
  69.344 +        currentPosition = (newPosition >= 0 && !delimsChanged) ?
  69.345 +            newPosition : skipDelimiters(currentPosition);
  69.346 +
  69.347 +        /* Reset these anyway */
  69.348 +        delimsChanged = false;
  69.349 +        newPosition = -1;
  69.350 +
  69.351 +        if (currentPosition >= maxPosition)
  69.352 +            throw new NoSuchElementException();
  69.353 +        int start = currentPosition;
  69.354 +        currentPosition = scanToken(currentPosition);
  69.355 +        return str.substring(start, currentPosition);
  69.356 +    }
  69.357 +
  69.358 +    /**
  69.359 +     * Returns the next token in this string tokenizer's string. First,
  69.360 +     * the set of characters considered to be delimiters by this
  69.361 +     * <tt>StringTokenizer</tt> object is changed to be the characters in
  69.362 +     * the string <tt>delim</tt>. Then the next token in the string
  69.363 +     * after the current position is returned. The current position is
  69.364 +     * advanced beyond the recognized token.  The new delimiter set
  69.365 +     * remains the default after this call.
  69.366 +     *
  69.367 +     * @param      delim   the new delimiters.
  69.368 +     * @return     the next token, after switching to the new delimiter set.
  69.369 +     * @exception  NoSuchElementException  if there are no more tokens in this
  69.370 +     *               tokenizer's string.
  69.371 +     * @exception NullPointerException if delim is <CODE>null</CODE>
  69.372 +     */
  69.373 +    public String nextToken(String delim) {
  69.374 +        delimiters = delim;
  69.375 +
  69.376 +        /* delimiter string specified, so set the appropriate flag. */
  69.377 +        delimsChanged = true;
  69.378 +
  69.379 +        setMaxDelimCodePoint();
  69.380 +        return nextToken();
  69.381 +    }
  69.382 +
  69.383 +    /**
  69.384 +     * Returns the same value as the <code>hasMoreTokens</code>
  69.385 +     * method. It exists so that this class can implement the
  69.386 +     * <code>Enumeration</code> interface.
  69.387 +     *
  69.388 +     * @return  <code>true</code> if there are more tokens;
  69.389 +     *          <code>false</code> otherwise.
  69.390 +     * @see     java.util.Enumeration
  69.391 +     * @see     java.util.StringTokenizer#hasMoreTokens()
  69.392 +     */
  69.393 +    public boolean hasMoreElements() {
  69.394 +        return hasMoreTokens();
  69.395 +    }
  69.396 +
  69.397 +    /**
  69.398 +     * Returns the same value as the <code>nextToken</code> method,
  69.399 +     * except that its declared return value is <code>Object</code> rather than
  69.400 +     * <code>String</code>. It exists so that this class can implement the
  69.401 +     * <code>Enumeration</code> interface.
  69.402 +     *
  69.403 +     * @return     the next token in the string.
  69.404 +     * @exception  NoSuchElementException  if there are no more tokens in this
  69.405 +     *               tokenizer's string.
  69.406 +     * @see        java.util.Enumeration
  69.407 +     * @see        java.util.StringTokenizer#nextToken()
  69.408 +     */
  69.409 +    public Object nextElement() {
  69.410 +        return nextToken();
  69.411 +    }
  69.412 +
  69.413 +    /**
  69.414 +     * Calculates the number of times that this tokenizer's
  69.415 +     * <code>nextToken</code> method can be called before it generates an
  69.416 +     * exception. The current position is not advanced.
  69.417 +     *
  69.418 +     * @return  the number of tokens remaining in the string using the current
  69.419 +     *          delimiter set.
  69.420 +     * @see     java.util.StringTokenizer#nextToken()
  69.421 +     */
  69.422 +    public int countTokens() {
  69.423 +        int count = 0;
  69.424 +        int currpos = currentPosition;
  69.425 +        while (currpos < maxPosition) {
  69.426 +            currpos = skipDelimiters(currpos);
  69.427 +            if (currpos >= maxPosition)
  69.428 +                break;
  69.429 +            currpos = scanToken(currpos);
  69.430 +            count++;
  69.431 +        }
  69.432 +        return count;
  69.433 +    }
  69.434 +}
    70.1 --- a/emul/compact/src/main/java/java/util/TimSort.java	Tue Feb 05 16:40:01 2013 +0100
    70.2 +++ b/emul/compact/src/main/java/java/util/TimSort.java	Tue Feb 05 17:04:22 2013 +0100
    70.3 @@ -25,7 +25,6 @@
    70.4  
    70.5  package java.util;
    70.6  
    70.7 -import org.apidesign.bck2brwsr.emul.lang.System;
    70.8  
    70.9  /**
   70.10   * A stable, adaptive, iterative mergesort that requires far fewer than
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/emul/compact/src/main/java/java/util/Vector.java	Tue Feb 05 17:04:22 2013 +0100
    71.3 @@ -0,0 +1,1194 @@
    71.4 +/*
    71.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
    71.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    71.7 + *
    71.8 + * This code is free software; you can redistribute it and/or modify it
    71.9 + * under the terms of the GNU General Public License version 2 only, as
   71.10 + * published by the Free Software Foundation.  Oracle designates this
   71.11 + * particular file as subject to the "Classpath" exception as provided
   71.12 + * by Oracle in the LICENSE file that accompanied this code.
   71.13 + *
   71.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   71.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   71.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   71.17 + * version 2 for more details (a copy is included in the LICENSE file that
   71.18 + * accompanied this code).
   71.19 + *
   71.20 + * You should have received a copy of the GNU General Public License version
   71.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   71.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   71.23 + *
   71.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   71.25 + * or visit www.oracle.com if you need additional information or have any
   71.26 + * questions.
   71.27 + */
   71.28 +
   71.29 +package java.util;
   71.30 +
   71.31 +
   71.32 +/**
   71.33 + * The {@code Vector} class implements a growable array of
   71.34 + * objects. Like an array, it contains components that can be
   71.35 + * accessed using an integer index. However, the size of a
   71.36 + * {@code Vector} can grow or shrink as needed to accommodate
   71.37 + * adding and removing items after the {@code Vector} has been created.
   71.38 + *
   71.39 + * <p>Each vector tries to optimize storage management by maintaining a
   71.40 + * {@code capacity} and a {@code capacityIncrement}. The
   71.41 + * {@code capacity} is always at least as large as the vector
   71.42 + * size; it is usually larger because as components are added to the
   71.43 + * vector, the vector's storage increases in chunks the size of
   71.44 + * {@code capacityIncrement}. An application can increase the
   71.45 + * capacity of a vector before inserting a large number of
   71.46 + * components; this reduces the amount of incremental reallocation.
   71.47 + *
   71.48 + * <p><a name="fail-fast"/>
   71.49 + * The iterators returned by this class's {@link #iterator() iterator} and
   71.50 + * {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:
   71.51 + * if the vector is structurally modified at any time after the iterator is
   71.52 + * created, in any way except through the iterator's own
   71.53 + * {@link ListIterator#remove() remove} or
   71.54 + * {@link ListIterator#add(Object) add} methods, the iterator will throw a
   71.55 + * {@link ConcurrentModificationException}.  Thus, in the face of
   71.56 + * concurrent modification, the iterator fails quickly and cleanly, rather
   71.57 + * than risking arbitrary, non-deterministic behavior at an undetermined
   71.58 + * time in the future.  The {@link Enumeration Enumerations} returned by
   71.59 + * the {@link #elements() elements} method are <em>not</em> fail-fast.
   71.60 + *
   71.61 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
   71.62 + * as it is, generally speaking, impossible to make any hard guarantees in the
   71.63 + * presence of unsynchronized concurrent modification.  Fail-fast iterators
   71.64 + * throw {@code ConcurrentModificationException} on a best-effort basis.
   71.65 + * Therefore, it would be wrong to write a program that depended on this
   71.66 + * exception for its correctness:  <i>the fail-fast behavior of iterators
   71.67 + * should be used only to detect bugs.</i>
   71.68 + *
   71.69 + * <p>As of the Java 2 platform v1.2, this class was retrofitted to
   71.70 + * implement the {@link List} interface, making it a member of the
   71.71 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
   71.72 + * Java Collections Framework</a>.  Unlike the new collection
   71.73 + * implementations, {@code Vector} is synchronized.  If a thread-safe
   71.74 + * implementation is not needed, it is recommended to use {@link
   71.75 + * ArrayList} in place of {@code Vector}.
   71.76 + *
   71.77 + * @author  Lee Boynton
   71.78 + * @author  Jonathan Payne
   71.79 + * @see Collection
   71.80 + * @see LinkedList
   71.81 + * @since   JDK1.0
   71.82 + */
   71.83 +public class Vector<E>
   71.84 +    extends AbstractList<E>
   71.85 +    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
   71.86 +{
   71.87 +    /**
   71.88 +     * The array buffer into which the components of the vector are
   71.89 +     * stored. The capacity of the vector is the length of this array buffer,
   71.90 +     * and is at least large enough to contain all the vector's elements.
   71.91 +     *
   71.92 +     * <p>Any array elements following the last element in the Vector are null.
   71.93 +     *
   71.94 +     * @serial
   71.95 +     */
   71.96 +    protected Object[] elementData;
   71.97 +
   71.98 +    /**
   71.99 +     * The number of valid components in this {@code Vector} object.
  71.100 +     * Components {@code elementData[0]} through
  71.101 +     * {@code elementData[elementCount-1]} are the actual items.
  71.102 +     *
  71.103 +     * @serial
  71.104 +     */
  71.105 +    protected int elementCount;
  71.106 +
  71.107 +    /**
  71.108 +     * The amount by which the capacity of the vector is automatically
  71.109 +     * incremented when its size becomes greater than its capacity.  If
  71.110 +     * the capacity increment is less than or equal to zero, the capacity
  71.111 +     * of the vector is doubled each time it needs to grow.
  71.112 +     *
  71.113 +     * @serial
  71.114 +     */
  71.115 +    protected int capacityIncrement;
  71.116 +
  71.117 +    /** use serialVersionUID from JDK 1.0.2 for interoperability */
  71.118 +    private static final long serialVersionUID = -2767605614048989439L;
  71.119 +
  71.120 +    /**
  71.121 +     * Constructs an empty vector with the specified initial capacity and
  71.122 +     * capacity increment.
  71.123 +     *
  71.124 +     * @param   initialCapacity     the initial capacity of the vector
  71.125 +     * @param   capacityIncrement   the amount by which the capacity is
  71.126 +     *                              increased when the vector overflows
  71.127 +     * @throws IllegalArgumentException if the specified initial capacity
  71.128 +     *         is negative
  71.129 +     */
  71.130 +    public Vector(int initialCapacity, int capacityIncrement) {
  71.131 +        super();
  71.132 +        if (initialCapacity < 0)
  71.133 +            throw new IllegalArgumentException("Illegal Capacity: "+
  71.134 +                                               initialCapacity);
  71.135 +        this.elementData = new Object[initialCapacity];
  71.136 +        this.capacityIncrement = capacityIncrement;
  71.137 +    }
  71.138 +
  71.139 +    /**
  71.140 +     * Constructs an empty vector with the specified initial capacity and
  71.141 +     * with its capacity increment equal to zero.
  71.142 +     *
  71.143 +     * @param   initialCapacity   the initial capacity of the vector
  71.144 +     * @throws IllegalArgumentException if the specified initial capacity
  71.145 +     *         is negative
  71.146 +     */
  71.147 +    public Vector(int initialCapacity) {
  71.148 +        this(initialCapacity, 0);
  71.149 +    }
  71.150 +
  71.151 +    /**
  71.152 +     * Constructs an empty vector so that its internal data array
  71.153 +     * has size {@code 10} and its standard capacity increment is
  71.154 +     * zero.
  71.155 +     */
  71.156 +    public Vector() {
  71.157 +        this(10);
  71.158 +    }
  71.159 +
  71.160 +    /**
  71.161 +     * Constructs a vector containing the elements of the specified
  71.162 +     * collection, in the order they are returned by the collection's
  71.163 +     * iterator.
  71.164 +     *
  71.165 +     * @param c the collection whose elements are to be placed into this
  71.166 +     *       vector
  71.167 +     * @throws NullPointerException if the specified collection is null
  71.168 +     * @since   1.2
  71.169 +     */
  71.170 +    public Vector(Collection<? extends E> c) {
  71.171 +        elementData = c.toArray();
  71.172 +        elementCount = elementData.length;
  71.173 +        // c.toArray might (incorrectly) not return Object[] (see 6260652)
  71.174 +        if (elementData.getClass() != Object[].class)
  71.175 +            elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
  71.176 +    }
  71.177 +
  71.178 +    /**
  71.179 +     * Copies the components of this vector into the specified array.
  71.180 +     * The item at index {@code k} in this vector is copied into
  71.181 +     * component {@code k} of {@code anArray}.
  71.182 +     *
  71.183 +     * @param  anArray the array into which the components get copied
  71.184 +     * @throws NullPointerException if the given array is null
  71.185 +     * @throws IndexOutOfBoundsException if the specified array is not
  71.186 +     *         large enough to hold all the components of this vector
  71.187 +     * @throws ArrayStoreException if a component of this vector is not of
  71.188 +     *         a runtime type that can be stored in the specified array
  71.189 +     * @see #toArray(Object[])
  71.190 +     */
  71.191 +    public synchronized void copyInto(Object[] anArray) {
  71.192 +        System.arraycopy(elementData, 0, anArray, 0, elementCount);
  71.193 +    }
  71.194 +
  71.195 +    /**
  71.196 +     * Trims the capacity of this vector to be the vector's current
  71.197 +     * size. If the capacity of this vector is larger than its current
  71.198 +     * size, then the capacity is changed to equal the size by replacing
  71.199 +     * its internal data array, kept in the field {@code elementData},
  71.200 +     * with a smaller one. An application can use this operation to
  71.201 +     * minimize the storage of a vector.
  71.202 +     */
  71.203 +    public synchronized void trimToSize() {
  71.204 +        modCount++;
  71.205 +        int oldCapacity = elementData.length;
  71.206 +        if (elementCount < oldCapacity) {
  71.207 +            elementData = Arrays.copyOf(elementData, elementCount);
  71.208 +        }
  71.209 +    }
  71.210 +
  71.211 +    /**
  71.212 +     * Increases the capacity of this vector, if necessary, to ensure
  71.213 +     * that it can hold at least the number of components specified by
  71.214 +     * the minimum capacity argument.
  71.215 +     *
  71.216 +     * <p>If the current capacity of this vector is less than
  71.217 +     * {@code minCapacity}, then its capacity is increased by replacing its
  71.218 +     * internal data array, kept in the field {@code elementData}, with a
  71.219 +     * larger one.  The size of the new data array will be the old size plus
  71.220 +     * {@code capacityIncrement}, unless the value of
  71.221 +     * {@code capacityIncrement} is less than or equal to zero, in which case
  71.222 +     * the new capacity will be twice the old capacity; but if this new size
  71.223 +     * is still smaller than {@code minCapacity}, then the new capacity will
  71.224 +     * be {@code minCapacity}.
  71.225 +     *
  71.226 +     * @param minCapacity the desired minimum capacity
  71.227 +     */
  71.228 +    public synchronized void ensureCapacity(int minCapacity) {
  71.229 +        if (minCapacity > 0) {
  71.230 +            modCount++;
  71.231 +            ensureCapacityHelper(minCapacity);
  71.232 +        }
  71.233 +    }
  71.234 +
  71.235 +    /**
  71.236 +     * This implements the unsynchronized semantics of ensureCapacity.
  71.237 +     * Synchronized methods in this class can internally call this
  71.238 +     * method for ensuring capacity without incurring the cost of an
  71.239 +     * extra synchronization.
  71.240 +     *
  71.241 +     * @see #ensureCapacity(int)
  71.242 +     */
  71.243 +    private void ensureCapacityHelper(int minCapacity) {
  71.244 +        // overflow-conscious code
  71.245 +        if (minCapacity - elementData.length > 0)
  71.246 +            grow(minCapacity);
  71.247 +    }
  71.248 +
  71.249 +    /**
  71.250 +     * The maximum size of array to allocate.
  71.251 +     * Some VMs reserve some header words in an array.
  71.252 +     * Attempts to allocate larger arrays may result in
  71.253 +     * OutOfMemoryError: Requested array size exceeds VM limit
  71.254 +     */
  71.255 +    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
  71.256 +
  71.257 +    private void grow(int minCapacity) {
  71.258 +        // overflow-conscious code
  71.259 +        int oldCapacity = elementData.length;
  71.260 +        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
  71.261 +                                         capacityIncrement : oldCapacity);
  71.262 +        if (newCapacity - minCapacity < 0)
  71.263 +            newCapacity = minCapacity;
  71.264 +        if (newCapacity - MAX_ARRAY_SIZE > 0)
  71.265 +            newCapacity = hugeCapacity(minCapacity);
  71.266 +        elementData = Arrays.copyOf(elementData, newCapacity);
  71.267 +    }
  71.268 +
  71.269 +    private static int hugeCapacity(int minCapacity) {
  71.270 +        if (minCapacity < 0) // overflow
  71.271 +            throw new OutOfMemoryError();
  71.272 +        return (minCapacity > MAX_ARRAY_SIZE) ?
  71.273 +            Integer.MAX_VALUE :
  71.274 +            MAX_ARRAY_SIZE;
  71.275 +    }
  71.276 +
  71.277 +    /**
  71.278 +     * Sets the size of this vector. If the new size is greater than the
  71.279 +     * current size, new {@code null} items are added to the end of
  71.280 +     * the vector. If the new size is less than the current size, all
  71.281 +     * components at index {@code newSize} and greater are discarded.
  71.282 +     *
  71.283 +     * @param  newSize   the new size of this vector
  71.284 +     * @throws ArrayIndexOutOfBoundsException if the new size is negative
  71.285 +     */
  71.286 +    public synchronized void setSize(int newSize) {
  71.287 +        modCount++;
  71.288 +        if (newSize > elementCount) {
  71.289 +            ensureCapacityHelper(newSize);
  71.290 +        } else {
  71.291 +            for (int i = newSize ; i < elementCount ; i++) {
  71.292 +                elementData[i] = null;
  71.293 +            }
  71.294 +        }
  71.295 +        elementCount = newSize;
  71.296 +    }
  71.297 +
  71.298 +    /**
  71.299 +     * Returns the current capacity of this vector.
  71.300 +     *
  71.301 +     * @return  the current capacity (the length of its internal
  71.302 +     *          data array, kept in the field {@code elementData}
  71.303 +     *          of this vector)
  71.304 +     */
  71.305 +    public synchronized int capacity() {
  71.306 +        return elementData.length;
  71.307 +    }
  71.308 +
  71.309 +    /**
  71.310 +     * Returns the number of components in this vector.
  71.311 +     *
  71.312 +     * @return  the number of components in this vector
  71.313 +     */
  71.314 +    public synchronized int size() {
  71.315 +        return elementCount;
  71.316 +    }
  71.317 +
  71.318 +    /**
  71.319 +     * Tests if this vector has no components.
  71.320 +     *
  71.321 +     * @return  {@code true} if and only if this vector has
  71.322 +     *          no components, that is, its size is zero;
  71.323 +     *          {@code false} otherwise.
  71.324 +     */
  71.325 +    public synchronized boolean isEmpty() {
  71.326 +        return elementCount == 0;
  71.327 +    }
  71.328 +
  71.329 +    /**
  71.330 +     * Returns an enumeration of the components of this vector. The
  71.331 +     * returned {@code Enumeration} object will generate all items in
  71.332 +     * this vector. The first item generated is the item at index {@code 0},
  71.333 +     * then the item at index {@code 1}, and so on.
  71.334 +     *
  71.335 +     * @return  an enumeration of the components of this vector
  71.336 +     * @see     Iterator
  71.337 +     */
  71.338 +    public Enumeration<E> elements() {
  71.339 +        return new Enumeration<E>() {
  71.340 +            int count = 0;
  71.341 +
  71.342 +            public boolean hasMoreElements() {
  71.343 +                return count < elementCount;
  71.344 +            }
  71.345 +
  71.346 +            public E nextElement() {
  71.347 +                synchronized (Vector.this) {
  71.348 +                    if (count < elementCount) {
  71.349 +                        return elementData(count++);
  71.350 +                    }
  71.351 +                }
  71.352 +                throw new NoSuchElementException("Vector Enumeration");
  71.353 +            }
  71.354 +        };
  71.355 +    }
  71.356 +
  71.357 +    /**
  71.358 +     * Returns {@code true} if this vector contains the specified element.
  71.359 +     * More formally, returns {@code true} if and only if this vector
  71.360 +     * contains at least one element {@code e} such that
  71.361 +     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
  71.362 +     *
  71.363 +     * @param o element whose presence in this vector is to be tested
  71.364 +     * @return {@code true} if this vector contains the specified element
  71.365 +     */
  71.366 +    public boolean contains(Object o) {
  71.367 +        return indexOf(o, 0) >= 0;
  71.368 +    }
  71.369 +
  71.370 +    /**
  71.371 +     * Returns the index of the first occurrence of the specified element
  71.372 +     * in this vector, or -1 if this vector does not contain the element.
  71.373 +     * More formally, returns the lowest index {@code i} such that
  71.374 +     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
  71.375 +     * or -1 if there is no such index.
  71.376 +     *
  71.377 +     * @param o element to search for
  71.378 +     * @return the index of the first occurrence of the specified element in
  71.379 +     *         this vector, or -1 if this vector does not contain the element
  71.380 +     */
  71.381 +    public int indexOf(Object o) {
  71.382 +        return indexOf(o, 0);
  71.383 +    }
  71.384 +
  71.385 +    /**
  71.386 +     * Returns the index of the first occurrence of the specified element in
  71.387 +     * this vector, searching forwards from {@code index}, or returns -1 if
  71.388 +     * the element is not found.
  71.389 +     * More formally, returns the lowest index {@code i} such that
  71.390 +     * <tt>(i&nbsp;&gt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i))))</tt>,
  71.391 +     * or -1 if there is no such index.
  71.392 +     *
  71.393 +     * @param o element to search for
  71.394 +     * @param index index to start searching from
  71.395 +     * @return the index of the first occurrence of the element in
  71.396 +     *         this vector at position {@code index} or later in the vector;
  71.397 +     *         {@code -1} if the element is not found.
  71.398 +     * @throws IndexOutOfBoundsException if the specified index is negative
  71.399 +     * @see     Object#equals(Object)
  71.400 +     */
  71.401 +    public synchronized int indexOf(Object o, int index) {
  71.402 +        if (o == null) {
  71.403 +            for (int i = index ; i < elementCount ; i++)
  71.404 +                if (elementData[i]==null)
  71.405 +                    return i;
  71.406 +        } else {
  71.407 +            for (int i = index ; i < elementCount ; i++)
  71.408 +                if (o.equals(elementData[i]))
  71.409 +                    return i;
  71.410 +        }
  71.411 +        return -1;
  71.412 +    }
  71.413 +
  71.414 +    /**
  71.415 +     * Returns the index of the last occurrence of the specified element
  71.416 +     * in this vector, or -1 if this vector does not contain the element.
  71.417 +     * More formally, returns the highest index {@code i} such that
  71.418 +     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
  71.419 +     * or -1 if there is no such index.
  71.420 +     *
  71.421 +     * @param o element to search for
  71.422 +     * @return the index of the last occurrence of the specified element in
  71.423 +     *         this vector, or -1 if this vector does not contain the element
  71.424 +     */
  71.425 +    public synchronized int lastIndexOf(Object o) {
  71.426 +        return lastIndexOf(o, elementCount-1);
  71.427 +    }
  71.428 +
  71.429 +    /**
  71.430 +     * Returns the index of the last occurrence of the specified element in
  71.431 +     * this vector, searching backwards from {@code index}, or returns -1 if
  71.432 +     * the element is not found.
  71.433 +     * More formally, returns the highest index {@code i} such that
  71.434 +     * <tt>(i&nbsp;&lt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i))))</tt>,
  71.435 +     * or -1 if there is no such index.
  71.436 +     *
  71.437 +     * @param o element to search for
  71.438 +     * @param index index to start searching backwards from
  71.439 +     * @return the index of the last occurrence of the element at position
  71.440 +     *         less than or equal to {@code index} in this vector;
  71.441 +     *         -1 if the element is not found.
  71.442 +     * @throws IndexOutOfBoundsException if the specified index is greater
  71.443 +     *         than or equal to the current size of this vector
  71.444 +     */
  71.445 +    public synchronized int lastIndexOf(Object o, int index) {
  71.446 +        if (index >= elementCount)
  71.447 +            throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
  71.448 +
  71.449 +        if (o == null) {
  71.450 +            for (int i = index; i >= 0; i--)
  71.451 +                if (elementData[i]==null)
  71.452 +                    return i;
  71.453 +        } else {
  71.454 +            for (int i = index; i >= 0; i--)
  71.455 +                if (o.equals(elementData[i]))
  71.456 +                    return i;
  71.457 +        }
  71.458 +        return -1;
  71.459 +    }
  71.460 +
  71.461 +    /**
  71.462 +     * Returns the component at the specified index.
  71.463 +     *
  71.464 +     * <p>This method is identical in functionality to the {@link #get(int)}
  71.465 +     * method (which is part of the {@link List} interface).
  71.466 +     *
  71.467 +     * @param      index   an index into this vector
  71.468 +     * @return     the component at the specified index
  71.469 +     * @throws ArrayIndexOutOfBoundsException if the index is out of range
  71.470 +     *         ({@code index < 0 || index >= size()})
  71.471 +     */
  71.472 +    public synchronized E elementAt(int index) {
  71.473 +        if (index >= elementCount) {
  71.474 +            throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
  71.475 +        }
  71.476 +
  71.477 +        return elementData(index);
  71.478 +    }
  71.479 +
  71.480 +    /**
  71.481 +     * Returns the first component (the item at index {@code 0}) of
  71.482 +     * this vector.
  71.483 +     *
  71.484 +     * @return     the first component of this vector
  71.485 +     * @throws NoSuchElementException if this vector has no components
  71.486 +     */
  71.487 +    public synchronized E firstElement() {
  71.488 +        if (elementCount == 0) {
  71.489 +            throw new NoSuchElementException();
  71.490 +        }
  71.491 +        return elementData(0);
  71.492 +    }
  71.493 +
  71.494 +    /**
  71.495 +     * Returns the last component of the vector.
  71.496 +     *
  71.497 +     * @return  the last component of the vector, i.e., the component at index
  71.498 +     *          <code>size()&nbsp;-&nbsp;1</code>.
  71.499 +     * @throws NoSuchElementException if this vector is empty
  71.500 +     */
  71.501 +    public synchronized E lastElement() {
  71.502 +        if (elementCount == 0) {
  71.503 +            throw new NoSuchElementException();
  71.504 +        }
  71.505 +        return elementData(elementCount - 1);
  71.506 +    }
  71.507 +
  71.508 +    /**
  71.509 +     * Sets the component at the specified {@code index} of this
  71.510 +     * vector to be the specified object. The previous component at that
  71.511 +     * position is discarded.
  71.512 +     *
  71.513 +     * <p>The index must be a value greater than or equal to {@code 0}
  71.514 +     * and less than the current size of the vector.
  71.515 +     *
  71.516 +     * <p>This method is identical in functionality to the
  71.517 +     * {@link #set(int, Object) set(int, E)}
  71.518 +     * method (which is part of the {@link List} interface). Note that the
  71.519 +     * {@code set} method reverses the order of the parameters, to more closely
  71.520 +     * match array usage.  Note also that the {@code set} method returns the
  71.521 +     * old value that was stored at the specified position.
  71.522 +     *
  71.523 +     * @param      obj     what the component is to be set to
  71.524 +     * @param      index   the specified index
  71.525 +     * @throws ArrayIndexOutOfBoundsException if the index is out of range
  71.526 +     *         ({@code index < 0 || index >= size()})
  71.527 +     */
  71.528 +    public synchronized void setElementAt(E obj, int index) {
  71.529 +        if (index >= elementCount) {
  71.530 +            throw new ArrayIndexOutOfBoundsException(index + " >= " +
  71.531 +                                                     elementCount);
  71.532 +        }
  71.533 +        elementData[index] = obj;
  71.534 +    }
  71.535 +
  71.536 +    /**
  71.537 +     * Deletes the component at the specified index. Each component in
  71.538 +     * this vector with an index greater or equal to the specified
  71.539 +     * {@code index} is shifted downward to have an index one
  71.540 +     * smaller than the value it had previously. The size of this vector
  71.541 +     * is decreased by {@code 1}.
  71.542 +     *
  71.543 +     * <p>The index must be a value greater than or equal to {@code 0}
  71.544 +     * and less than the current size of the vector.
  71.545 +     *
  71.546 +     * <p>This method is identical in functionality to the {@link #remove(int)}
  71.547 +     * method (which is part of the {@link List} interface).  Note that the
  71.548 +     * {@code remove} method returns the old value that was stored at the
  71.549 +     * specified position.
  71.550 +     *
  71.551 +     * @param      index   the index of the object to remove
  71.552 +     * @throws ArrayIndexOutOfBoundsException if the index is out of range
  71.553 +     *         ({@code index < 0 || index >= size()})
  71.554 +     */
  71.555 +    public synchronized void removeElementAt(int index) {
  71.556 +        modCount++;
  71.557 +        if (index >= elementCount) {
  71.558 +            throw new ArrayIndexOutOfBoundsException(index + " >= " +
  71.559 +                                                     elementCount);
  71.560 +        }
  71.561 +        else if (index < 0) {
  71.562 +            throw new ArrayIndexOutOfBoundsException(index);
  71.563 +        }
  71.564 +        int j = elementCount - index - 1;
  71.565 +        if (j > 0) {
  71.566 +            System.arraycopy(elementData, index + 1, elementData, index, j);
  71.567 +        }
  71.568 +        elementCount--;
  71.569 +        elementData[elementCount] = null; /* to let gc do its work */
  71.570 +    }
  71.571 +
  71.572 +    /**
  71.573 +     * Inserts the specified object as a component in this vector at the
  71.574 +     * specified {@code index}. Each component in this vector with
  71.575 +     * an index greater or equal to the specified {@code index} is
  71.576 +     * shifted upward to have an index one greater than the value it had
  71.577 +     * previously.
  71.578 +     *
  71.579 +     * <p>The index must be a value greater than or equal to {@code 0}
  71.580 +     * and less than or equal to the current size of the vector. (If the
  71.581 +     * index is equal to the current size of the vector, the new element
  71.582 +     * is appended to the Vector.)
  71.583 +     *
  71.584 +     * <p>This method is identical in functionality to the
  71.585 +     * {@link #add(int, Object) add(int, E)}
  71.586 +     * method (which is part of the {@link List} interface).  Note that the
  71.587 +     * {@code add} method reverses the order of the parameters, to more closely
  71.588 +     * match array usage.
  71.589 +     *
  71.590 +     * @param      obj     the component to insert
  71.591 +     * @param      index   where to insert the new component
  71.592 +     * @throws ArrayIndexOutOfBoundsException if the index is out of range
  71.593 +     *         ({@code index < 0 || index > size()})
  71.594 +     */
  71.595 +    public synchronized void insertElementAt(E obj, int index) {
  71.596 +        modCount++;
  71.597 +        if (index > elementCount) {
  71.598 +            throw new ArrayIndexOutOfBoundsException(index
  71.599 +                                                     + " > " + elementCount);
  71.600 +        }
  71.601 +        ensureCapacityHelper(elementCount + 1);
  71.602 +        System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
  71.603 +        elementData[index] = obj;
  71.604 +        elementCount++;
  71.605 +    }
  71.606 +
  71.607 +    /**
  71.608 +     * Adds the specified component to the end of this vector,
  71.609 +     * increasing its size by one. The capacity of this vector is
  71.610 +     * increased if its size becomes greater than its capacity.
  71.611 +     *
  71.612 +     * <p>This method is identical in functionality to the
  71.613 +     * {@link #add(Object) add(E)}
  71.614 +     * method (which is part of the {@link List} interface).
  71.615 +     *
  71.616 +     * @param   obj   the component to be added
  71.617 +     */
  71.618 +    public synchronized void addElement(E obj) {
  71.619 +        modCount++;
  71.620 +        ensureCapacityHelper(elementCount + 1);
  71.621 +        elementData[elementCount++] = obj;
  71.622 +    }
  71.623 +
  71.624 +    /**
  71.625 +     * Removes the first (lowest-indexed) occurrence of the argument
  71.626 +     * from this vector. If the object is found in this vector, each
  71.627 +     * component in the vector with an index greater or equal to the
  71.628 +     * object's index is shifted downward to have an index one smaller
  71.629 +     * than the value it had previously.
  71.630 +     *
  71.631 +     * <p>This method is identical in functionality to the
  71.632 +     * {@link #remove(Object)} method (which is part of the
  71.633 +     * {@link List} interface).
  71.634 +     *
  71.635 +     * @param   obj   the component to be removed
  71.636 +     * @return  {@code true} if the argument was a component of this
  71.637 +     *          vector; {@code false} otherwise.
  71.638 +     */
  71.639 +    public synchronized boolean removeElement(Object obj) {
  71.640 +        modCount++;
  71.641 +        int i = indexOf(obj);
  71.642 +        if (i >= 0) {
  71.643 +            removeElementAt(i);
  71.644 +            return true;
  71.645 +        }
  71.646 +        return false;
  71.647 +    }
  71.648 +
  71.649 +    /**
  71.650 +     * Removes all components from this vector and sets its size to zero.
  71.651 +     *
  71.652 +     * <p>This method is identical in functionality to the {@link #clear}
  71.653 +     * method (which is part of the {@link List} interface).
  71.654 +     */
  71.655 +    public synchronized void removeAllElements() {
  71.656 +        modCount++;
  71.657 +        // Let gc do its work
  71.658 +        for (int i = 0; i < elementCount; i++)
  71.659 +            elementData[i] = null;
  71.660 +
  71.661 +        elementCount = 0;
  71.662 +    }
  71.663 +
  71.664 +    /**
  71.665 +     * Returns a clone of this vector. The copy will contain a
  71.666 +     * reference to a clone of the internal data array, not a reference
  71.667 +     * to the original internal data array of this {@code Vector} object.
  71.668 +     *
  71.669 +     * @return  a clone of this vector
  71.670 +     */
  71.671 +    public synchronized Object clone() {
  71.672 +        try {
  71.673 +            @SuppressWarnings("unchecked")
  71.674 +                Vector<E> v = (Vector<E>) super.clone();
  71.675 +            v.elementData = Arrays.copyOf(elementData, elementCount);
  71.676 +            v.modCount = 0;
  71.677 +            return v;
  71.678 +        } catch (CloneNotSupportedException e) {
  71.679 +            // this shouldn't happen, since we are Cloneable
  71.680 +            throw new InternalError();
  71.681 +        }
  71.682 +    }
  71.683 +
  71.684 +    /**
  71.685 +     * Returns an array containing all of the elements in this Vector
  71.686 +     * in the correct order.
  71.687 +     *
  71.688 +     * @since 1.2
  71.689 +     */
  71.690 +    public synchronized Object[] toArray() {
  71.691 +        return Arrays.copyOf(elementData, elementCount);
  71.692 +    }
  71.693 +
  71.694 +    /**
  71.695 +     * Returns an array containing all of the elements in this Vector in the
  71.696 +     * correct order; the runtime type of the returned array is that of the
  71.697 +     * specified array.  If the Vector fits in the specified array, it is
  71.698 +     * returned therein.  Otherwise, a new array is allocated with the runtime
  71.699 +     * type of the specified array and the size of this Vector.
  71.700 +     *
  71.701 +     * <p>If the Vector fits in the specified array with room to spare
  71.702 +     * (i.e., the array has more elements than the Vector),
  71.703 +     * the element in the array immediately following the end of the
  71.704 +     * Vector is set to null.  (This is useful in determining the length
  71.705 +     * of the Vector <em>only</em> if the caller knows that the Vector
  71.706 +     * does not contain any null elements.)
  71.707 +     *
  71.708 +     * @param a the array into which the elements of the Vector are to
  71.709 +     *          be stored, if it is big enough; otherwise, a new array of the
  71.710 +     *          same runtime type is allocated for this purpose.
  71.711 +     * @return an array containing the elements of the Vector
  71.712 +     * @throws ArrayStoreException if the runtime type of a is not a supertype
  71.713 +     * of the runtime type of every element in this Vector
  71.714 +     * @throws NullPointerException if the given array is null
  71.715 +     * @since 1.2
  71.716 +     */
  71.717 +    @SuppressWarnings("unchecked")
  71.718 +    public synchronized <T> T[] toArray(T[] a) {
  71.719 +        if (a.length < elementCount)
  71.720 +            return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());
  71.721 +
  71.722 +        System.arraycopy(elementData, 0, a, 0, elementCount);
  71.723 +
  71.724 +        if (a.length > elementCount)
  71.725 +            a[elementCount] = null;
  71.726 +
  71.727 +        return a;
  71.728 +    }
  71.729 +
  71.730 +    // Positional Access Operations
  71.731 +
  71.732 +    @SuppressWarnings("unchecked")
  71.733 +    E elementData(int index) {
  71.734 +        return (E) elementData[index];
  71.735 +    }
  71.736 +
  71.737 +    /**
  71.738 +     * Returns the element at the specified position in this Vector.
  71.739 +     *
  71.740 +     * @param index index of the element to return
  71.741 +     * @return object at the specified index
  71.742 +     * @throws ArrayIndexOutOfBoundsException if the index is out of range
  71.743 +     *            ({@code index < 0 || index >= size()})
  71.744 +     * @since 1.2
  71.745 +     */
  71.746 +    public synchronized E get(int index) {
  71.747 +        if (index >= elementCount)
  71.748 +            throw new ArrayIndexOutOfBoundsException(index);
  71.749 +
  71.750 +        return elementData(index);
  71.751 +    }
  71.752 +
  71.753 +    /**
  71.754 +     * Replaces the element at the specified position in this Vector with the
  71.755 +     * specified element.
  71.756 +     *
  71.757 +     * @param index index of the element to replace
  71.758 +     * @param element element to be stored at the specified position
  71.759 +     * @return the element previously at the specified position
  71.760 +     * @throws ArrayIndexOutOfBoundsException if the index is out of range
  71.761 +     *         ({@code index < 0 || index >= size()})
  71.762 +     * @since 1.2
  71.763 +     */
  71.764 +    public synchronized E set(int index, E element) {
  71.765 +        if (index >= elementCount)
  71.766 +            throw new ArrayIndexOutOfBoundsException(index);
  71.767 +
  71.768 +        E oldValue = elementData(index);
  71.769 +        elementData[index] = element;
  71.770 +        return oldValue;
  71.771 +    }
  71.772 +
  71.773 +    /**
  71.774 +     * Appends the specified element to the end of this Vector.
  71.775 +     *
  71.776 +     * @param e element to be appended to this Vector
  71.777 +     * @return {@code true} (as specified by {@link Collection#add})
  71.778 +     * @since 1.2
  71.779 +     */
  71.780 +    public synchronized boolean add(E e) {
  71.781 +        modCount++;
  71.782 +        ensureCapacityHelper(elementCount + 1);
  71.783 +        elementData[elementCount++] = e;
  71.784 +        return true;
  71.785 +    }
  71.786 +
  71.787 +    /**
  71.788 +     * Removes the first occurrence of the specified element in this Vector
  71.789 +     * If the Vector does not contain the element, it is unchanged.  More
  71.790 +     * formally, removes the element with the lowest index i such that
  71.791 +     * {@code (o==null ? get(i)==null : o.equals(get(i)))} (if such
  71.792 +     * an element exists).
  71.793 +     *
  71.794 +     * @param o element to be removed from this Vector, if present
  71.795 +     * @return true if the Vector contained the specified element
  71.796 +     * @since 1.2
  71.797 +     */
  71.798 +    public boolean remove(Object o) {
  71.799 +        return removeElement(o);
  71.800 +    }
  71.801 +
  71.802 +    /**
  71.803 +     * Inserts the specified element at the specified position in this Vector.
  71.804 +     * Shifts the element currently at that position (if any) and any
  71.805 +     * subsequent elements to the right (adds one to their indices).
  71.806 +     *
  71.807 +     * @param index index at which the specified element is to be inserted
  71.808 +     * @param element element to be inserted
  71.809 +     * @throws ArrayIndexOutOfBoundsException if the index is out of range
  71.810 +     *         ({@code index < 0 || index > size()})
  71.811 +     * @since 1.2
  71.812 +     */
  71.813 +    public void add(int index, E element) {
  71.814 +        insertElementAt(element, index);
  71.815 +    }
  71.816 +
  71.817 +    /**
  71.818 +     * Removes the element at the specified position in this Vector.
  71.819 +     * Shifts any subsequent elements to the left (subtracts one from their
  71.820 +     * indices).  Returns the element that was removed from the Vector.
  71.821 +     *
  71.822 +     * @throws ArrayIndexOutOfBoundsException if the index is out of range
  71.823 +     *         ({@code index < 0 || index >= size()})
  71.824 +     * @param index the index of the element to be removed
  71.825 +     * @return element that was removed
  71.826 +     * @since 1.2
  71.827 +     */
  71.828 +    public synchronized E remove(int index) {
  71.829 +        modCount++;
  71.830 +        if (index >= elementCount)
  71.831 +            throw new ArrayIndexOutOfBoundsException(index);
  71.832 +        E oldValue = elementData(index);
  71.833 +
  71.834 +        int numMoved = elementCount - index - 1;
  71.835 +        if (numMoved > 0)
  71.836 +            System.arraycopy(elementData, index+1, elementData, index,
  71.837 +                             numMoved);
  71.838 +        elementData[--elementCount] = null; // Let gc do its work
  71.839 +
  71.840 +        return oldValue;
  71.841 +    }
  71.842 +
  71.843 +    /**
  71.844 +     * Removes all of the elements from this Vector.  The Vector will
  71.845 +     * be empty after this call returns (unless it throws an exception).
  71.846 +     *
  71.847 +     * @since 1.2
  71.848 +     */
  71.849 +    public void clear() {
  71.850 +        removeAllElements();
  71.851 +    }
  71.852 +
  71.853 +    // Bulk Operations
  71.854 +
  71.855 +    /**
  71.856 +     * Returns true if this Vector contains all of the elements in the
  71.857 +     * specified Collection.
  71.858 +     *
  71.859 +     * @param   c a collection whose elements will be tested for containment
  71.860 +     *          in this Vector
  71.861 +     * @return true if this Vector contains all of the elements in the
  71.862 +     *         specified collection
  71.863 +     * @throws NullPointerException if the specified collection is null
  71.864 +     */
  71.865 +    public synchronized boolean containsAll(Collection<?> c) {
  71.866 +        return super.containsAll(c);
  71.867 +    }
  71.868 +
  71.869 +    /**
  71.870 +     * Appends all of the elements in the specified Collection to the end of
  71.871 +     * this Vector, in the order that they are returned by the specified
  71.872 +     * Collection's Iterator.  The behavior of this operation is undefined if
  71.873 +     * the specified Collection is modified while the operation is in progress.
  71.874 +     * (This implies that the behavior of this call is undefined if the
  71.875 +     * specified Collection is this Vector, and this Vector is nonempty.)
  71.876 +     *
  71.877 +     * @param c elements to be inserted into this Vector
  71.878 +     * @return {@code true} if this Vector changed as a result of the call
  71.879 +     * @throws NullPointerException if the specified collection is null
  71.880 +     * @since 1.2
  71.881 +     */
  71.882 +    public synchronized boolean addAll(Collection<? extends E> c) {
  71.883 +        modCount++;
  71.884 +        Object[] a = c.toArray();
  71.885 +        int numNew = a.length;
  71.886 +        ensureCapacityHelper(elementCount + numNew);
  71.887 +        System.arraycopy(a, 0, elementData, elementCount, numNew);
  71.888 +        elementCount += numNew;
  71.889 +        return numNew != 0;
  71.890 +    }
  71.891 +
  71.892 +    /**
  71.893 +     * Removes from this Vector all of its elements that are contained in the
  71.894 +     * specified Collection.
  71.895 +     *
  71.896 +     * @param c a collection of elements to be removed from the Vector
  71.897 +     * @return true if this Vector changed as a result of the call
  71.898 +     * @throws ClassCastException if the types of one or more elements
  71.899 +     *         in this vector are incompatible with the specified
  71.900 +     *         collection
  71.901 +     * (<a href="Collection.html#optional-restrictions">optional</a>)
  71.902 +     * @throws NullPointerException if this vector contains one or more null
  71.903 +     *         elements and the specified collection does not support null
  71.904 +     *         elements
  71.905 +     * (<a href="Collection.html#optional-restrictions">optional</a>),
  71.906 +     *         or if the specified collection is null
  71.907 +     * @since 1.2
  71.908 +     */
  71.909 +    public synchronized boolean removeAll(Collection<?> c) {
  71.910 +        return super.removeAll(c);
  71.911 +    }
  71.912 +
  71.913 +    /**
  71.914 +     * Retains only the elements in this Vector that are contained in the
  71.915 +     * specified Collection.  In other words, removes from this Vector all
  71.916 +     * of its elements that are not contained in the specified Collection.
  71.917 +     *
  71.918 +     * @param c a collection of elements to be retained in this Vector
  71.919 +     *          (all other elements are removed)
  71.920 +     * @return true if this Vector changed as a result of the call
  71.921 +     * @throws ClassCastException if the types of one or more elements
  71.922 +     *         in this vector are incompatible with the specified
  71.923 +     *         collection
  71.924 +     * (<a href="Collection.html#optional-restrictions">optional</a>)
  71.925 +     * @throws NullPointerException if this vector contains one or more null
  71.926 +     *         elements and the specified collection does not support null
  71.927 +     *         elements
  71.928 +     *         (<a href="Collection.html#optional-restrictions">optional</a>),
  71.929 +     *         or if the specified collection is null
  71.930 +     * @since 1.2
  71.931 +     */
  71.932 +    public synchronized boolean retainAll(Collection<?> c) {
  71.933 +        return super.retainAll(c);
  71.934 +    }
  71.935 +
  71.936 +    /**
  71.937 +     * Inserts all of the elements in the specified Collection into this
  71.938 +     * Vector at the specified position.  Shifts the element currently at
  71.939 +     * that position (if any) and any subsequent elements to the right
  71.940 +     * (increases their indices).  The new elements will appear in the Vector
  71.941 +     * in the order that they are returned by the specified Collection's
  71.942 +     * iterator.
  71.943 +     *
  71.944 +     * @param index index at which to insert the first element from the
  71.945 +     *              specified collection
  71.946 +     * @param c elements to be inserted into this Vector
  71.947 +     * @return {@code true} if this Vector changed as a result of the call
  71.948 +     * @throws ArrayIndexOutOfBoundsException if the index is out of range
  71.949 +     *         ({@code index < 0 || index > size()})
  71.950 +     * @throws NullPointerException if the specified collection is null
  71.951 +     * @since 1.2
  71.952 +     */
  71.953 +    public synchronized boolean addAll(int index, Collection<? extends E> c) {
  71.954 +        modCount++;
  71.955 +        if (index < 0 || index > elementCount)
  71.956 +            throw new ArrayIndexOutOfBoundsException(index);
  71.957 +
  71.958 +        Object[] a = c.toArray();
  71.959 +        int numNew = a.length;
  71.960 +        ensureCapacityHelper(elementCount + numNew);
  71.961 +
  71.962 +        int numMoved = elementCount - index;
  71.963 +        if (numMoved > 0)
  71.964 +            System.arraycopy(elementData, index, elementData, index + numNew,
  71.965 +                             numMoved);
  71.966 +
  71.967 +        System.arraycopy(a, 0, elementData, index, numNew);
  71.968 +        elementCount += numNew;
  71.969 +        return numNew != 0;
  71.970 +    }
  71.971 +
  71.972 +    /**
  71.973 +     * Compares the specified Object with this Vector for equality.  Returns
  71.974 +     * true if and only if the specified Object is also a List, both Lists
  71.975 +     * have the same size, and all corresponding pairs of elements in the two
  71.976 +     * Lists are <em>equal</em>.  (Two elements {@code e1} and
  71.977 +     * {@code e2} are <em>equal</em> if {@code (e1==null ? e2==null :
  71.978 +     * e1.equals(e2))}.)  In other words, two Lists are defined to be
  71.979 +     * equal if they contain the same elements in the same order.
  71.980 +     *
  71.981 +     * @param o the Object to be compared for equality with this Vector
  71.982 +     * @return true if the specified Object is equal to this Vector
  71.983 +     */
  71.984 +    public synchronized boolean equals(Object o) {
  71.985 +        return super.equals(o);
  71.986 +    }
  71.987 +
  71.988 +    /**
  71.989 +     * Returns the hash code value for this Vector.
  71.990 +     */
  71.991 +    public synchronized int hashCode() {
  71.992 +        return super.hashCode();
  71.993 +    }
  71.994 +
  71.995 +    /**
  71.996 +     * Returns a string representation of this Vector, containing
  71.997 +     * the String representation of each element.
  71.998 +     */
  71.999 +    public synchronized String toString() {
 71.1000 +        return super.toString();
 71.1001 +    }
 71.1002 +
 71.1003 +    /**
 71.1004 +     * Returns a view of the portion of this List between fromIndex,
 71.1005 +     * inclusive, and toIndex, exclusive.  (If fromIndex and toIndex are
 71.1006 +     * equal, the returned List is empty.)  The returned List is backed by this
 71.1007 +     * List, so changes in the returned List are reflected in this List, and
 71.1008 +     * vice-versa.  The returned List supports all of the optional List
 71.1009 +     * operations supported by this List.
 71.1010 +     *
 71.1011 +     * <p>This method eliminates the need for explicit range operations (of
 71.1012 +     * the sort that commonly exist for arrays).  Any operation that expects
 71.1013 +     * a List can be used as a range operation by operating on a subList view
 71.1014 +     * instead of a whole List.  For example, the following idiom
 71.1015 +     * removes a range of elements from a List:
 71.1016 +     * <pre>
 71.1017 +     *      list.subList(from, to).clear();
 71.1018 +     * </pre>
 71.1019 +     * Similar idioms may be constructed for indexOf and lastIndexOf,
 71.1020 +     * and all of the algorithms in the Collections class can be applied to
 71.1021 +     * a subList.
 71.1022 +     *
 71.1023 +     * <p>The semantics of the List returned by this method become undefined if
 71.1024 +     * the backing list (i.e., this List) is <i>structurally modified</i> in
 71.1025 +     * any way other than via the returned List.  (Structural modifications are
 71.1026 +     * those that change the size of the List, or otherwise perturb it in such
 71.1027 +     * a fashion that iterations in progress may yield incorrect results.)
 71.1028 +     *
 71.1029 +     * @param fromIndex low endpoint (inclusive) of the subList
 71.1030 +     * @param toIndex high endpoint (exclusive) of the subList
 71.1031 +     * @return a view of the specified range within this List
 71.1032 +     * @throws IndexOutOfBoundsException if an endpoint index value is out of range
 71.1033 +     *         {@code (fromIndex < 0 || toIndex > size)}
 71.1034 +     * @throws IllegalArgumentException if the endpoint indices are out of order
 71.1035 +     *         {@code (fromIndex > toIndex)}
 71.1036 +     */
 71.1037 +    public synchronized List<E> subList(int fromIndex, int toIndex) {
 71.1038 +        return Collections.synchronizedList(super.subList(fromIndex, toIndex),
 71.1039 +                                            this);
 71.1040 +    }
 71.1041 +
 71.1042 +    /**
 71.1043 +     * Removes from this list all of the elements whose index is between
 71.1044 +     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
 71.1045 +     * Shifts any succeeding elements to the left (reduces their index).
 71.1046 +     * This call shortens the list by {@code (toIndex - fromIndex)} elements.
 71.1047 +     * (If {@code toIndex==fromIndex}, this operation has no effect.)
 71.1048 +     */
 71.1049 +    protected synchronized void removeRange(int fromIndex, int toIndex) {
 71.1050 +        modCount++;
 71.1051 +        int numMoved = elementCount - toIndex;
 71.1052 +        System.arraycopy(elementData, toIndex, elementData, fromIndex,
 71.1053 +                         numMoved);
 71.1054 +
 71.1055 +        // Let gc do its work
 71.1056 +        int newElementCount = elementCount - (toIndex-fromIndex);
 71.1057 +        while (elementCount != newElementCount)
 71.1058 +            elementData[--elementCount] = null;
 71.1059 +    }
 71.1060 +
 71.1061 +    /**
 71.1062 +     * Returns a list iterator over the elements in this list (in proper
 71.1063 +     * sequence), starting at the specified position in the list.
 71.1064 +     * The specified index indicates the first element that would be
 71.1065 +     * returned by an initial call to {@link ListIterator#next next}.
 71.1066 +     * An initial call to {@link ListIterator#previous previous} would
 71.1067 +     * return the element with the specified index minus one.
 71.1068 +     *
 71.1069 +     * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
 71.1070 +     *
 71.1071 +     * @throws IndexOutOfBoundsException {@inheritDoc}
 71.1072 +     */
 71.1073 +    public synchronized ListIterator<E> listIterator(int index) {
 71.1074 +        if (index < 0 || index > elementCount)
 71.1075 +            throw new IndexOutOfBoundsException("Index: "+index);
 71.1076 +        return new ListItr(index);
 71.1077 +    }
 71.1078 +
 71.1079 +    /**
 71.1080 +     * Returns a list iterator over the elements in this list (in proper
 71.1081 +     * sequence).
 71.1082 +     *
 71.1083 +     * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
 71.1084 +     *
 71.1085 +     * @see #listIterator(int)
 71.1086 +     */
 71.1087 +    public synchronized ListIterator<E> listIterator() {
 71.1088 +        return new ListItr(0);
 71.1089 +    }
 71.1090 +
 71.1091 +    /**
 71.1092 +     * Returns an iterator over the elements in this list in proper sequence.
 71.1093 +     *
 71.1094 +     * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
 71.1095 +     *
 71.1096 +     * @return an iterator over the elements in this list in proper sequence
 71.1097 +     */
 71.1098 +    public synchronized Iterator<E> iterator() {
 71.1099 +        return new Itr();
 71.1100 +    }
 71.1101 +
 71.1102 +    /**
 71.1103 +     * An optimized version of AbstractList.Itr
 71.1104 +     */
 71.1105 +    private class Itr implements Iterator<E> {
 71.1106 +        int cursor;       // index of next element to return
 71.1107 +        int lastRet = -1; // index of last element returned; -1 if no such
 71.1108 +        int expectedModCount = modCount;
 71.1109 +
 71.1110 +        public boolean hasNext() {
 71.1111 +            // Racy but within spec, since modifications are checked
 71.1112 +            // within or after synchronization in next/previous
 71.1113 +            return cursor != elementCount;
 71.1114 +        }
 71.1115 +
 71.1116 +        public E next() {
 71.1117 +            synchronized (Vector.this) {
 71.1118 +                checkForComodification();
 71.1119 +                int i = cursor;
 71.1120 +                if (i >= elementCount)
 71.1121 +                    throw new NoSuchElementException();
 71.1122 +                cursor = i + 1;
 71.1123 +                return elementData(lastRet = i);
 71.1124 +            }
 71.1125 +        }
 71.1126 +
 71.1127 +        public void remove() {
 71.1128 +            if (lastRet == -1)
 71.1129 +                throw new IllegalStateException();
 71.1130 +            synchronized (Vector.this) {
 71.1131 +                checkForComodification();
 71.1132 +                Vector.this.remove(lastRet);
 71.1133 +                expectedModCount = modCount;
 71.1134 +            }
 71.1135 +            cursor = lastRet;
 71.1136 +            lastRet = -1;
 71.1137 +        }
 71.1138 +
 71.1139 +        final void checkForComodification() {
 71.1140 +            if (modCount != expectedModCount)
 71.1141 +                throw new ConcurrentModificationException();
 71.1142 +        }
 71.1143 +    }
 71.1144 +
 71.1145 +    /**
 71.1146 +     * An optimized version of AbstractList.ListItr
 71.1147 +     */
 71.1148 +    final class ListItr extends Itr implements ListIterator<E> {
 71.1149 +        ListItr(int index) {
 71.1150 +            super();
 71.1151 +            cursor = index;
 71.1152 +        }
 71.1153 +
 71.1154 +        public boolean hasPrevious() {
 71.1155 +            return cursor != 0;
 71.1156 +        }
 71.1157 +
 71.1158 +        public int nextIndex() {
 71.1159 +            return cursor;
 71.1160 +        }
 71.1161 +
 71.1162 +        public int previousIndex() {
 71.1163 +            return cursor - 1;
 71.1164 +        }
 71.1165 +
 71.1166 +        public E previous() {
 71.1167 +            synchronized (Vector.this) {
 71.1168 +                checkForComodification();
 71.1169 +                int i = cursor - 1;
 71.1170 +                if (i < 0)
 71.1171 +                    throw new NoSuchElementException();
 71.1172 +                cursor = i;
 71.1173 +                return elementData(lastRet = i);
 71.1174 +            }
 71.1175 +        }
 71.1176 +
 71.1177 +        public void set(E e) {
 71.1178 +            if (lastRet == -1)
 71.1179 +                throw new IllegalStateException();
 71.1180 +            synchronized (Vector.this) {
 71.1181 +                checkForComodification();
 71.1182 +                Vector.this.set(lastRet, e);
 71.1183 +            }
 71.1184 +        }
 71.1185 +
 71.1186 +        public void add(E e) {
 71.1187 +            int i = cursor;
 71.1188 +            synchronized (Vector.this) {
 71.1189 +                checkForComodification();
 71.1190 +                Vector.this.add(i, e);
 71.1191 +                expectedModCount = modCount;
 71.1192 +            }
 71.1193 +            cursor = i + 1;
 71.1194 +            lastRet = -1;
 71.1195 +        }
 71.1196 +    }
 71.1197 +}
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/emul/compact/src/main/java/java/util/concurrent/Callable.java	Tue Feb 05 17:04:22 2013 +0100
    72.3 @@ -0,0 +1,65 @@
    72.4 +/*
    72.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    72.6 + *
    72.7 + * This code is free software; you can redistribute it and/or modify it
    72.8 + * under the terms of the GNU General Public License version 2 only, as
    72.9 + * published by the Free Software Foundation.  Oracle designates this
   72.10 + * particular file as subject to the "Classpath" exception as provided
   72.11 + * by Oracle in the LICENSE file that accompanied this code.
   72.12 + *
   72.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
   72.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   72.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   72.16 + * version 2 for more details (a copy is included in the LICENSE file that
   72.17 + * accompanied this code).
   72.18 + *
   72.19 + * You should have received a copy of the GNU General Public License version
   72.20 + * 2 along with this work; if not, write to the Free Software Foundation,
   72.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   72.22 + *
   72.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   72.24 + * or visit www.oracle.com if you need additional information or have any
   72.25 + * questions.
   72.26 + */
   72.27 +
   72.28 +/*
   72.29 + * This file is available under and governed by the GNU General Public
   72.30 + * License version 2 only, as published by the Free Software Foundation.
   72.31 + * However, the following notice accompanied the original version of this
   72.32 + * file:
   72.33 + *
   72.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
   72.35 + * Expert Group and released to the public domain, as explained at
   72.36 + * http://creativecommons.org/publicdomain/zero/1.0/
   72.37 + */
   72.38 +
   72.39 +package java.util.concurrent;
   72.40 +
   72.41 +/**
   72.42 + * A task that returns a result and may throw an exception.
   72.43 + * Implementors define a single method with no arguments called
   72.44 + * <tt>call</tt>.
   72.45 + *
   72.46 + * <p>The <tt>Callable</tt> interface is similar to {@link
   72.47 + * java.lang.Runnable}, in that both are designed for classes whose
   72.48 + * instances are potentially executed by another thread.  A
   72.49 + * <tt>Runnable</tt>, however, does not return a result and cannot
   72.50 + * throw a checked exception.
   72.51 + *
   72.52 + * <p> The {@link Executors} class contains utility methods to
   72.53 + * convert from other common forms to <tt>Callable</tt> classes.
   72.54 + *
   72.55 + * @see Executor
   72.56 + * @since 1.5
   72.57 + * @author Doug Lea
   72.58 + * @param <V> the result type of method <tt>call</tt>
   72.59 + */
   72.60 +public interface Callable<V> {
   72.61 +    /**
   72.62 +     * Computes a result, or throws an exception if unable to do so.
   72.63 +     *
   72.64 +     * @return computed result
   72.65 +     * @throws Exception if unable to compute a result
   72.66 +     */
   72.67 +    V call() throws Exception;
   72.68 +}
    73.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.2 +++ b/emul/compact/src/main/java/java/util/concurrent/TimeUnit.java	Tue Feb 05 17:04:22 2013 +0100
    73.3 @@ -0,0 +1,367 @@
    73.4 +/*
    73.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    73.6 + *
    73.7 + * This code is free software; you can redistribute it and/or modify it
    73.8 + * under the terms of the GNU General Public License version 2 only, as
    73.9 + * published by the Free Software Foundation.  Oracle designates this
   73.10 + * particular file as subject to the "Classpath" exception as provided
   73.11 + * by Oracle in the LICENSE file that accompanied this code.
   73.12 + *
   73.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
   73.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   73.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   73.16 + * version 2 for more details (a copy is included in the LICENSE file that
   73.17 + * accompanied this code).
   73.18 + *
   73.19 + * You should have received a copy of the GNU General Public License version
   73.20 + * 2 along with this work; if not, write to the Free Software Foundation,
   73.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   73.22 + *
   73.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   73.24 + * or visit www.oracle.com if you need additional information or have any
   73.25 + * questions.
   73.26 + */
   73.27 +
   73.28 +/*
   73.29 + * This file is available under and governed by the GNU General Public
   73.30 + * License version 2 only, as published by the Free Software Foundation.
   73.31 + * However, the following notice accompanied the original version of this
   73.32 + * file:
   73.33 + *
   73.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
   73.35 + * Expert Group and released to the public domain, as explained at
   73.36 + * http://creativecommons.org/publicdomain/zero/1.0/
   73.37 + */
   73.38 +
   73.39 +package java.util.concurrent;
   73.40 +
   73.41 +/**
   73.42 + * A <tt>TimeUnit</tt> represents time durations at a given unit of
   73.43 + * granularity and provides utility methods to convert across units,
   73.44 + * and to perform timing and delay operations in these units.  A
   73.45 + * <tt>TimeUnit</tt> does not maintain time information, but only
   73.46 + * helps organize and use time representations that may be maintained
   73.47 + * separately across various contexts.  A nanosecond is defined as one
   73.48 + * thousandth of a microsecond, a microsecond as one thousandth of a
   73.49 + * millisecond, a millisecond as one thousandth of a second, a minute
   73.50 + * as sixty seconds, an hour as sixty minutes, and a day as twenty four
   73.51 + * hours.
   73.52 + *
   73.53 + * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods
   73.54 + * how a given timing parameter should be interpreted. For example,
   73.55 + * the following code will timeout in 50 milliseconds if the {@link
   73.56 + * java.util.concurrent.locks.Lock lock} is not available:
   73.57 + *
   73.58 + * <pre>  Lock lock = ...;
   73.59 + *  if (lock.tryLock(50L, TimeUnit.MILLISECONDS)) ...
   73.60 + * </pre>
   73.61 + * while this code will timeout in 50 seconds:
   73.62 + * <pre>
   73.63 + *  Lock lock = ...;
   73.64 + *  if (lock.tryLock(50L, TimeUnit.SECONDS)) ...
   73.65 + * </pre>
   73.66 + *
   73.67 + * Note however, that there is no guarantee that a particular timeout
   73.68 + * implementation will be able to notice the passage of time at the
   73.69 + * same granularity as the given <tt>TimeUnit</tt>.
   73.70 + *
   73.71 + * @since 1.5
   73.72 + * @author Doug Lea
   73.73 + */
   73.74 +public enum TimeUnit {
   73.75 +    NANOSECONDS {
   73.76 +        public long toNanos(long d)   { return d; }
   73.77 +        public long toMicros(long d)  { return d/(C1/C0); }
   73.78 +        public long toMillis(long d)  { return d/(C2/C0); }
   73.79 +        public long toSeconds(long d) { return d/(C3/C0); }
   73.80 +        public long toMinutes(long d) { return d/(C4/C0); }
   73.81 +        public long toHours(long d)   { return d/(C5/C0); }
   73.82 +        public long toDays(long d)    { return d/(C6/C0); }
   73.83 +        public long convert(long d, TimeUnit u) { return u.toNanos(d); }
   73.84 +        int excessNanos(long d, long m) { return (int)(d - (m*C2)); }
   73.85 +    },
   73.86 +    MICROSECONDS {
   73.87 +        public long toNanos(long d)   { return x(d, C1/C0, MAX/(C1/C0)); }
   73.88 +        public long toMicros(long d)  { return d; }
   73.89 +        public long toMillis(long d)  { return d/(C2/C1); }
   73.90 +        public long toSeconds(long d) { return d/(C3/C1); }
   73.91 +        public long toMinutes(long d) { return d/(C4/C1); }
   73.92 +        public long toHours(long d)   { return d/(C5/C1); }
   73.93 +        public long toDays(long d)    { return d/(C6/C1); }
   73.94 +        public long convert(long d, TimeUnit u) { return u.toMicros(d); }
   73.95 +        int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }
   73.96 +    },
   73.97 +    MILLISECONDS {
   73.98 +        public long toNanos(long d)   { return x(d, C2/C0, MAX/(C2/C0)); }
   73.99 +        public long toMicros(long d)  { return x(d, C2/C1, MAX/(C2/C1)); }
  73.100 +        public long toMillis(long d)  { return d; }
  73.101 +        public long toSeconds(long d) { return d/(C3/C2); }
  73.102 +        public long toMinutes(long d) { return d/(C4/C2); }
  73.103 +        public long toHours(long d)   { return d/(C5/C2); }
  73.104 +        public long toDays(long d)    { return d/(C6/C2); }
  73.105 +        public long convert(long d, TimeUnit u) { return u.toMillis(d); }
  73.106 +        int excessNanos(long d, long m) { return 0; }
  73.107 +    },
  73.108 +    SECONDS {
  73.109 +        public long toNanos(long d)   { return x(d, C3/C0, MAX/(C3/C0)); }
  73.110 +        public long toMicros(long d)  { return x(d, C3/C1, MAX/(C3/C1)); }
  73.111 +        public long toMillis(long d)  { return x(d, C3/C2, MAX/(C3/C2)); }
  73.112 +        public long toSeconds(long d) { return d; }
  73.113 +        public long toMinutes(long d) { return d/(C4/C3); }
  73.114 +        public long toHours(long d)   { return d/(C5/C3); }
  73.115 +        public long toDays(long d)    { return d/(C6/C3); }
  73.116 +        public long convert(long d, TimeUnit u) { return u.toSeconds(d); }
  73.117 +        int excessNanos(long d, long m) { return 0; }
  73.118 +    },
  73.119 +    MINUTES {
  73.120 +        public long toNanos(long d)   { return x(d, C4/C0, MAX/(C4/C0)); }
  73.121 +        public long toMicros(long d)  { return x(d, C4/C1, MAX/(C4/C1)); }
  73.122 +        public long toMillis(long d)  { return x(d, C4/C2, MAX/(C4/C2)); }
  73.123 +        public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }
  73.124 +        public long toMinutes(long d) { return d; }
  73.125 +        public long toHours(long d)   { return d/(C5/C4); }
  73.126 +        public long toDays(long d)    { return d/(C6/C4); }
  73.127 +        public long convert(long d, TimeUnit u) { return u.toMinutes(d); }
  73.128 +        int excessNanos(long d, long m) { return 0; }
  73.129 +    },
  73.130 +    HOURS {
  73.131 +        public long toNanos(long d)   { return x(d, C5/C0, MAX/(C5/C0)); }
  73.132 +        public long toMicros(long d)  { return x(d, C5/C1, MAX/(C5/C1)); }
  73.133 +        public long toMillis(long d)  { return x(d, C5/C2, MAX/(C5/C2)); }
  73.134 +        public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }
  73.135 +        public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }
  73.136 +        public long toHours(long d)   { return d; }
  73.137 +        public long toDays(long d)    { return d/(C6/C5); }
  73.138 +        public long convert(long d, TimeUnit u) { return u.toHours(d); }
  73.139 +        int excessNanos(long d, long m) { return 0; }
  73.140 +    },
  73.141 +    DAYS {
  73.142 +        public long toNanos(long d)   { return x(d, C6/C0, MAX/(C6/C0)); }
  73.143 +        public long toMicros(long d)  { return x(d, C6/C1, MAX/(C6/C1)); }
  73.144 +        public long toMillis(long d)  { return x(d, C6/C2, MAX/(C6/C2)); }
  73.145 +        public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }
  73.146 +        public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }
  73.147 +        public long toHours(long d)   { return x(d, C6/C5, MAX/(C6/C5)); }
  73.148 +        public long toDays(long d)    { return d; }
  73.149 +        public long convert(long d, TimeUnit u) { return u.toDays(d); }
  73.150 +        int excessNanos(long d, long m) { return 0; }
  73.151 +    };
  73.152 +
  73.153 +    // Handy constants for conversion methods
  73.154 +    static final long C0 = 1L;
  73.155 +    static final long C1 = C0 * 1000L;
  73.156 +    static final long C2 = C1 * 1000L;
  73.157 +    static final long C3 = C2 * 1000L;
  73.158 +    static final long C4 = C3 * 60L;
  73.159 +    static final long C5 = C4 * 60L;
  73.160 +    static final long C6 = C5 * 24L;
  73.161 +
  73.162 +    static final long MAX = Long.MAX_VALUE;
  73.163 +
  73.164 +    /**
  73.165 +     * Scale d by m, checking for overflow.
  73.166 +     * This has a short name to make above code more readable.
  73.167 +     */
  73.168 +    static long x(long d, long m, long over) {
  73.169 +        if (d >  over) return Long.MAX_VALUE;
  73.170 +        if (d < -over) return Long.MIN_VALUE;
  73.171 +        return d * m;
  73.172 +    }
  73.173 +
  73.174 +    // To maintain full signature compatibility with 1.5, and to improve the
  73.175 +    // clarity of the generated javadoc (see 6287639: Abstract methods in
  73.176 +    // enum classes should not be listed as abstract), method convert
  73.177 +    // etc. are not declared abstract but otherwise act as abstract methods.
  73.178 +
  73.179 +    /**
  73.180 +     * Convert the given time duration in the given unit to this
  73.181 +     * unit.  Conversions from finer to coarser granularities
  73.182 +     * truncate, so lose precision. For example converting
  73.183 +     * <tt>999</tt> milliseconds to seconds results in
  73.184 +     * <tt>0</tt>. Conversions from coarser to finer granularities
  73.185 +     * with arguments that would numerically overflow saturate to
  73.186 +     * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt>
  73.187 +     * if positive.
  73.188 +     *
  73.189 +     * <p>For example, to convert 10 minutes to milliseconds, use:
  73.190 +     * <tt>TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)</tt>
  73.191 +     *
  73.192 +     * @param sourceDuration the time duration in the given <tt>sourceUnit</tt>
  73.193 +     * @param sourceUnit the unit of the <tt>sourceDuration</tt> argument
  73.194 +     * @return the converted duration in this unit,
  73.195 +     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
  73.196 +     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
  73.197 +     */
  73.198 +    public long convert(long sourceDuration, TimeUnit sourceUnit) {
  73.199 +        throw new AbstractMethodError();
  73.200 +    }
  73.201 +
  73.202 +    /**
  73.203 +     * Equivalent to <tt>NANOSECONDS.convert(duration, this)</tt>.
  73.204 +     * @param duration the duration
  73.205 +     * @return the converted duration,
  73.206 +     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
  73.207 +     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
  73.208 +     * @see #convert
  73.209 +     */
  73.210 +    public long toNanos(long duration) {
  73.211 +        throw new AbstractMethodError();
  73.212 +    }
  73.213 +
  73.214 +    /**
  73.215 +     * Equivalent to <tt>MICROSECONDS.convert(duration, this)</tt>.
  73.216 +     * @param duration the duration
  73.217 +     * @return the converted duration,
  73.218 +     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
  73.219 +     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
  73.220 +     * @see #convert
  73.221 +     */
  73.222 +    public long toMicros(long duration) {
  73.223 +        throw new AbstractMethodError();
  73.224 +    }
  73.225 +
  73.226 +    /**
  73.227 +     * Equivalent to <tt>MILLISECONDS.convert(duration, this)</tt>.
  73.228 +     * @param duration the duration
  73.229 +     * @return the converted duration,
  73.230 +     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
  73.231 +     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
  73.232 +     * @see #convert
  73.233 +     */
  73.234 +    public long toMillis(long duration) {
  73.235 +        throw new AbstractMethodError();
  73.236 +    }
  73.237 +
  73.238 +    /**
  73.239 +     * Equivalent to <tt>SECONDS.convert(duration, this)</tt>.
  73.240 +     * @param duration the duration
  73.241 +     * @return the converted duration,
  73.242 +     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
  73.243 +     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
  73.244 +     * @see #convert
  73.245 +     */
  73.246 +    public long toSeconds(long duration) {
  73.247 +        throw new AbstractMethodError();
  73.248 +    }
  73.249 +
  73.250 +    /**
  73.251 +     * Equivalent to <tt>MINUTES.convert(duration, this)</tt>.
  73.252 +     * @param duration the duration
  73.253 +     * @return the converted duration,
  73.254 +     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
  73.255 +     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
  73.256 +     * @see #convert
  73.257 +     * @since 1.6
  73.258 +     */
  73.259 +    public long toMinutes(long duration) {
  73.260 +        throw new AbstractMethodError();
  73.261 +    }
  73.262 +
  73.263 +    /**
  73.264 +     * Equivalent to <tt>HOURS.convert(duration, this)</tt>.
  73.265 +     * @param duration the duration
  73.266 +     * @return the converted duration,
  73.267 +     * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
  73.268 +     * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
  73.269 +     * @see #convert
  73.270 +     * @since 1.6
  73.271 +     */
  73.272 +    public long toHours(long duration) {
  73.273 +        throw new AbstractMethodError();
  73.274 +    }
  73.275 +
  73.276 +    /**
  73.277 +     * Equivalent to <tt>DAYS.convert(duration, this)</tt>.
  73.278 +     * @param duration the duration
  73.279 +     * @return the converted duration
  73.280 +     * @see #convert
  73.281 +     * @since 1.6
  73.282 +     */
  73.283 +    public long toDays(long duration) {
  73.284 +        throw new AbstractMethodError();
  73.285 +    }
  73.286 +
  73.287 +    /**
  73.288 +     * Utility to compute the excess-nanosecond argument to wait,
  73.289 +     * sleep, join.
  73.290 +     * @param d the duration
  73.291 +     * @param m the number of milliseconds
  73.292 +     * @return the number of nanoseconds
  73.293 +     */
  73.294 +    abstract int excessNanos(long d, long m);
  73.295 +
  73.296 +    /**
  73.297 +     * Performs a timed {@link Object#wait(long, int) Object.wait}
  73.298 +     * using this time unit.
  73.299 +     * This is a convenience method that converts timeout arguments
  73.300 +     * into the form required by the <tt>Object.wait</tt> method.
  73.301 +     *
  73.302 +     * <p>For example, you could implement a blocking <tt>poll</tt>
  73.303 +     * method (see {@link BlockingQueue#poll BlockingQueue.poll})
  73.304 +     * using:
  73.305 +     *
  73.306 +     *  <pre> {@code
  73.307 +     * public synchronized Object poll(long timeout, TimeUnit unit)
  73.308 +     *     throws InterruptedException {
  73.309 +     *   while (empty) {
  73.310 +     *     unit.timedWait(this, timeout);
  73.311 +     *     ...
  73.312 +     *   }
  73.313 +     * }}</pre>
  73.314 +     *
  73.315 +     * @param obj the object to wait on
  73.316 +     * @param timeout the maximum time to wait. If less than
  73.317 +     * or equal to zero, do not wait at all.
  73.318 +     * @throws InterruptedException if interrupted while waiting
  73.319 +     */
  73.320 +    public void timedWait(Object obj, long timeout)
  73.321 +            throws InterruptedException {
  73.322 +        if (timeout > 0) {
  73.323 +            long ms = toMillis(timeout);
  73.324 +            int ns = excessNanos(timeout, ms);
  73.325 +            obj.wait(ms, ns);
  73.326 +        }
  73.327 +    }
  73.328 +
  73.329 +    /**
  73.330 +     * Performs a timed {@link Thread#join(long, int) Thread.join}
  73.331 +     * using this time unit.
  73.332 +     * This is a convenience method that converts time arguments into the
  73.333 +     * form required by the <tt>Thread.join</tt> method.
  73.334 +     *
  73.335 +     * @param thread the thread to wait for
  73.336 +     * @param timeout the maximum time to wait. If less than
  73.337 +     * or equal to zero, do not wait at all.
  73.338 +     * @throws InterruptedException if interrupted while waiting
  73.339 +     */
  73.340 +//    public void timedJoin(Thread thread, long timeout)
  73.341 +//            throws InterruptedException {
  73.342 +//        if (timeout > 0) {
  73.343 +//            long ms = toMillis(timeout);
  73.344 +//            int ns = excessNanos(timeout, ms);
  73.345 +//            thread.join(ms, ns);
  73.346 +//        }
  73.347 +//    }
  73.348 +
  73.349 +    /**
  73.350 +     * Performs a {@link Thread#sleep(long, int) Thread.sleep} using
  73.351 +     * this time unit.
  73.352 +     * This is a convenience method that converts time arguments into the
  73.353 +     * form required by the <tt>Thread.sleep</tt> method.
  73.354 +     *
  73.355 +     * @param timeout the minimum time to sleep. If less than
  73.356 +     * or equal to zero, do not sleep at all.
  73.357 +     * @throws InterruptedException if interrupted while sleeping
  73.358 +     */
  73.359 +    public void sleep(long timeout) throws InterruptedException {
  73.360 +        if (timeout > 0) {
  73.361 +            long ms = toMillis(timeout);
  73.362 +            int ns = excessNanos(timeout, ms);
  73.363 +            Object o = new Object();
  73.364 +            synchronized (o) {
  73.365 +                o.wait(ms, ns);
  73.366 +            }
  73.367 +        }
  73.368 +    }
  73.369 +
  73.370 +}
    74.1 --- a/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/CollectionsTest.java	Tue Feb 05 16:40:01 2013 +0100
    74.2 +++ b/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/CollectionsTest.java	Tue Feb 05 17:04:22 2013 +0100
    74.3 @@ -25,6 +25,8 @@
    74.4  import java.util.HashSet;
    74.5  import java.util.List;
    74.6  import java.util.Map;
    74.7 +import java.util.Map.Entry;
    74.8 +import java.util.Vector;
    74.9  import org.apidesign.bck2brwsr.vmtest.Compare;
   74.10  import org.apidesign.bck2brwsr.vmtest.VMTest;
   74.11  import org.testng.annotations.Factory;
   74.12 @@ -92,10 +94,9 @@
   74.13          map.put("nine", 9);
   74.14          map.put("ten", 10);
   74.15          
   74.16 -        Map.Entry<String,Integer>[] arr = map.entrySet().toArray(new Map.Entry[map.size()]);
   74.17 -        Arrays.sort(arr, new C());
   74.18 -        
   74.19 -        return Arrays.asList(arr).toString();
   74.20 +        List<Entry<String,Integer>> arr = new Vector<>();
   74.21 +        arr.addAll(map.entrySet());
   74.22 +        return arr.toString();
   74.23      }
   74.24      
   74.25      @Factory
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/RandomTest.java	Tue Feb 05 17:04:22 2013 +0100
    75.3 @@ -0,0 +1,40 @@
    75.4 +/**
    75.5 + * Back 2 Browser Bytecode Translator
    75.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    75.7 + *
    75.8 + * This program is free software: you can redistribute it and/or modify
    75.9 + * it under the terms of the GNU General Public License as published by
   75.10 + * the Free Software Foundation, version 2 of the License.
   75.11 + *
   75.12 + * This program is distributed in the hope that it will be useful,
   75.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   75.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   75.15 + * GNU General Public License for more details.
   75.16 + *
   75.17 + * You should have received a copy of the GNU General Public License
   75.18 + * along with this program. Look for COPYING file in the top folder.
   75.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   75.20 + */
   75.21 +package org.apidesign.bck2brwsr.compact.tck;
   75.22 +
   75.23 +import java.util.Random;
   75.24 +import org.apidesign.bck2brwsr.vmtest.Compare;
   75.25 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   75.26 +import org.testng.annotations.Factory;
   75.27 +
   75.28 +/**
   75.29 + *
   75.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   75.31 + */
   75.32 +public class RandomTest {
   75.33 +    @Compare public boolean canInstantiateRandom() {
   75.34 +        Random r = new Random();
   75.35 +        r.nextInt();
   75.36 +        return r != null;
   75.37 +    }
   75.38 +
   75.39 +    
   75.40 +    @Factory public static Object[] create() {
   75.41 +        return VMTest.create(RandomTest.class);
   75.42 +    }
   75.43 +}
    76.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.2 +++ b/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/ReaderTest.java	Tue Feb 05 17:04:22 2013 +0100
    76.3 @@ -0,0 +1,60 @@
    76.4 +/**
    76.5 + * Back 2 Browser Bytecode Translator
    76.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    76.7 + *
    76.8 + * This program is free software: you can redistribute it and/or modify
    76.9 + * it under the terms of the GNU General Public License as published by
   76.10 + * the Free Software Foundation, version 2 of the License.
   76.11 + *
   76.12 + * This program is distributed in the hope that it will be useful,
   76.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   76.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   76.15 + * GNU General Public License for more details.
   76.16 + *
   76.17 + * You should have received a copy of the GNU General Public License
   76.18 + * along with this program. Look for COPYING file in the top folder.
   76.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   76.20 + */
   76.21 +package org.apidesign.bck2brwsr.compact.tck;
   76.22 +
   76.23 +import java.io.ByteArrayInputStream;
   76.24 +import java.io.IOException;
   76.25 +import java.io.InputStreamReader;
   76.26 +import java.util.Arrays;
   76.27 +import org.apidesign.bck2brwsr.vmtest.Compare;
   76.28 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   76.29 +import org.testng.annotations.Factory;
   76.30 +
   76.31 +/**
   76.32 + *
   76.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   76.34 + */
   76.35 +public class ReaderTest {
   76.36 +    @Compare public String readUTFString() throws IOException {
   76.37 +        byte[] arr = { 
   76.38 +            (byte)-59, (byte)-67, (byte)108, (byte)117, (byte)-59, (byte)-91, 
   76.39 +            (byte)111, (byte)117, (byte)-60, (byte)-115, (byte)107, (byte)-61, 
   76.40 +            (byte)-67, (byte)32, (byte)107, (byte)-59, (byte)-81, (byte)-59, 
   76.41 +            (byte)-120 
   76.42 +        };
   76.43 +        ByteArrayInputStream is = new ByteArrayInputStream(arr);
   76.44 +        InputStreamReader r = new InputStreamReader(is);
   76.45 +        
   76.46 +        StringBuilder sb = new StringBuilder();
   76.47 +        for (;;) {
   76.48 +            int ch = r.read();
   76.49 +            if (ch == -1) {
   76.50 +                break;
   76.51 +            }
   76.52 +            sb.append((char)ch);
   76.53 +        }
   76.54 +        return sb.toString().toString();
   76.55 +    }
   76.56 +    @Compare public String stringToBytes() {
   76.57 +        return Arrays.toString("Žluťoučký kůň".getBytes());
   76.58 +    }
   76.59 +    
   76.60 +    @Factory public static Object[] create() {
   76.61 +        return VMTest.create(ReaderTest.class);
   76.62 +    }
   76.63 +}
    77.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.2 +++ b/emul/mini/src/main/java/java/lang/ArrayStoreException.java	Tue Feb 05 17:04:22 2013 +0100
    77.3 @@ -0,0 +1,60 @@
    77.4 +/*
    77.5 + * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
    77.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    77.7 + *
    77.8 + * This code is free software; you can redistribute it and/or modify it
    77.9 + * under the terms of the GNU General Public License version 2 only, as
   77.10 + * published by the Free Software Foundation.  Oracle designates this
   77.11 + * particular file as subject to the "Classpath" exception as provided
   77.12 + * by Oracle in the LICENSE file that accompanied this code.
   77.13 + *
   77.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   77.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   77.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   77.17 + * version 2 for more details (a copy is included in the LICENSE file that
   77.18 + * accompanied this code).
   77.19 + *
   77.20 + * You should have received a copy of the GNU General Public License version
   77.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   77.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   77.23 + *
   77.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   77.25 + * or visit www.oracle.com if you need additional information or have any
   77.26 + * questions.
   77.27 + */
   77.28 +
   77.29 +package java.lang;
   77.30 +
   77.31 +/**
   77.32 + * Thrown to indicate that an attempt has been made to store the
   77.33 + * wrong type of object into an array of objects. For example, the
   77.34 + * following code generates an <code>ArrayStoreException</code>:
   77.35 + * <p><blockquote><pre>
   77.36 + *     Object x[] = new String[3];
   77.37 + *     x[0] = new Integer(0);
   77.38 + * </pre></blockquote>
   77.39 + *
   77.40 + * @author  unascribed
   77.41 + * @since   JDK1.0
   77.42 + */
   77.43 +public
   77.44 +class ArrayStoreException extends RuntimeException {
   77.45 +    private static final long serialVersionUID = -4522193890499838241L;
   77.46 +
   77.47 +    /**
   77.48 +     * Constructs an <code>ArrayStoreException</code> with no detail message.
   77.49 +     */
   77.50 +    public ArrayStoreException() {
   77.51 +        super();
   77.52 +    }
   77.53 +
   77.54 +    /**
   77.55 +     * Constructs an <code>ArrayStoreException</code> with the specified
   77.56 +     * detail message.
   77.57 +     *
   77.58 +     * @param   s   the detail message.
   77.59 +     */
   77.60 +    public ArrayStoreException(String s) {
   77.61 +        super(s);
   77.62 +    }
   77.63 +}
    78.1 --- a/emul/mini/src/main/java/java/lang/Class.java	Tue Feb 05 16:40:01 2013 +0100
    78.2 +++ b/emul/mini/src/main/java/java/lang/Class.java	Tue Feb 05 17:04:22 2013 +0100
    78.3 @@ -347,6 +347,9 @@
    78.4       * @since JDK1.1
    78.5       */
    78.6      public boolean isInstance(Object obj) {
    78.7 +        if (obj == null) {
    78.8 +            return false;
    78.9 +        }
   78.10          if (isArray()) {
   78.11              return isAssignableFrom(obj.getClass());
   78.12          }
   78.13 @@ -909,7 +912,50 @@
   78.14          }
   78.15          return m;
   78.16      }
   78.17 -
   78.18 +    
   78.19 +    /**
   78.20 +     * Returns an array of {@code Method} objects reflecting all the
   78.21 +     * methods declared by the class or interface represented by this
   78.22 +     * {@code Class} object. This includes public, protected, default
   78.23 +     * (package) access, and private methods, but excludes inherited methods.
   78.24 +     * The elements in the array returned are not sorted and are not in any
   78.25 +     * particular order.  This method returns an array of length 0 if the class
   78.26 +     * or interface declares no methods, or if this {@code Class} object
   78.27 +     * represents a primitive type, an array class, or void.  The class
   78.28 +     * initialization method {@code <clinit>} is not included in the
   78.29 +     * returned array. If the class declares multiple public member methods
   78.30 +     * with the same parameter types, they are all included in the returned
   78.31 +     * array.
   78.32 +     *
   78.33 +     * <p> See <em>The Java Language Specification</em>, section 8.2.
   78.34 +     *
   78.35 +     * @return    the array of {@code Method} objects representing all the
   78.36 +     * declared methods of this class
   78.37 +     * @exception  SecurityException
   78.38 +     *             If a security manager, <i>s</i>, is present and any of the
   78.39 +     *             following conditions is met:
   78.40 +     *
   78.41 +     *             <ul>
   78.42 +     *
   78.43 +     *             <li> invocation of
   78.44 +     *             {@link SecurityManager#checkMemberAccess
   78.45 +     *             s.checkMemberAccess(this, Member.DECLARED)} denies
   78.46 +     *             access to the declared methods within this class
   78.47 +     *
   78.48 +     *             <li> the caller's class loader is not the same as or an
   78.49 +     *             ancestor of the class loader for the current class and
   78.50 +     *             invocation of {@link SecurityManager#checkPackageAccess
   78.51 +     *             s.checkPackageAccess()} denies access to the package
   78.52 +     *             of this class
   78.53 +     *
   78.54 +     *             </ul>
   78.55 +     *
   78.56 +     * @since JDK1.1
   78.57 +     */
   78.58 +    public Method[] getDeclaredMethods() throws SecurityException {
   78.59 +        throw new SecurityException();
   78.60 +    }
   78.61 +    
   78.62      /**
   78.63       * Character.isDigit answers {@code true} to some non-ascii
   78.64       * digits.  This one does not.
   78.65 @@ -1096,6 +1142,48 @@
   78.66      public ClassLoader getClassLoader() {
   78.67          throw new SecurityException();
   78.68      }
   78.69 +
   78.70 +    /**
   78.71 +     * Determines the interfaces implemented by the class or interface
   78.72 +     * represented by this object.
   78.73 +     *
   78.74 +     * <p> If this object represents a class, the return value is an array
   78.75 +     * containing objects representing all interfaces implemented by the
   78.76 +     * class. The order of the interface objects in the array corresponds to
   78.77 +     * the order of the interface names in the {@code implements} clause
   78.78 +     * of the declaration of the class represented by this object. For
   78.79 +     * example, given the declaration:
   78.80 +     * <blockquote>
   78.81 +     * {@code class Shimmer implements FloorWax, DessertTopping { ... }}
   78.82 +     * </blockquote>
   78.83 +     * suppose the value of {@code s} is an instance of
   78.84 +     * {@code Shimmer}; the value of the expression:
   78.85 +     * <blockquote>
   78.86 +     * {@code s.getClass().getInterfaces()[0]}
   78.87 +     * </blockquote>
   78.88 +     * is the {@code Class} object that represents interface
   78.89 +     * {@code FloorWax}; and the value of:
   78.90 +     * <blockquote>
   78.91 +     * {@code s.getClass().getInterfaces()[1]}
   78.92 +     * </blockquote>
   78.93 +     * is the {@code Class} object that represents interface
   78.94 +     * {@code DessertTopping}.
   78.95 +     *
   78.96 +     * <p> If this object represents an interface, the array contains objects
   78.97 +     * representing all interfaces extended by the interface. The order of the
   78.98 +     * interface objects in the array corresponds to the order of the interface
   78.99 +     * names in the {@code extends} clause of the declaration of the
  78.100 +     * interface represented by this object.
  78.101 +     *
  78.102 +     * <p> If this object represents a class or interface that implements no
  78.103 +     * interfaces, the method returns an array of length 0.
  78.104 +     *
  78.105 +     * <p> If this object represents a primitive type or void, the method
  78.106 +     * returns an array of length 0.
  78.107 +     *
  78.108 +     * @return an array of interfaces implemented by this class.
  78.109 +     */
  78.110 +    public native Class<?>[] getInterfaces();
  78.111      
  78.112      /**
  78.113       * Returns the {@code Class} representing the component type of an
    79.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.2 +++ b/emul/mini/src/main/java/java/lang/Cloneable.java	Tue Feb 05 17:04:22 2013 +0100
    79.3 @@ -0,0 +1,54 @@
    79.4 +/*
    79.5 + * Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved.
    79.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    79.7 + *
    79.8 + * This code is free software; you can redistribute it and/or modify it
    79.9 + * under the terms of the GNU General Public License version 2 only, as
   79.10 + * published by the Free Software Foundation.  Oracle designates this
   79.11 + * particular file as subject to the "Classpath" exception as provided
   79.12 + * by Oracle in the LICENSE file that accompanied this code.
   79.13 + *
   79.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   79.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   79.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   79.17 + * version 2 for more details (a copy is included in the LICENSE file that
   79.18 + * accompanied this code).
   79.19 + *
   79.20 + * You should have received a copy of the GNU General Public License version
   79.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   79.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   79.23 + *
   79.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   79.25 + * or visit www.oracle.com if you need additional information or have any
   79.26 + * questions.
   79.27 + */
   79.28 +
   79.29 +package java.lang;
   79.30 +
   79.31 +/**
   79.32 + * A class implements the <code>Cloneable</code> interface to
   79.33 + * indicate to the {@link java.lang.Object#clone()} method that it
   79.34 + * is legal for that method to make a
   79.35 + * field-for-field copy of instances of that class.
   79.36 + * <p>
   79.37 + * Invoking Object's clone method on an instance that does not implement the
   79.38 + * <code>Cloneable</code> interface results in the exception
   79.39 + * <code>CloneNotSupportedException</code> being thrown.
   79.40 + * <p>
   79.41 + * By convention, classes that implement this interface should override
   79.42 + * <tt>Object.clone</tt> (which is protected) with a public method.
   79.43 + * See {@link java.lang.Object#clone()} for details on overriding this
   79.44 + * method.
   79.45 + * <p>
   79.46 + * Note that this interface does <i>not</i> contain the <tt>clone</tt> method.
   79.47 + * Therefore, it is not possible to clone an object merely by virtue of the
   79.48 + * fact that it implements this interface.  Even if the clone method is invoked
   79.49 + * reflectively, there is no guarantee that it will succeed.
   79.50 + *
   79.51 + * @author  unascribed
   79.52 + * @see     java.lang.CloneNotSupportedException
   79.53 + * @see     java.lang.Object#clone()
   79.54 + * @since   JDK1.0
   79.55 + */
   79.56 +public interface Cloneable {
   79.57 +}
    80.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.2 +++ b/emul/mini/src/main/java/java/lang/IllegalAccessError.java	Tue Feb 05 17:04:22 2013 +0100
    80.3 @@ -0,0 +1,58 @@
    80.4 +/*
    80.5 + * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
    80.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    80.7 + *
    80.8 + * This code is free software; you can redistribute it and/or modify it
    80.9 + * under the terms of the GNU General Public License version 2 only, as
   80.10 + * published by the Free Software Foundation.  Oracle designates this
   80.11 + * particular file as subject to the "Classpath" exception as provided
   80.12 + * by Oracle in the LICENSE file that accompanied this code.
   80.13 + *
   80.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   80.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   80.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   80.17 + * version 2 for more details (a copy is included in the LICENSE file that
   80.18 + * accompanied this code).
   80.19 + *
   80.20 + * You should have received a copy of the GNU General Public License version
   80.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   80.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   80.23 + *
   80.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   80.25 + * or visit www.oracle.com if you need additional information or have any
   80.26 + * questions.
   80.27 + */
   80.28 +
   80.29 +package java.lang;
   80.30 +
   80.31 +/**
   80.32 + * Thrown if an application attempts to access or modify a field, or
   80.33 + * to call a method that it does not have access to.
   80.34 + * <p>
   80.35 + * Normally, this error is caught by the compiler; this error can
   80.36 + * only occur at run time if the definition of a class has
   80.37 + * incompatibly changed.
   80.38 + *
   80.39 + * @author  unascribed
   80.40 + * @since   JDK1.0
   80.41 + */
   80.42 +public class IllegalAccessError extends IncompatibleClassChangeError {
   80.43 +    private static final long serialVersionUID = -8988904074992417891L;
   80.44 +
   80.45 +    /**
   80.46 +     * Constructs an <code>IllegalAccessError</code> with no detail message.
   80.47 +     */
   80.48 +    public IllegalAccessError() {
   80.49 +        super();
   80.50 +    }
   80.51 +
   80.52 +    /**
   80.53 +     * Constructs an <code>IllegalAccessError</code> with the specified
   80.54 +     * detail message.
   80.55 +     *
   80.56 +     * @param   s   the detail message.
   80.57 +     */
   80.58 +    public IllegalAccessError(String s) {
   80.59 +        super(s);
   80.60 +    }
   80.61 +}
    81.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    81.2 +++ b/emul/mini/src/main/java/java/lang/IncompatibleClassChangeError.java	Tue Feb 05 17:04:22 2013 +0100
    81.3 @@ -0,0 +1,57 @@
    81.4 +/*
    81.5 + * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
    81.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    81.7 + *
    81.8 + * This code is free software; you can redistribute it and/or modify it
    81.9 + * under the terms of the GNU General Public License version 2 only, as
   81.10 + * published by the Free Software Foundation.  Oracle designates this
   81.11 + * particular file as subject to the "Classpath" exception as provided
   81.12 + * by Oracle in the LICENSE file that accompanied this code.
   81.13 + *
   81.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   81.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   81.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   81.17 + * version 2 for more details (a copy is included in the LICENSE file that
   81.18 + * accompanied this code).
   81.19 + *
   81.20 + * You should have received a copy of the GNU General Public License version
   81.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   81.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   81.23 + *
   81.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   81.25 + * or visit www.oracle.com if you need additional information or have any
   81.26 + * questions.
   81.27 + */
   81.28 +
   81.29 +package java.lang;
   81.30 +
   81.31 +/**
   81.32 + * Thrown when an incompatible class change has occurred to some class
   81.33 + * definition. The definition of some class, on which the currently
   81.34 + * executing method depends, has since changed.
   81.35 + *
   81.36 + * @author  unascribed
   81.37 + * @since   JDK1.0
   81.38 + */
   81.39 +public
   81.40 +class IncompatibleClassChangeError extends LinkageError {
   81.41 +    private static final long serialVersionUID = -4914975503642802119L;
   81.42 +
   81.43 +    /**
   81.44 +     * Constructs an <code>IncompatibleClassChangeError</code> with no
   81.45 +     * detail message.
   81.46 +     */
   81.47 +    public IncompatibleClassChangeError () {
   81.48 +        super();
   81.49 +    }
   81.50 +
   81.51 +    /**
   81.52 +     * Constructs an <code>IncompatibleClassChangeError</code> with the
   81.53 +     * specified detail message.
   81.54 +     *
   81.55 +     * @param   s   the detail message.
   81.56 +     */
   81.57 +    public IncompatibleClassChangeError(String s) {
   81.58 +        super(s);
   81.59 +    }
   81.60 +}
    82.1 --- a/emul/mini/src/main/java/java/lang/Math.java	Tue Feb 05 16:40:01 2013 +0100
    82.2 +++ b/emul/mini/src/main/java/java/lang/Math.java	Tue Feb 05 17:04:22 2013 +0100
    82.3 @@ -375,6 +375,68 @@
    82.4      public static double floor(double a) {
    82.5          throw new UnsupportedOperationException();
    82.6      }
    82.7 +    /**
    82.8 +     * Computes the remainder operation on two arguments as prescribed
    82.9 +     * by the IEEE 754 standard.
   82.10 +     * The remainder value is mathematically equal to
   82.11 +     * <code>f1&nbsp;-&nbsp;f2</code>&nbsp;&times;&nbsp;<i>n</i>,
   82.12 +     * where <i>n</i> is the mathematical integer closest to the exact
   82.13 +     * mathematical value of the quotient {@code f1/f2}, and if two
   82.14 +     * mathematical integers are equally close to {@code f1/f2},
   82.15 +     * then <i>n</i> is the integer that is even. If the remainder is
   82.16 +     * zero, its sign is the same as the sign of the first argument.
   82.17 +     * Special cases:
   82.18 +     * <ul><li>If either argument is NaN, or the first argument is infinite,
   82.19 +     * or the second argument is positive zero or negative zero, then the
   82.20 +     * result is NaN.
   82.21 +     * <li>If the first argument is finite and the second argument is
   82.22 +     * infinite, then the result is the same as the first argument.</ul>
   82.23 +     *
   82.24 +     * @param   f1   the dividend.
   82.25 +     * @param   f2   the divisor.
   82.26 +     * @return  the remainder when {@code f1} is divided by
   82.27 +     *          {@code f2}.
   82.28 +     */
   82.29 +    public static double IEEEremainder(double f1, double f2) {
   82.30 +        return f1 - (f2 * Math.round(f1 / f2));
   82.31 +    }
   82.32 +
   82.33 +    /**
   82.34 +     * Returns the {@code double} value that is closest in value
   82.35 +     * to the argument and is equal to a mathematical integer. If two
   82.36 +     * {@code double} values that are mathematical integers are
   82.37 +     * equally close, the result is the integer value that is
   82.38 +     * even. Special cases:
   82.39 +     * <ul><li>If the argument value is already equal to a mathematical
   82.40 +     * integer, then the result is the same as the argument.
   82.41 +     * <li>If the argument is NaN or an infinity or positive zero or negative
   82.42 +     * zero, then the result is the same as the argument.</ul>
   82.43 +     *
   82.44 +     * @param   a   a {@code double} value.
   82.45 +     * @return  the closest floating-point value to {@code a} that is
   82.46 +     *          equal to a mathematical integer.
   82.47 +     */
   82.48 +    public static double rint(double a) {
   82.49 +        double ceil = ceil(a);
   82.50 +        double floor = floor(a);
   82.51 +        
   82.52 +        double dc = ceil - a;
   82.53 +        double df = a - floor;
   82.54 +        
   82.55 +        if (dc < df) {
   82.56 +            return ceil;
   82.57 +        } else if (dc > df) {
   82.58 +            return floor;
   82.59 +        }
   82.60 +        
   82.61 +        int tenC = (int) (ceil % 10.0);
   82.62 +        
   82.63 +        if (tenC % 2 == 0) {
   82.64 +            return ceil;
   82.65 +        } else {
   82.66 +            return floor;
   82.67 +        }
   82.68 +    }
   82.69  
   82.70      /**
   82.71       * Returns the angle <i>theta</i> from the conversion of rectangular
   82.72 @@ -929,9 +991,11 @@
   82.73       * @author Joseph D. Darcy
   82.74       * @since 1.5
   82.75       */
   82.76 -//    public static double signum(double d) {
   82.77 -//        return sun.misc.FpUtils.signum(d);
   82.78 -//    }
   82.79 +    public static double signum(double d) {
   82.80 +        if (d < 0.0) { return -1.0; }
   82.81 +        if (d > 0.0) { return 1.0; }
   82.82 +        return d;
   82.83 +    }
   82.84  
   82.85      /**
   82.86       * Returns the signum function of the argument; zero if the argument
   82.87 @@ -950,9 +1014,11 @@
   82.88       * @author Joseph D. Darcy
   82.89       * @since 1.5
   82.90       */
   82.91 -//    public static float signum(float f) {
   82.92 -//        return sun.misc.FpUtils.signum(f);
   82.93 -//    }
   82.94 +    public static float signum(float f) {
   82.95 +        if (f < 0.0f) { return -1.0f; }
   82.96 +        if (f > 0.0f) { return 1.0f; }
   82.97 +        return f;
   82.98 +    }
   82.99  
  82.100      /**
  82.101       * Returns the first floating-point argument with the sign of the
    83.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.2 +++ b/emul/mini/src/main/java/java/lang/Override.java	Tue Feb 05 17:04:22 2013 +0100
    83.3 @@ -0,0 +1,52 @@
    83.4 +/*
    83.5 + * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
    83.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    83.7 + *
    83.8 + * This code is free software; you can redistribute it and/or modify it
    83.9 + * under the terms of the GNU General Public License version 2 only, as
   83.10 + * published by the Free Software Foundation.  Oracle designates this
   83.11 + * particular file as subject to the "Classpath" exception as provided
   83.12 + * by Oracle in the LICENSE file that accompanied this code.
   83.13 + *
   83.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   83.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   83.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   83.17 + * version 2 for more details (a copy is included in the LICENSE file that
   83.18 + * accompanied this code).
   83.19 + *
   83.20 + * You should have received a copy of the GNU General Public License version
   83.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   83.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   83.23 + *
   83.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   83.25 + * or visit www.oracle.com if you need additional information or have any
   83.26 + * questions.
   83.27 + */
   83.28 +
   83.29 +package java.lang;
   83.30 +
   83.31 +import java.lang.annotation.*;
   83.32 +
   83.33 +/**
   83.34 + * Indicates that a method declaration is intended to override a
   83.35 + * method declaration in a supertype. If a method is annotated with
   83.36 + * this annotation type compilers are required to generate an error
   83.37 + * message unless at least one of the following conditions hold:
   83.38 + *
   83.39 + * <ul><li>
   83.40 + * The method does override or implement a method declared in a
   83.41 + * supertype.
   83.42 + * </li><li>
   83.43 + * The method has a signature that is override-equivalent to that of
   83.44 + * any public method declared in {@linkplain Object}.
   83.45 + * </li></ul>
   83.46 + *
   83.47 + * @author  Peter von der Ah&eacute;
   83.48 + * @author  Joshua Bloch
   83.49 + * @jls 9.6.1.4 Override
   83.50 + * @since 1.5
   83.51 + */
   83.52 +@Target(ElementType.METHOD)
   83.53 +@Retention(RetentionPolicy.SOURCE)
   83.54 +public @interface Override {
   83.55 +}
    84.1 --- a/emul/mini/src/main/java/java/lang/String.java	Tue Feb 05 16:40:01 2013 +0100
    84.2 +++ b/emul/mini/src/main/java/java/lang/String.java	Tue Feb 05 17:04:22 2013 +0100
    84.3 @@ -25,6 +25,7 @@
    84.4  
    84.5  package java.lang;
    84.6  
    84.7 +import java.io.UnsupportedEncodingException;
    84.8  import java.util.Comparator;
    84.9  import org.apidesign.bck2brwsr.core.ExtraJavaScript;
   84.10  import org.apidesign.bck2brwsr.core.JavaScriptBody;
   84.11 @@ -200,6 +201,10 @@
   84.12       *          If the {@code offset} and {@code count} arguments index
   84.13       *          characters outside the bounds of the {@code value} array
   84.14       */
   84.15 +    public String(char value[], int offset, int count) {
   84.16 +        initFromCharArray(value, offset, count);
   84.17 +    }
   84.18 +    
   84.19      @JavaScriptBody(args = { "charArr", "off", "cnt" }, body =
   84.20          "var up = off + cnt;\n" +
   84.21          "for (var i = off; i < up; i++) {\n" +
   84.22 @@ -207,8 +212,7 @@
   84.23          "}\n" +
   84.24          "this._r(charArr.slice(off, up).join(\"\"));\n"
   84.25      )
   84.26 -    public String(char value[], int offset, int count) {
   84.27 -    }
   84.28 +    private native void initFromCharArray(char value[], int offset, int count);
   84.29  
   84.30      /**
   84.31       * Allocates a new {@code String} that contains characters from a subarray
   84.32 @@ -415,17 +419,11 @@
   84.33       *
   84.34       * @since  JDK1.1
   84.35       */
   84.36 -//    public String(byte bytes[], int offset, int length, String charsetName)
   84.37 -//        throws UnsupportedEncodingException
   84.38 -//    {
   84.39 -//        if (charsetName == null)
   84.40 -//            throw new NullPointerException("charsetName");
   84.41 -//        checkBounds(bytes, offset, length);
   84.42 -//        char[] v = StringCoding.decode(charsetName, bytes, offset, length);
   84.43 -//        this.offset = 0;
   84.44 -//        this.count = v.length;
   84.45 -//        this.value = v;
   84.46 -//    }
   84.47 +    public String(byte bytes[], int offset, int length, String charsetName)
   84.48 +        throws UnsupportedEncodingException
   84.49 +    {
   84.50 +        this(checkUTF8(bytes, charsetName), offset, length);
   84.51 +    }
   84.52  
   84.53      /**
   84.54       * Constructs a new {@code String} by decoding the specified subarray of
   84.55 @@ -492,11 +490,11 @@
   84.56       *
   84.57       * @since  JDK1.1
   84.58       */
   84.59 -//    public String(byte bytes[], String charsetName)
   84.60 -//        throws UnsupportedEncodingException
   84.61 -//    {
   84.62 -//        this(bytes, 0, bytes.length, charsetName);
   84.63 -//    }
   84.64 +    public String(byte bytes[], String charsetName)
   84.65 +        throws UnsupportedEncodingException
   84.66 +    {
   84.67 +        this(bytes, 0, bytes.length, charsetName);
   84.68 +    }
   84.69  
   84.70      /**
   84.71       * Constructs a new {@code String} by decoding the specified array of
   84.72 @@ -553,10 +551,14 @@
   84.73      public String(byte bytes[], int offset, int length) {
   84.74          checkBounds(bytes, offset, length);
   84.75          char[] v  = new char[length];
   84.76 -        for (int i = 0; i < length; i++) {
   84.77 -            v[i] = (char)bytes[offset++];
   84.78 +        int[] at = { offset };
   84.79 +        int end = offset + length;
   84.80 +        int chlen = 0;
   84.81 +        while (at[0] < end) {
   84.82 +            int ch = nextChar(bytes, at);
   84.83 +            v[chlen++] = (char)ch;
   84.84          }
   84.85 -        this.r = new String(v, 0, v.length);
   84.86 +        initFromCharArray(v, 0, chlen);
   84.87      }
   84.88  
   84.89      /**
   84.90 @@ -925,12 +927,12 @@
   84.91       *
   84.92       * @since  JDK1.1
   84.93       */
   84.94 -//    public byte[] getBytes(String charsetName)
   84.95 -//        throws UnsupportedEncodingException
   84.96 -//    {
   84.97 -//        if (charsetName == null) throw new NullPointerException();
   84.98 -//        return StringCoding.encode(charsetName, value, offset, count);
   84.99 -//    }
  84.100 +    public byte[] getBytes(String charsetName)
  84.101 +        throws UnsupportedEncodingException
  84.102 +    {
  84.103 +        checkUTF8(null, charsetName);
  84.104 +        return getBytes();
  84.105 +    }
  84.106  
  84.107      /**
  84.108       * Encodes this {@code String} into a sequence of bytes using the given
  84.109 @@ -971,10 +973,24 @@
  84.110       * @since      JDK1.1
  84.111       */
  84.112      public byte[] getBytes() {
  84.113 -        byte[] arr = new byte[length()];
  84.114 -        for (int i = 0; i < arr.length; i++) {
  84.115 -            final char v = charAt(i);
  84.116 -            arr[i] = (byte)v;
  84.117 +        int len = length();
  84.118 +        byte[] arr = new byte[len];
  84.119 +        for (int i = 0, j = 0; j < len; j++) {
  84.120 +            final int v = charAt(j);
  84.121 +            if (v < 128) {
  84.122 +                arr[i++] = (byte) v;
  84.123 +                continue;
  84.124 +            }
  84.125 +            if (v < 0x0800) {
  84.126 +                arr = System.expandArray(arr, i + 1);
  84.127 +                arr[i++] = (byte) (0xC0 | (v >> 6));
  84.128 +                arr[i++] = (byte) (0x80 | (0x3F & v));
  84.129 +                continue;
  84.130 +            }
  84.131 +            arr = System.expandArray(arr, i + 2);
  84.132 +            arr[i++] = (byte) (0xE0 | (v >> 12));
  84.133 +            arr[i++] = (byte) (0x80 | ((v >> 6) & 0x7F));
  84.134 +            arr[i++] = (byte) (0x80 | (0x3F & v));
  84.135          }
  84.136          return arr;
  84.137      }
  84.138 @@ -1210,7 +1226,7 @@
  84.139      private static int offset() {
  84.140          return 0;
  84.141      }
  84.142 -    
  84.143 +
  84.144      private static class CaseInsensitiveComparator
  84.145                           implements Comparator<String>, java.io.Serializable {
  84.146          // use serialVersionUID from JDK 1.2.2 for interoperability
  84.147 @@ -3007,4 +3023,57 @@
  84.148       *          guaranteed to be from a pool of unique strings.
  84.149       */
  84.150      public native String intern();
  84.151 +    
  84.152 +    
  84.153 +    private static <T> T checkUTF8(T data, String charsetName)
  84.154 +        throws UnsupportedEncodingException {
  84.155 +        if (charsetName == null) {
  84.156 +            throw new NullPointerException("charsetName");
  84.157 +        }
  84.158 +        if (!charsetName.equalsIgnoreCase("UTF-8")
  84.159 +            && !charsetName.equalsIgnoreCase("UTF8")) {
  84.160 +            throw new UnsupportedEncodingException(charsetName);
  84.161 +        }
  84.162 +        return data;
  84.163 +    }
  84.164 +    
  84.165 +    private static int nextChar(byte[] arr, int[] index) throws IndexOutOfBoundsException {
  84.166 +        int c = arr[index[0]++] & 0xff;
  84.167 +        switch (c >> 4) {
  84.168 +            case 0:
  84.169 +            case 1:
  84.170 +            case 2:
  84.171 +            case 3:
  84.172 +            case 4:
  84.173 +            case 5:
  84.174 +            case 6:
  84.175 +            case 7:
  84.176 +                /* 0xxxxxxx*/
  84.177 +                return c;
  84.178 +            case 12:
  84.179 +            case 13: {
  84.180 +                /* 110x xxxx   10xx xxxx*/
  84.181 +                int char2 = (int) arr[index[0]++];
  84.182 +                if ((char2 & 0xC0) != 0x80) {
  84.183 +                    throw new IndexOutOfBoundsException("malformed input");
  84.184 +                }
  84.185 +                return (((c & 0x1F) << 6) | (char2 & 0x3F));
  84.186 +            }
  84.187 +            case 14: {
  84.188 +                /* 1110 xxxx  10xx xxxx  10xx xxxx */
  84.189 +                int char2 = arr[index[0]++];
  84.190 +                int char3 = arr[index[0]++];
  84.191 +                if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) {
  84.192 +                    throw new IndexOutOfBoundsException("malformed input");
  84.193 +                }
  84.194 +                return (((c & 0x0F) << 12)
  84.195 +                    | ((char2 & 0x3F) << 6)
  84.196 +                    | ((char3 & 0x3F) << 0));
  84.197 +            }
  84.198 +            default:
  84.199 +                /* 10xx xxxx,  1111 xxxx */
  84.200 +                throw new IndexOutOfBoundsException("malformed input");
  84.201 +        }
  84.202 +        
  84.203 +    }
  84.204  }
    85.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.2 +++ b/emul/mini/src/main/java/java/lang/reflect/Constructor.java	Tue Feb 05 17:04:22 2013 +0100
    85.3 @@ -0,0 +1,567 @@
    85.4 +/*
    85.5 + * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
    85.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    85.7 + *
    85.8 + * This code is free software; you can redistribute it and/or modify it
    85.9 + * under the terms of the GNU General Public License version 2 only, as
   85.10 + * published by the Free Software Foundation.  Oracle designates this
   85.11 + * particular file as subject to the "Classpath" exception as provided
   85.12 + * by Oracle in the LICENSE file that accompanied this code.
   85.13 + *
   85.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   85.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   85.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   85.17 + * version 2 for more details (a copy is included in the LICENSE file that
   85.18 + * accompanied this code).
   85.19 + *
   85.20 + * You should have received a copy of the GNU General Public License version
   85.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   85.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   85.23 + *
   85.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   85.25 + * or visit www.oracle.com if you need additional information or have any
   85.26 + * questions.
   85.27 + */
   85.28 +
   85.29 +package java.lang.reflect;
   85.30 +
   85.31 +import java.lang.annotation.Annotation;
   85.32 +import org.apidesign.bck2brwsr.emul.reflect.TypeProvider;
   85.33 +
   85.34 +/**
   85.35 + * {@code Constructor} provides information about, and access to, a single
   85.36 + * constructor for a class.
   85.37 + *
   85.38 + * <p>{@code Constructor} permits widening conversions to occur when matching the
   85.39 + * actual parameters to newInstance() with the underlying
   85.40 + * constructor's formal parameters, but throws an
   85.41 + * {@code IllegalArgumentException} if a narrowing conversion would occur.
   85.42 + *
   85.43 + * @param <T> the class in which the constructor is declared
   85.44 + *
   85.45 + * @see Member
   85.46 + * @see java.lang.Class
   85.47 + * @see java.lang.Class#getConstructors()
   85.48 + * @see java.lang.Class#getConstructor(Class[])
   85.49 + * @see java.lang.Class#getDeclaredConstructors()
   85.50 + *
   85.51 + * @author      Kenneth Russell
   85.52 + * @author      Nakul Saraiya
   85.53 + */
   85.54 +public final
   85.55 +    class Constructor<T> extends AccessibleObject implements
   85.56 +                                                    GenericDeclaration,
   85.57 +                                                    Member {
   85.58 +
   85.59 +    private Class<T>            clazz;
   85.60 +    private int                 slot;
   85.61 +    private Class<?>[]          parameterTypes;
   85.62 +    private Class<?>[]          exceptionTypes;
   85.63 +    private int                 modifiers;
   85.64 +    // Generics and annotations support
   85.65 +    private transient String    signature;
   85.66 +    private byte[]              annotations;
   85.67 +    private byte[]              parameterAnnotations;
   85.68 +
   85.69 +
   85.70 +    // For sharing of ConstructorAccessors. This branching structure
   85.71 +    // is currently only two levels deep (i.e., one root Constructor
   85.72 +    // and potentially many Constructor objects pointing to it.)
   85.73 +    private Constructor<T>      root;
   85.74 +
   85.75 +    /**
   85.76 +     * Package-private constructor used by ReflectAccess to enable
   85.77 +     * instantiation of these objects in Java code from the java.lang
   85.78 +     * package via sun.reflect.LangReflectAccess.
   85.79 +     */
   85.80 +    Constructor(Class<T> declaringClass,
   85.81 +                Class<?>[] parameterTypes,
   85.82 +                Class<?>[] checkedExceptions,
   85.83 +                int modifiers,
   85.84 +                int slot,
   85.85 +                String signature,
   85.86 +                byte[] annotations,
   85.87 +                byte[] parameterAnnotations)
   85.88 +    {
   85.89 +        this.clazz = declaringClass;
   85.90 +        this.parameterTypes = parameterTypes;
   85.91 +        this.exceptionTypes = checkedExceptions;
   85.92 +        this.modifiers = modifiers;
   85.93 +        this.slot = slot;
   85.94 +        this.signature = signature;
   85.95 +        this.annotations = annotations;
   85.96 +        this.parameterAnnotations = parameterAnnotations;
   85.97 +    }
   85.98 +
   85.99 +    /**
  85.100 +     * Package-private routine (exposed to java.lang.Class via
  85.101 +     * ReflectAccess) which returns a copy of this Constructor. The copy's
  85.102 +     * "root" field points to this Constructor.
  85.103 +     */
  85.104 +    Constructor<T> copy() {
  85.105 +        return this;
  85.106 +    }
  85.107 +
  85.108 +    /**
  85.109 +     * Returns the {@code Class} object representing the class that declares
  85.110 +     * the constructor represented by this {@code Constructor} object.
  85.111 +     */
  85.112 +    public Class<T> getDeclaringClass() {
  85.113 +        return clazz;
  85.114 +    }
  85.115 +
  85.116 +    /**
  85.117 +     * Returns the name of this constructor, as a string.  This is
  85.118 +     * the binary name of the constructor's declaring class.
  85.119 +     */
  85.120 +    public String getName() {
  85.121 +        return getDeclaringClass().getName();
  85.122 +    }
  85.123 +
  85.124 +    /**
  85.125 +     * Returns the Java language modifiers for the constructor
  85.126 +     * represented by this {@code Constructor} object, as an integer. The
  85.127 +     * {@code Modifier} class should be used to decode the modifiers.
  85.128 +     *
  85.129 +     * @see Modifier
  85.130 +     */
  85.131 +    public int getModifiers() {
  85.132 +        return modifiers;
  85.133 +    }
  85.134 +
  85.135 +    /**
  85.136 +     * Returns an array of {@code TypeVariable} objects that represent the
  85.137 +     * type variables declared by the generic declaration represented by this
  85.138 +     * {@code GenericDeclaration} object, in declaration order.  Returns an
  85.139 +     * array of length 0 if the underlying generic declaration declares no type
  85.140 +     * variables.
  85.141 +     *
  85.142 +     * @return an array of {@code TypeVariable} objects that represent
  85.143 +     *     the type variables declared by this generic declaration
  85.144 +     * @throws GenericSignatureFormatError if the generic
  85.145 +     *     signature of this generic declaration does not conform to
  85.146 +     *     the format specified in
  85.147 +     *     <cite>The Java&trade; Virtual Machine Specification</cite>
  85.148 +     * @since 1.5
  85.149 +     */
  85.150 +    public TypeVariable<Constructor<T>>[] getTypeParameters() {
  85.151 +        return TypeProvider.getDefault().getTypeParameters(this);
  85.152 +    }
  85.153 +
  85.154 +
  85.155 +    /**
  85.156 +     * Returns an array of {@code Class} objects that represent the formal
  85.157 +     * parameter types, in declaration order, of the constructor
  85.158 +     * represented by this {@code Constructor} object.  Returns an array of
  85.159 +     * length 0 if the underlying constructor takes no parameters.
  85.160 +     *
  85.161 +     * @return the parameter types for the constructor this object
  85.162 +     * represents
  85.163 +     */
  85.164 +    public Class<?>[] getParameterTypes() {
  85.165 +        return (Class<?>[]) parameterTypes.clone();
  85.166 +    }
  85.167 +
  85.168 +
  85.169 +    /**
  85.170 +     * Returns an array of {@code Type} objects that represent the formal
  85.171 +     * parameter types, in declaration order, of the method represented by
  85.172 +     * this {@code Constructor} object. Returns an array of length 0 if the
  85.173 +     * underlying method takes no parameters.
  85.174 +     *
  85.175 +     * <p>If a formal parameter type is a parameterized type,
  85.176 +     * the {@code Type} object returned for it must accurately reflect
  85.177 +     * the actual type parameters used in the source code.
  85.178 +     *
  85.179 +     * <p>If a formal parameter type is a type variable or a parameterized
  85.180 +     * type, it is created. Otherwise, it is resolved.
  85.181 +     *
  85.182 +     * @return an array of {@code Type}s that represent the formal
  85.183 +     *     parameter types of the underlying method, in declaration order
  85.184 +     * @throws GenericSignatureFormatError
  85.185 +     *     if the generic method signature does not conform to the format
  85.186 +     *     specified in
  85.187 +     *     <cite>The Java&trade; Virtual Machine Specification</cite>
  85.188 +     * @throws TypeNotPresentException if any of the parameter
  85.189 +     *     types of the underlying method refers to a non-existent type
  85.190 +     *     declaration
  85.191 +     * @throws MalformedParameterizedTypeException if any of
  85.192 +     *     the underlying method's parameter types refer to a parameterized
  85.193 +     *     type that cannot be instantiated for any reason
  85.194 +     * @since 1.5
  85.195 +     */
  85.196 +    public Type[] getGenericParameterTypes() {
  85.197 +        return TypeProvider.getDefault().getGenericParameterTypes(this);
  85.198 +    }
  85.199 +
  85.200 +
  85.201 +    /**
  85.202 +     * Returns an array of {@code Class} objects that represent the types
  85.203 +     * of exceptions declared to be thrown by the underlying constructor
  85.204 +     * represented by this {@code Constructor} object.  Returns an array of
  85.205 +     * length 0 if the constructor declares no exceptions in its {@code throws} clause.
  85.206 +     *
  85.207 +     * @return the exception types declared as being thrown by the
  85.208 +     * constructor this object represents
  85.209 +     */
  85.210 +    public Class<?>[] getExceptionTypes() {
  85.211 +        return (Class<?>[])exceptionTypes.clone();
  85.212 +    }
  85.213 +
  85.214 +
  85.215 +    /**
  85.216 +     * Returns an array of {@code Type} objects that represent the
  85.217 +     * exceptions declared to be thrown by this {@code Constructor} object.
  85.218 +     * Returns an array of length 0 if the underlying method declares
  85.219 +     * no exceptions in its {@code throws} clause.
  85.220 +     *
  85.221 +     * <p>If an exception type is a type variable or a parameterized
  85.222 +     * type, it is created. Otherwise, it is resolved.
  85.223 +     *
  85.224 +     * @return an array of Types that represent the exception types
  85.225 +     *     thrown by the underlying method
  85.226 +     * @throws GenericSignatureFormatError
  85.227 +     *     if the generic method signature does not conform to the format
  85.228 +     *     specified in
  85.229 +     *     <cite>The Java&trade; Virtual Machine Specification</cite>
  85.230 +     * @throws TypeNotPresentException if the underlying method's
  85.231 +     *     {@code throws} clause refers to a non-existent type declaration
  85.232 +     * @throws MalformedParameterizedTypeException if
  85.233 +     *     the underlying method's {@code throws} clause refers to a
  85.234 +     *     parameterized type that cannot be instantiated for any reason
  85.235 +     * @since 1.5
  85.236 +     */
  85.237 +      public Type[] getGenericExceptionTypes() {
  85.238 +          return TypeProvider.getDefault().getGenericExceptionTypes(this);
  85.239 +      }
  85.240 +
  85.241 +    /**
  85.242 +     * Compares this {@code Constructor} against the specified object.
  85.243 +     * Returns true if the objects are the same.  Two {@code Constructor} objects are
  85.244 +     * the same if they were declared by the same class and have the
  85.245 +     * same formal parameter types.
  85.246 +     */
  85.247 +    public boolean equals(Object obj) {
  85.248 +        if (obj != null && obj instanceof Constructor) {
  85.249 +            Constructor<?> other = (Constructor<?>)obj;
  85.250 +            if (getDeclaringClass() == other.getDeclaringClass()) {
  85.251 +                /* Avoid unnecessary cloning */
  85.252 +                Class<?>[] params1 = parameterTypes;
  85.253 +                Class<?>[] params2 = other.parameterTypes;
  85.254 +                if (params1.length == params2.length) {
  85.255 +                    for (int i = 0; i < params1.length; i++) {
  85.256 +                        if (params1[i] != params2[i])
  85.257 +                            return false;
  85.258 +                    }
  85.259 +                    return true;
  85.260 +                }
  85.261 +            }
  85.262 +        }
  85.263 +        return false;
  85.264 +    }
  85.265 +
  85.266 +    /**
  85.267 +     * Returns a hashcode for this {@code Constructor}. The hashcode is
  85.268 +     * the same as the hashcode for the underlying constructor's
  85.269 +     * declaring class name.
  85.270 +     */
  85.271 +    public int hashCode() {
  85.272 +        return getDeclaringClass().getName().hashCode();
  85.273 +    }
  85.274 +
  85.275 +    /**
  85.276 +     * Returns a string describing this {@code Constructor}.  The string is
  85.277 +     * formatted as the constructor access modifiers, if any,
  85.278 +     * followed by the fully-qualified name of the declaring class,
  85.279 +     * followed by a parenthesized, comma-separated list of the
  85.280 +     * constructor's formal parameter types.  For example:
  85.281 +     * <pre>
  85.282 +     *    public java.util.Hashtable(int,float)
  85.283 +     * </pre>
  85.284 +     *
  85.285 +     * <p>The only possible modifiers for constructors are the access
  85.286 +     * modifiers {@code public}, {@code protected} or
  85.287 +     * {@code private}.  Only one of these may appear, or none if the
  85.288 +     * constructor has default (package) access.
  85.289 +     */
  85.290 +    public String toString() {
  85.291 +        try {
  85.292 +            StringBuffer sb = new StringBuffer();
  85.293 +            int mod = getModifiers() & Modifier.constructorModifiers();
  85.294 +            if (mod != 0) {
  85.295 +                sb.append(Modifier.toString(mod) + " ");
  85.296 +            }
  85.297 +            sb.append(Field.getTypeName(getDeclaringClass()));
  85.298 +            sb.append("(");
  85.299 +            Class<?>[] params = parameterTypes; // avoid clone
  85.300 +            for (int j = 0; j < params.length; j++) {
  85.301 +                sb.append(Field.getTypeName(params[j]));
  85.302 +                if (j < (params.length - 1))
  85.303 +                    sb.append(",");
  85.304 +            }
  85.305 +            sb.append(")");
  85.306 +            Class<?>[] exceptions = exceptionTypes; // avoid clone
  85.307 +            if (exceptions.length > 0) {
  85.308 +                sb.append(" throws ");
  85.309 +                for (int k = 0; k < exceptions.length; k++) {
  85.310 +                    sb.append(exceptions[k].getName());
  85.311 +                    if (k < (exceptions.length - 1))
  85.312 +                        sb.append(",");
  85.313 +                }
  85.314 +            }
  85.315 +            return sb.toString();
  85.316 +        } catch (Exception e) {
  85.317 +            return "<" + e + ">";
  85.318 +        }
  85.319 +    }
  85.320 +
  85.321 +    /**
  85.322 +     * Returns a string describing this {@code Constructor},
  85.323 +     * including type parameters.  The string is formatted as the
  85.324 +     * constructor access modifiers, if any, followed by an
  85.325 +     * angle-bracketed comma separated list of the constructor's type
  85.326 +     * parameters, if any, followed by the fully-qualified name of the
  85.327 +     * declaring class, followed by a parenthesized, comma-separated
  85.328 +     * list of the constructor's generic formal parameter types.
  85.329 +     *
  85.330 +     * If this constructor was declared to take a variable number of
  85.331 +     * arguments, instead of denoting the last parameter as
  85.332 +     * "<tt><i>Type</i>[]</tt>", it is denoted as
  85.333 +     * "<tt><i>Type</i>...</tt>".
  85.334 +     *
  85.335 +     * A space is used to separate access modifiers from one another
  85.336 +     * and from the type parameters or return type.  If there are no
  85.337 +     * type parameters, the type parameter list is elided; if the type
  85.338 +     * parameter list is present, a space separates the list from the
  85.339 +     * class name.  If the constructor is declared to throw
  85.340 +     * exceptions, the parameter list is followed by a space, followed
  85.341 +     * by the word "{@code throws}" followed by a
  85.342 +     * comma-separated list of the thrown exception types.
  85.343 +     *
  85.344 +     * <p>The only possible modifiers for constructors are the access
  85.345 +     * modifiers {@code public}, {@code protected} or
  85.346 +     * {@code private}.  Only one of these may appear, or none if the
  85.347 +     * constructor has default (package) access.
  85.348 +     *
  85.349 +     * @return a string describing this {@code Constructor},
  85.350 +     * include type parameters
  85.351 +     *
  85.352 +     * @since 1.5
  85.353 +     */
  85.354 +    public String toGenericString() {
  85.355 +        try {
  85.356 +            StringBuilder sb = new StringBuilder();
  85.357 +            int mod = getModifiers() & Modifier.constructorModifiers();
  85.358 +            if (mod != 0) {
  85.359 +                sb.append(Modifier.toString(mod) + " ");
  85.360 +            }
  85.361 +            TypeVariable<?>[] typeparms = getTypeParameters();
  85.362 +            if (typeparms.length > 0) {
  85.363 +                boolean first = true;
  85.364 +                sb.append("<");
  85.365 +                for(TypeVariable<?> typeparm: typeparms) {
  85.366 +                    if (!first)
  85.367 +                        sb.append(",");
  85.368 +                    // Class objects can't occur here; no need to test
  85.369 +                    // and call Class.getName().
  85.370 +                    sb.append(typeparm.toString());
  85.371 +                    first = false;
  85.372 +                }
  85.373 +                sb.append("> ");
  85.374 +            }
  85.375 +            sb.append(Field.getTypeName(getDeclaringClass()));
  85.376 +            sb.append("(");
  85.377 +            Type[] params = getGenericParameterTypes();
  85.378 +            for (int j = 0; j < params.length; j++) {
  85.379 +                String param = (params[j] instanceof Class<?>)?
  85.380 +                    Field.getTypeName((Class<?>)params[j]):
  85.381 +                    (params[j].toString());
  85.382 +                if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
  85.383 +                    param = param.replaceFirst("\\[\\]$", "...");
  85.384 +                sb.append(param);
  85.385 +                if (j < (params.length - 1))
  85.386 +                    sb.append(",");
  85.387 +            }
  85.388 +            sb.append(")");
  85.389 +            Type[] exceptions = getGenericExceptionTypes();
  85.390 +            if (exceptions.length > 0) {
  85.391 +                sb.append(" throws ");
  85.392 +                for (int k = 0; k < exceptions.length; k++) {
  85.393 +                    sb.append((exceptions[k] instanceof Class)?
  85.394 +                              ((Class<?>)exceptions[k]).getName():
  85.395 +                              exceptions[k].toString());
  85.396 +                    if (k < (exceptions.length - 1))
  85.397 +                        sb.append(",");
  85.398 +                }
  85.399 +            }
  85.400 +            return sb.toString();
  85.401 +        } catch (Exception e) {
  85.402 +            return "<" + e + ">";
  85.403 +        }
  85.404 +    }
  85.405 +
  85.406 +    /**
  85.407 +     * Uses the constructor represented by this {@code Constructor} object to
  85.408 +     * create and initialize a new instance of the constructor's
  85.409 +     * declaring class, with the specified initialization parameters.
  85.410 +     * Individual parameters are automatically unwrapped to match
  85.411 +     * primitive formal parameters, and both primitive and reference
  85.412 +     * parameters are subject to method invocation conversions as necessary.
  85.413 +     *
  85.414 +     * <p>If the number of formal parameters required by the underlying constructor
  85.415 +     * is 0, the supplied {@code initargs} array may be of length 0 or null.
  85.416 +     *
  85.417 +     * <p>If the constructor's declaring class is an inner class in a
  85.418 +     * non-static context, the first argument to the constructor needs
  85.419 +     * to be the enclosing instance; see section 15.9.3 of
  85.420 +     * <cite>The Java&trade; Language Specification</cite>.
  85.421 +     *
  85.422 +     * <p>If the required access and argument checks succeed and the
  85.423 +     * instantiation will proceed, the constructor's declaring class
  85.424 +     * is initialized if it has not already been initialized.
  85.425 +     *
  85.426 +     * <p>If the constructor completes normally, returns the newly
  85.427 +     * created and initialized instance.
  85.428 +     *
  85.429 +     * @param initargs array of objects to be passed as arguments to
  85.430 +     * the constructor call; values of primitive types are wrapped in
  85.431 +     * a wrapper object of the appropriate type (e.g. a {@code float}
  85.432 +     * in a {@link java.lang.Float Float})
  85.433 +     *
  85.434 +     * @return a new object created by calling the constructor
  85.435 +     * this object represents
  85.436 +     *
  85.437 +     * @exception IllegalAccessException    if this {@code Constructor} object
  85.438 +     *              is enforcing Java language access control and the underlying
  85.439 +     *              constructor is inaccessible.
  85.440 +     * @exception IllegalArgumentException  if the number of actual
  85.441 +     *              and formal parameters differ; if an unwrapping
  85.442 +     *              conversion for primitive arguments fails; or if,
  85.443 +     *              after possible unwrapping, a parameter value
  85.444 +     *              cannot be converted to the corresponding formal
  85.445 +     *              parameter type by a method invocation conversion; if
  85.446 +     *              this constructor pertains to an enum type.
  85.447 +     * @exception InstantiationException    if the class that declares the
  85.448 +     *              underlying constructor represents an abstract class.
  85.449 +     * @exception InvocationTargetException if the underlying constructor
  85.450 +     *              throws an exception.
  85.451 +     * @exception ExceptionInInitializerError if the initialization provoked
  85.452 +     *              by this method fails.
  85.453 +     */
  85.454 +    public T newInstance(Object ... initargs)
  85.455 +        throws InstantiationException, IllegalAccessException,
  85.456 +               IllegalArgumentException, InvocationTargetException
  85.457 +    {
  85.458 +        throw new SecurityException();
  85.459 +    }
  85.460 +
  85.461 +    /**
  85.462 +     * Returns {@code true} if this constructor was declared to take
  85.463 +     * a variable number of arguments; returns {@code false}
  85.464 +     * otherwise.
  85.465 +     *
  85.466 +     * @return {@code true} if an only if this constructor was declared to
  85.467 +     * take a variable number of arguments.
  85.468 +     * @since 1.5
  85.469 +     */
  85.470 +    public boolean isVarArgs() {
  85.471 +        return (getModifiers() & Modifier.VARARGS) != 0;
  85.472 +    }
  85.473 +
  85.474 +    /**
  85.475 +     * Returns {@code true} if this constructor is a synthetic
  85.476 +     * constructor; returns {@code false} otherwise.
  85.477 +     *
  85.478 +     * @return true if and only if this constructor is a synthetic
  85.479 +     * constructor as defined by
  85.480 +     * <cite>The Java&trade; Language Specification</cite>.
  85.481 +     * @since 1.5
  85.482 +     */
  85.483 +    public boolean isSynthetic() {
  85.484 +        return Modifier.isSynthetic(getModifiers());
  85.485 +    }
  85.486 +
  85.487 +    int getSlot() {
  85.488 +        return slot;
  85.489 +    }
  85.490 +
  85.491 +   String getSignature() {
  85.492 +            return signature;
  85.493 +   }
  85.494 +
  85.495 +    byte[] getRawAnnotations() {
  85.496 +        return annotations;
  85.497 +    }
  85.498 +
  85.499 +    byte[] getRawParameterAnnotations() {
  85.500 +        return parameterAnnotations;
  85.501 +    }
  85.502 +
  85.503 +    /**
  85.504 +     * @throws NullPointerException {@inheritDoc}
  85.505 +     * @since 1.5
  85.506 +     */
  85.507 +    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
  85.508 +        if (annotationClass == null)
  85.509 +            throw new NullPointerException();
  85.510 +
  85.511 +        return null; // XXX (T) declaredAnnotations().get(annotationClass);
  85.512 +    }
  85.513 +
  85.514 +    /**
  85.515 +     * @since 1.5
  85.516 +     */
  85.517 +    public Annotation[] getDeclaredAnnotations()  {
  85.518 +        return new Annotation[0]; // XXX AnnotationParser.toArray(declaredAnnotations());
  85.519 +    }
  85.520 +
  85.521 +    /**
  85.522 +     * Returns an array of arrays that represent the annotations on the formal
  85.523 +     * parameters, in declaration order, of the method represented by
  85.524 +     * this {@code Constructor} object. (Returns an array of length zero if the
  85.525 +     * underlying method is parameterless.  If the method has one or more
  85.526 +     * parameters, a nested array of length zero is returned for each parameter
  85.527 +     * with no annotations.) The annotation objects contained in the returned
  85.528 +     * arrays are serializable.  The caller of this method is free to modify
  85.529 +     * the returned arrays; it will have no effect on the arrays returned to
  85.530 +     * other callers.
  85.531 +     *
  85.532 +     * @return an array of arrays that represent the annotations on the formal
  85.533 +     *    parameters, in declaration order, of the method represented by this
  85.534 +     *    Constructor object
  85.535 +     * @since 1.5
  85.536 +     */
  85.537 +    public Annotation[][] getParameterAnnotations() {
  85.538 +        int numParameters = parameterTypes.length;
  85.539 +        if (parameterAnnotations == null)
  85.540 +            return new Annotation[numParameters][0];
  85.541 +        
  85.542 +        return new Annotation[numParameters][0]; // XXX
  85.543 +/*
  85.544 +        Annotation[][] result = AnnotationParser.parseParameterAnnotations(
  85.545 +            parameterAnnotations,
  85.546 +            sun.misc.SharedSecrets.getJavaLangAccess().
  85.547 +                getConstantPool(getDeclaringClass()),
  85.548 +            getDeclaringClass());
  85.549 +        if (result.length != numParameters) {
  85.550 +            Class<?> declaringClass = getDeclaringClass();
  85.551 +            if (declaringClass.isEnum() ||
  85.552 +                declaringClass.isAnonymousClass() ||
  85.553 +                declaringClass.isLocalClass() )
  85.554 +                ; // Can't do reliable parameter counting
  85.555 +            else {
  85.556 +                if (!declaringClass.isMemberClass() || // top-level
  85.557 +                    // Check for the enclosing instance parameter for
  85.558 +                    // non-static member classes
  85.559 +                    (declaringClass.isMemberClass() &&
  85.560 +                     ((declaringClass.getModifiers() & Modifier.STATIC) == 0)  &&
  85.561 +                     result.length + 1 != numParameters) ) {
  85.562 +                    throw new AnnotationFormatError(
  85.563 +                              "Parameter annotations don't match number of parameters");
  85.564 +                }
  85.565 +            }
  85.566 +        }
  85.567 +        return result;
  85.568 +        */
  85.569 +    }
  85.570 +}
    86.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.2 +++ b/emul/mini/src/main/java/java/lang/reflect/InvocationHandler.java	Tue Feb 05 17:04:22 2013 +0100
    86.3 @@ -0,0 +1,95 @@
    86.4 +/*
    86.5 + * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
    86.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    86.7 + *
    86.8 + * This code is free software; you can redistribute it and/or modify it
    86.9 + * under the terms of the GNU General Public License version 2 only, as
   86.10 + * published by the Free Software Foundation.  Oracle designates this
   86.11 + * particular file as subject to the "Classpath" exception as provided
   86.12 + * by Oracle in the LICENSE file that accompanied this code.
   86.13 + *
   86.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   86.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   86.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   86.17 + * version 2 for more details (a copy is included in the LICENSE file that
   86.18 + * accompanied this code).
   86.19 + *
   86.20 + * You should have received a copy of the GNU General Public License version
   86.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   86.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   86.23 + *
   86.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   86.25 + * or visit www.oracle.com if you need additional information or have any
   86.26 + * questions.
   86.27 + */
   86.28 +
   86.29 +package java.lang.reflect;
   86.30 +
   86.31 +/**
   86.32 + * {@code InvocationHandler} is the interface implemented by
   86.33 + * the <i>invocation handler</i> of a proxy instance.
   86.34 + *
   86.35 + * <p>Each proxy instance has an associated invocation handler.
   86.36 + * When a method is invoked on a proxy instance, the method
   86.37 + * invocation is encoded and dispatched to the {@code invoke}
   86.38 + * method of its invocation handler.
   86.39 + *
   86.40 + * @author      Peter Jones
   86.41 + * @see         Proxy
   86.42 + * @since       1.3
   86.43 + */
   86.44 +public interface InvocationHandler {
   86.45 +
   86.46 +    /**
   86.47 +     * Processes a method invocation on a proxy instance and returns
   86.48 +     * the result.  This method will be invoked on an invocation handler
   86.49 +     * when a method is invoked on a proxy instance that it is
   86.50 +     * associated with.
   86.51 +     *
   86.52 +     * @param   proxy the proxy instance that the method was invoked on
   86.53 +     *
   86.54 +     * @param   method the {@code Method} instance corresponding to
   86.55 +     * the interface method invoked on the proxy instance.  The declaring
   86.56 +     * class of the {@code Method} object will be the interface that
   86.57 +     * the method was declared in, which may be a superinterface of the
   86.58 +     * proxy interface that the proxy class inherits the method through.
   86.59 +     *
   86.60 +     * @param   args an array of objects containing the values of the
   86.61 +     * arguments passed in the method invocation on the proxy instance,
   86.62 +     * or {@code null} if interface method takes no arguments.
   86.63 +     * Arguments of primitive types are wrapped in instances of the
   86.64 +     * appropriate primitive wrapper class, such as
   86.65 +     * {@code java.lang.Integer} or {@code java.lang.Boolean}.
   86.66 +     *
   86.67 +     * @return  the value to return from the method invocation on the
   86.68 +     * proxy instance.  If the declared return type of the interface
   86.69 +     * method is a primitive type, then the value returned by
   86.70 +     * this method must be an instance of the corresponding primitive
   86.71 +     * wrapper class; otherwise, it must be a type assignable to the
   86.72 +     * declared return type.  If the value returned by this method is
   86.73 +     * {@code null} and the interface method's return type is
   86.74 +     * primitive, then a {@code NullPointerException} will be
   86.75 +     * thrown by the method invocation on the proxy instance.  If the
   86.76 +     * value returned by this method is otherwise not compatible with
   86.77 +     * the interface method's declared return type as described above,
   86.78 +     * a {@code ClassCastException} will be thrown by the method
   86.79 +     * invocation on the proxy instance.
   86.80 +     *
   86.81 +     * @throws  Throwable the exception to throw from the method
   86.82 +     * invocation on the proxy instance.  The exception's type must be
   86.83 +     * assignable either to any of the exception types declared in the
   86.84 +     * {@code throws} clause of the interface method or to the
   86.85 +     * unchecked exception types {@code java.lang.RuntimeException}
   86.86 +     * or {@code java.lang.Error}.  If a checked exception is
   86.87 +     * thrown by this method that is not assignable to any of the
   86.88 +     * exception types declared in the {@code throws} clause of
   86.89 +     * the interface method, then an
   86.90 +     * {@link UndeclaredThrowableException} containing the
   86.91 +     * exception that was thrown by this method will be thrown by the
   86.92 +     * method invocation on the proxy instance.
   86.93 +     *
   86.94 +     * @see     UndeclaredThrowableException
   86.95 +     */
   86.96 +    public Object invoke(Object proxy, Method method, Object[] args)
   86.97 +        throws Throwable;
   86.98 +}
    87.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.2 +++ b/emul/mini/src/main/java/java/lang/reflect/Proxy.java	Tue Feb 05 17:04:22 2013 +0100
    87.3 @@ -0,0 +1,407 @@
    87.4 +/*
    87.5 + * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
    87.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    87.7 + *
    87.8 + * This code is free software; you can redistribute it and/or modify it
    87.9 + * under the terms of the GNU General Public License version 2 only, as
   87.10 + * published by the Free Software Foundation.  Oracle designates this
   87.11 + * particular file as subject to the "Classpath" exception as provided
   87.12 + * by Oracle in the LICENSE file that accompanied this code.
   87.13 + *
   87.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   87.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   87.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   87.17 + * version 2 for more details (a copy is included in the LICENSE file that
   87.18 + * accompanied this code).
   87.19 + *
   87.20 + * You should have received a copy of the GNU General Public License version
   87.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   87.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   87.23 + *
   87.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   87.25 + * or visit www.oracle.com if you need additional information or have any
   87.26 + * questions.
   87.27 + */
   87.28 +
   87.29 +package java.lang.reflect;
   87.30 +
   87.31 +
   87.32 +/**
   87.33 + * {@code Proxy} provides static methods for creating dynamic proxy
   87.34 + * classes and instances, and it is also the superclass of all
   87.35 + * dynamic proxy classes created by those methods.
   87.36 + *
   87.37 + * <p>To create a proxy for some interface {@code Foo}:
   87.38 + * <pre>
   87.39 + *     InvocationHandler handler = new MyInvocationHandler(...);
   87.40 + *     Class proxyClass = Proxy.getProxyClass(
   87.41 + *         Foo.class.getClassLoader(), new Class[] { Foo.class });
   87.42 + *     Foo f = (Foo) proxyClass.
   87.43 + *         getConstructor(new Class[] { InvocationHandler.class }).
   87.44 + *         newInstance(new Object[] { handler });
   87.45 + * </pre>
   87.46 + * or more simply:
   87.47 + * <pre>
   87.48 + *     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
   87.49 + *                                          new Class[] { Foo.class },
   87.50 + *                                          handler);
   87.51 + * </pre>
   87.52 + *
   87.53 + * <p>A <i>dynamic proxy class</i> (simply referred to as a <i>proxy
   87.54 + * class</i> below) is a class that implements a list of interfaces
   87.55 + * specified at runtime when the class is created, with behavior as
   87.56 + * described below.
   87.57 + *
   87.58 + * A <i>proxy interface</i> is such an interface that is implemented
   87.59 + * by a proxy class.
   87.60 + *
   87.61 + * A <i>proxy instance</i> is an instance of a proxy class.
   87.62 + *
   87.63 + * Each proxy instance has an associated <i>invocation handler</i>
   87.64 + * object, which implements the interface {@link InvocationHandler}.
   87.65 + * A method invocation on a proxy instance through one of its proxy
   87.66 + * interfaces will be dispatched to the {@link InvocationHandler#invoke
   87.67 + * invoke} method of the instance's invocation handler, passing the proxy
   87.68 + * instance, a {@code java.lang.reflect.Method} object identifying
   87.69 + * the method that was invoked, and an array of type {@code Object}
   87.70 + * containing the arguments.  The invocation handler processes the
   87.71 + * encoded method invocation as appropriate and the result that it
   87.72 + * returns will be returned as the result of the method invocation on
   87.73 + * the proxy instance.
   87.74 + *
   87.75 + * <p>A proxy class has the following properties:
   87.76 + *
   87.77 + * <ul>
   87.78 + * <li>Proxy classes are public, final, and not abstract.
   87.79 + *
   87.80 + * <li>The unqualified name of a proxy class is unspecified.  The space
   87.81 + * of class names that begin with the string {@code "$Proxy"}
   87.82 + * should be, however, reserved for proxy classes.
   87.83 + *
   87.84 + * <li>A proxy class extends {@code java.lang.reflect.Proxy}.
   87.85 + *
   87.86 + * <li>A proxy class implements exactly the interfaces specified at its
   87.87 + * creation, in the same order.
   87.88 + *
   87.89 + * <li>If a proxy class implements a non-public interface, then it will
   87.90 + * be defined in the same package as that interface.  Otherwise, the
   87.91 + * package of a proxy class is also unspecified.  Note that package
   87.92 + * sealing will not prevent a proxy class from being successfully defined
   87.93 + * in a particular package at runtime, and neither will classes already
   87.94 + * defined by the same class loader and the same package with particular
   87.95 + * signers.
   87.96 + *
   87.97 + * <li>Since a proxy class implements all of the interfaces specified at
   87.98 + * its creation, invoking {@code getInterfaces} on its
   87.99 + * {@code Class} object will return an array containing the same
  87.100 + * list of interfaces (in the order specified at its creation), invoking
  87.101 + * {@code getMethods} on its {@code Class} object will return
  87.102 + * an array of {@code Method} objects that include all of the
  87.103 + * methods in those interfaces, and invoking {@code getMethod} will
  87.104 + * find methods in the proxy interfaces as would be expected.
  87.105 + *
  87.106 + * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method will
  87.107 + * return true if it is passed a proxy class-- a class returned by
  87.108 + * {@code Proxy.getProxyClass} or the class of an object returned by
  87.109 + * {@code Proxy.newProxyInstance}-- and false otherwise.
  87.110 + *
  87.111 + * <li>The {@code java.security.ProtectionDomain} of a proxy class
  87.112 + * is the same as that of system classes loaded by the bootstrap class
  87.113 + * loader, such as {@code java.lang.Object}, because the code for a
  87.114 + * proxy class is generated by trusted system code.  This protection
  87.115 + * domain will typically be granted
  87.116 + * {@code java.security.AllPermission}.
  87.117 + *
  87.118 + * <li>Each proxy class has one public constructor that takes one argument,
  87.119 + * an implementation of the interface {@link InvocationHandler}, to set
  87.120 + * the invocation handler for a proxy instance.  Rather than having to use
  87.121 + * the reflection API to access the public constructor, a proxy instance
  87.122 + * can be also be created by calling the {@link Proxy#newProxyInstance
  87.123 + * Proxy.newProxyInstance} method, which combines the actions of calling
  87.124 + * {@link Proxy#getProxyClass Proxy.getProxyClass} with invoking the
  87.125 + * constructor with an invocation handler.
  87.126 + * </ul>
  87.127 + *
  87.128 + * <p>A proxy instance has the following properties:
  87.129 + *
  87.130 + * <ul>
  87.131 + * <li>Given a proxy instance {@code proxy} and one of the
  87.132 + * interfaces implemented by its proxy class {@code Foo}, the
  87.133 + * following expression will return true:
  87.134 + * <pre>
  87.135 + *     {@code proxy instanceof Foo}
  87.136 + * </pre>
  87.137 + * and the following cast operation will succeed (rather than throwing
  87.138 + * a {@code ClassCastException}):
  87.139 + * <pre>
  87.140 + *     {@code (Foo) proxy}
  87.141 + * </pre>
  87.142 + *
  87.143 + * <li>Each proxy instance has an associated invocation handler, the one
  87.144 + * that was passed to its constructor.  The static
  87.145 + * {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method
  87.146 + * will return the invocation handler associated with the proxy instance
  87.147 + * passed as its argument.
  87.148 + *
  87.149 + * <li>An interface method invocation on a proxy instance will be
  87.150 + * encoded and dispatched to the invocation handler's {@link
  87.151 + * InvocationHandler#invoke invoke} method as described in the
  87.152 + * documentation for that method.
  87.153 + *
  87.154 + * <li>An invocation of the {@code hashCode},
  87.155 + * {@code equals}, or {@code toString} methods declared in
  87.156 + * {@code java.lang.Object} on a proxy instance will be encoded and
  87.157 + * dispatched to the invocation handler's {@code invoke} method in
  87.158 + * the same manner as interface method invocations are encoded and
  87.159 + * dispatched, as described above.  The declaring class of the
  87.160 + * {@code Method} object passed to {@code invoke} will be
  87.161 + * {@code java.lang.Object}.  Other public methods of a proxy
  87.162 + * instance inherited from {@code java.lang.Object} are not
  87.163 + * overridden by a proxy class, so invocations of those methods behave
  87.164 + * like they do for instances of {@code java.lang.Object}.
  87.165 + * </ul>
  87.166 + *
  87.167 + * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
  87.168 + *
  87.169 + * <p>When two or more interfaces of a proxy class contain a method with
  87.170 + * the same name and parameter signature, the order of the proxy class's
  87.171 + * interfaces becomes significant.  When such a <i>duplicate method</i>
  87.172 + * is invoked on a proxy instance, the {@code Method} object passed
  87.173 + * to the invocation handler will not necessarily be the one whose
  87.174 + * declaring class is assignable from the reference type of the interface
  87.175 + * that the proxy's method was invoked through.  This limitation exists
  87.176 + * because the corresponding method implementation in the generated proxy
  87.177 + * class cannot determine which interface it was invoked through.
  87.178 + * Therefore, when a duplicate method is invoked on a proxy instance,
  87.179 + * the {@code Method} object for the method in the foremost interface
  87.180 + * that contains the method (either directly or inherited through a
  87.181 + * superinterface) in the proxy class's list of interfaces is passed to
  87.182 + * the invocation handler's {@code invoke} method, regardless of the
  87.183 + * reference type through which the method invocation occurred.
  87.184 + *
  87.185 + * <p>If a proxy interface contains a method with the same name and
  87.186 + * parameter signature as the {@code hashCode}, {@code equals},
  87.187 + * or {@code toString} methods of {@code java.lang.Object},
  87.188 + * when such a method is invoked on a proxy instance, the
  87.189 + * {@code Method} object passed to the invocation handler will have
  87.190 + * {@code java.lang.Object} as its declaring class.  In other words,
  87.191 + * the public, non-final methods of {@code java.lang.Object}
  87.192 + * logically precede all of the proxy interfaces for the determination of
  87.193 + * which {@code Method} object to pass to the invocation handler.
  87.194 + *
  87.195 + * <p>Note also that when a duplicate method is dispatched to an
  87.196 + * invocation handler, the {@code invoke} method may only throw
  87.197 + * checked exception types that are assignable to one of the exception
  87.198 + * types in the {@code throws} clause of the method in <i>all</i> of
  87.199 + * the proxy interfaces that it can be invoked through.  If the
  87.200 + * {@code invoke} method throws a checked exception that is not
  87.201 + * assignable to any of the exception types declared by the method in one
  87.202 + * of the proxy interfaces that it can be invoked through, then an
  87.203 + * unchecked {@code UndeclaredThrowableException} will be thrown by
  87.204 + * the invocation on the proxy instance.  This restriction means that not
  87.205 + * all of the exception types returned by invoking
  87.206 + * {@code getExceptionTypes} on the {@code Method} object
  87.207 + * passed to the {@code invoke} method can necessarily be thrown
  87.208 + * successfully by the {@code invoke} method.
  87.209 + *
  87.210 + * @author      Peter Jones
  87.211 + * @see         InvocationHandler
  87.212 + * @since       1.3
  87.213 + */
  87.214 +public class Proxy implements java.io.Serializable {
  87.215 +
  87.216 +    private static final long serialVersionUID = -2222568056686623797L;
  87.217 +
  87.218 +
  87.219 +
  87.220 +    /**
  87.221 +     * the invocation handler for this proxy instance.
  87.222 +     * @serial
  87.223 +     */
  87.224 +    protected InvocationHandler h;
  87.225 +
  87.226 +    /**
  87.227 +     * Prohibits instantiation.
  87.228 +     */
  87.229 +    private Proxy() {
  87.230 +    }
  87.231 +
  87.232 +    /**
  87.233 +     * Constructs a new {@code Proxy} instance from a subclass
  87.234 +     * (typically, a dynamic proxy class) with the specified value
  87.235 +     * for its invocation handler.
  87.236 +     *
  87.237 +     * @param   h the invocation handler for this proxy instance
  87.238 +     */
  87.239 +    protected Proxy(InvocationHandler h) {
  87.240 +        this.h = h;
  87.241 +    }
  87.242 +
  87.243 +    /**
  87.244 +     * Returns the {@code java.lang.Class} object for a proxy class
  87.245 +     * given a class loader and an array of interfaces.  The proxy class
  87.246 +     * will be defined by the specified class loader and will implement
  87.247 +     * all of the supplied interfaces.  If a proxy class for the same
  87.248 +     * permutation of interfaces has already been defined by the class
  87.249 +     * loader, then the existing proxy class will be returned; otherwise,
  87.250 +     * a proxy class for those interfaces will be generated dynamically
  87.251 +     * and defined by the class loader.
  87.252 +     *
  87.253 +     * <p>There are several restrictions on the parameters that may be
  87.254 +     * passed to {@code Proxy.getProxyClass}:
  87.255 +     *
  87.256 +     * <ul>
  87.257 +     * <li>All of the {@code Class} objects in the
  87.258 +     * {@code interfaces} array must represent interfaces, not
  87.259 +     * classes or primitive types.
  87.260 +     *
  87.261 +     * <li>No two elements in the {@code interfaces} array may
  87.262 +     * refer to identical {@code Class} objects.
  87.263 +     *
  87.264 +     * <li>All of the interface types must be visible by name through the
  87.265 +     * specified class loader.  In other words, for class loader
  87.266 +     * {@code cl} and every interface {@code i}, the following
  87.267 +     * expression must be true:
  87.268 +     * <pre>
  87.269 +     *     Class.forName(i.getName(), false, cl) == i
  87.270 +     * </pre>
  87.271 +     *
  87.272 +     * <li>All non-public interfaces must be in the same package;
  87.273 +     * otherwise, it would not be possible for the proxy class to
  87.274 +     * implement all of the interfaces, regardless of what package it is
  87.275 +     * defined in.
  87.276 +     *
  87.277 +     * <li>For any set of member methods of the specified interfaces
  87.278 +     * that have the same signature:
  87.279 +     * <ul>
  87.280 +     * <li>If the return type of any of the methods is a primitive
  87.281 +     * type or void, then all of the methods must have that same
  87.282 +     * return type.
  87.283 +     * <li>Otherwise, one of the methods must have a return type that
  87.284 +     * is assignable to all of the return types of the rest of the
  87.285 +     * methods.
  87.286 +     * </ul>
  87.287 +     *
  87.288 +     * <li>The resulting proxy class must not exceed any limits imposed
  87.289 +     * on classes by the virtual machine.  For example, the VM may limit
  87.290 +     * the number of interfaces that a class may implement to 65535; in
  87.291 +     * that case, the size of the {@code interfaces} array must not
  87.292 +     * exceed 65535.
  87.293 +     * </ul>
  87.294 +     *
  87.295 +     * <p>If any of these restrictions are violated,
  87.296 +     * {@code Proxy.getProxyClass} will throw an
  87.297 +     * {@code IllegalArgumentException}.  If the {@code interfaces}
  87.298 +     * array argument or any of its elements are {@code null}, a
  87.299 +     * {@code NullPointerException} will be thrown.
  87.300 +     *
  87.301 +     * <p>Note that the order of the specified proxy interfaces is
  87.302 +     * significant: two requests for a proxy class with the same combination
  87.303 +     * of interfaces but in a different order will result in two distinct
  87.304 +     * proxy classes.
  87.305 +     *
  87.306 +     * @param   loader the class loader to define the proxy class
  87.307 +     * @param   interfaces the list of interfaces for the proxy class
  87.308 +     *          to implement
  87.309 +     * @return  a proxy class that is defined in the specified class loader
  87.310 +     *          and that implements the specified interfaces
  87.311 +     * @throws  IllegalArgumentException if any of the restrictions on the
  87.312 +     *          parameters that may be passed to {@code getProxyClass}
  87.313 +     *          are violated
  87.314 +     * @throws  NullPointerException if the {@code interfaces} array
  87.315 +     *          argument or any of its elements are {@code null}
  87.316 +     */
  87.317 +    public static Class<?> getProxyClass(ClassLoader loader,
  87.318 +                                         Class<?>... interfaces)
  87.319 +        throws IllegalArgumentException
  87.320 +    {
  87.321 +        throw new IllegalArgumentException();
  87.322 +    }
  87.323 +
  87.324 +    /**
  87.325 +     * Returns an instance of a proxy class for the specified interfaces
  87.326 +     * that dispatches method invocations to the specified invocation
  87.327 +     * handler.  This method is equivalent to:
  87.328 +     * <pre>
  87.329 +     *     Proxy.getProxyClass(loader, interfaces).
  87.330 +     *         getConstructor(new Class[] { InvocationHandler.class }).
  87.331 +     *         newInstance(new Object[] { handler });
  87.332 +     * </pre>
  87.333 +     *
  87.334 +     * <p>{@code Proxy.newProxyInstance} throws
  87.335 +     * {@code IllegalArgumentException} for the same reasons that
  87.336 +     * {@code Proxy.getProxyClass} does.
  87.337 +     *
  87.338 +     * @param   loader the class loader to define the proxy class
  87.339 +     * @param   interfaces the list of interfaces for the proxy class
  87.340 +     *          to implement
  87.341 +     * @param   h the invocation handler to dispatch method invocations to
  87.342 +     * @return  a proxy instance with the specified invocation handler of a
  87.343 +     *          proxy class that is defined by the specified class loader
  87.344 +     *          and that implements the specified interfaces
  87.345 +     * @throws  IllegalArgumentException if any of the restrictions on the
  87.346 +     *          parameters that may be passed to {@code getProxyClass}
  87.347 +     *          are violated
  87.348 +     * @throws  NullPointerException if the {@code interfaces} array
  87.349 +     *          argument or any of its elements are {@code null}, or
  87.350 +     *          if the invocation handler, {@code h}, is
  87.351 +     *          {@code null}
  87.352 +     */
  87.353 +    public static Object newProxyInstance(ClassLoader loader,
  87.354 +                                          Class<?>[] interfaces,
  87.355 +                                          InvocationHandler h)
  87.356 +        throws IllegalArgumentException
  87.357 +    {
  87.358 +        if (h == null) {
  87.359 +            throw new NullPointerException();
  87.360 +        }
  87.361 +        throw new IllegalArgumentException();
  87.362 +    }
  87.363 +
  87.364 +    /**
  87.365 +     * Returns true if and only if the specified class was dynamically
  87.366 +     * generated to be a proxy class using the {@code getProxyClass}
  87.367 +     * method or the {@code newProxyInstance} method.
  87.368 +     *
  87.369 +     * <p>The reliability of this method is important for the ability
  87.370 +     * to use it to make security decisions, so its implementation should
  87.371 +     * not just test if the class in question extends {@code Proxy}.
  87.372 +     *
  87.373 +     * @param   cl the class to test
  87.374 +     * @return  {@code true} if the class is a proxy class and
  87.375 +     *          {@code false} otherwise
  87.376 +     * @throws  NullPointerException if {@code cl} is {@code null}
  87.377 +     */
  87.378 +    public static boolean isProxyClass(Class<?> cl) {
  87.379 +        if (cl == null) {
  87.380 +            throw new NullPointerException();
  87.381 +        }
  87.382 +
  87.383 +        return false;
  87.384 +    }
  87.385 +
  87.386 +    /**
  87.387 +     * Returns the invocation handler for the specified proxy instance.
  87.388 +     *
  87.389 +     * @param   proxy the proxy instance to return the invocation handler for
  87.390 +     * @return  the invocation handler for the proxy instance
  87.391 +     * @throws  IllegalArgumentException if the argument is not a
  87.392 +     *          proxy instance
  87.393 +     */
  87.394 +    public static InvocationHandler getInvocationHandler(Object proxy)
  87.395 +        throws IllegalArgumentException
  87.396 +    {
  87.397 +        /*
  87.398 +         * Verify that the object is actually a proxy instance.
  87.399 +         */
  87.400 +        if (!isProxyClass(proxy.getClass())) {
  87.401 +            throw new IllegalArgumentException("not a proxy instance");
  87.402 +        }
  87.403 +
  87.404 +        Proxy p = (Proxy) proxy;
  87.405 +        return p.h;
  87.406 +    }
  87.407 +
  87.408 +    private static native Class defineClass0(ClassLoader loader, String name,
  87.409 +                                             byte[] b, int off, int len);
  87.410 +}
    88.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.2 +++ b/emul/mini/src/main/java/java/lang/reflect/UndeclaredThrowableException.java	Tue Feb 05 17:04:22 2013 +0100
    88.3 @@ -0,0 +1,119 @@
    88.4 +/*
    88.5 + * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
    88.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    88.7 + *
    88.8 + * This code is free software; you can redistribute it and/or modify it
    88.9 + * under the terms of the GNU General Public License version 2 only, as
   88.10 + * published by the Free Software Foundation.  Oracle designates this
   88.11 + * particular file as subject to the "Classpath" exception as provided
   88.12 + * by Oracle in the LICENSE file that accompanied this code.
   88.13 + *
   88.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   88.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   88.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   88.17 + * version 2 for more details (a copy is included in the LICENSE file that
   88.18 + * accompanied this code).
   88.19 + *
   88.20 + * You should have received a copy of the GNU General Public License version
   88.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   88.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   88.23 + *
   88.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   88.25 + * or visit www.oracle.com if you need additional information or have any
   88.26 + * questions.
   88.27 + */
   88.28 +
   88.29 +package java.lang.reflect;
   88.30 +
   88.31 +/**
   88.32 + * Thrown by a method invocation on a proxy instance if its invocation
   88.33 + * handler's {@link InvocationHandler#invoke invoke} method throws a
   88.34 + * checked exception (a {@code Throwable} that is not assignable
   88.35 + * to {@code RuntimeException} or {@code Error}) that
   88.36 + * is not assignable to any of the exception types declared in the
   88.37 + * {@code throws} clause of the method that was invoked on the
   88.38 + * proxy instance and dispatched to the invocation handler.
   88.39 + *
   88.40 + * <p>An {@code UndeclaredThrowableException} instance contains
   88.41 + * the undeclared checked exception that was thrown by the invocation
   88.42 + * handler, and it can be retrieved with the
   88.43 + * {@code getUndeclaredThrowable()} method.
   88.44 + * {@code UndeclaredThrowableException} extends
   88.45 + * {@code RuntimeException}, so it is an unchecked exception
   88.46 + * that wraps a checked exception.
   88.47 + *
   88.48 + * <p>As of release 1.4, this exception has been retrofitted to
   88.49 + * conform to the general purpose exception-chaining mechanism.  The
   88.50 + * "undeclared checked exception that was thrown by the invocation
   88.51 + * handler" that may be provided at construction time and accessed via
   88.52 + * the {@link #getUndeclaredThrowable()} method is now known as the
   88.53 + * <i>cause</i>, and may be accessed via the {@link
   88.54 + * Throwable#getCause()} method, as well as the aforementioned "legacy
   88.55 + * method."
   88.56 + *
   88.57 + * @author      Peter Jones
   88.58 + * @see         InvocationHandler
   88.59 + * @since       1.3
   88.60 + */
   88.61 +public class UndeclaredThrowableException extends RuntimeException {
   88.62 +    static final long serialVersionUID = 330127114055056639L;
   88.63 +
   88.64 +    /**
   88.65 +     * the undeclared checked exception that was thrown
   88.66 +     * @serial
   88.67 +     */
   88.68 +    private Throwable undeclaredThrowable;
   88.69 +
   88.70 +    /**
   88.71 +     * Constructs an {@code UndeclaredThrowableException} with the
   88.72 +     * specified {@code Throwable}.
   88.73 +     *
   88.74 +     * @param   undeclaredThrowable the undeclared checked exception
   88.75 +     *          that was thrown
   88.76 +     */
   88.77 +    public UndeclaredThrowableException(Throwable undeclaredThrowable) {
   88.78 +        super((Throwable) null);  // Disallow initCause
   88.79 +        this.undeclaredThrowable = undeclaredThrowable;
   88.80 +    }
   88.81 +
   88.82 +    /**
   88.83 +     * Constructs an {@code UndeclaredThrowableException} with the
   88.84 +     * specified {@code Throwable} and a detail message.
   88.85 +     *
   88.86 +     * @param   undeclaredThrowable the undeclared checked exception
   88.87 +     *          that was thrown
   88.88 +     * @param   s the detail message
   88.89 +     */
   88.90 +    public UndeclaredThrowableException(Throwable undeclaredThrowable,
   88.91 +                                        String s)
   88.92 +    {
   88.93 +        super(s, null);  // Disallow initCause
   88.94 +        this.undeclaredThrowable = undeclaredThrowable;
   88.95 +    }
   88.96 +
   88.97 +    /**
   88.98 +     * Returns the {@code Throwable} instance wrapped in this
   88.99 +     * {@code UndeclaredThrowableException}, which may be {@code null}.
  88.100 +     *
  88.101 +     * <p>This method predates the general-purpose exception chaining facility.
  88.102 +     * The {@link Throwable#getCause()} method is now the preferred means of
  88.103 +     * obtaining this information.
  88.104 +     *
  88.105 +     * @return the undeclared checked exception that was thrown
  88.106 +     */
  88.107 +    public Throwable getUndeclaredThrowable() {
  88.108 +        return undeclaredThrowable;
  88.109 +    }
  88.110 +
  88.111 +    /**
  88.112 +     * Returns the cause of this exception (the {@code Throwable}
  88.113 +     * instance wrapped in this {@code UndeclaredThrowableException},
  88.114 +     * which may be {@code null}).
  88.115 +     *
  88.116 +     * @return  the cause of this exception.
  88.117 +     * @since   1.4
  88.118 +     */
  88.119 +    public Throwable getCause() {
  88.120 +        return undeclaredThrowable;
  88.121 +    }
  88.122 +}
    89.1 --- a/emul/mini/src/main/java/java/net/URL.java	Tue Feb 05 16:40:01 2013 +0100
    89.2 +++ b/emul/mini/src/main/java/java/net/URL.java	Tue Feb 05 17:04:22 2013 +0100
    89.3 @@ -25,6 +25,7 @@
    89.4  
    89.5  package java.net;
    89.6  
    89.7 +import java.io.ByteArrayInputStream;
    89.8  import java.io.IOException;
    89.9  import java.io.InputStream;
   89.10  import org.apidesign.bck2brwsr.core.JavaScriptBody;
   89.11 @@ -505,6 +506,17 @@
   89.12      public URL(URL context, String spec, URLStreamHandler handler)
   89.13          throws MalformedURLException
   89.14      {
   89.15 +        this(findContext(context), spec, handler != null);
   89.16 +    }
   89.17 +    
   89.18 +    private URL(URL context, String spec, boolean ishandler)
   89.19 +    throws MalformedURLException {
   89.20 +        // Check for permission to specify a handler
   89.21 +        if (ishandler) {
   89.22 +            throw new SecurityException();
   89.23 +        }
   89.24 +        URLStreamHandler handler = null;
   89.25 +        
   89.26          String original = spec;
   89.27          int i, limit, c;
   89.28          int start = 0;
   89.29 @@ -512,10 +524,6 @@
   89.30          boolean aRef=false;
   89.31          boolean isRelative = false;
   89.32  
   89.33 -        // Check for permission to specify a handler
   89.34 -        if (handler != null) {
   89.35 -            throw new SecurityException();
   89.36 -        }
   89.37  
   89.38          try {
   89.39              limit = spec.length();
   89.40 @@ -962,7 +970,11 @@
   89.41          if (is != null) {
   89.42              return is;
   89.43          }
   89.44 -        throw new IOException();
   89.45 +        byte[] arr = (byte[]) getContent(new Class[] { byte[].class });
   89.46 +        if (arr == null) {
   89.47 +            throw new IOException();
   89.48 +        }
   89.49 +        return new ByteArrayInputStream(arr);
   89.50      }
   89.51  
   89.52      /**
   89.53 @@ -987,6 +999,17 @@
   89.54      )
   89.55      private static native String loadText(String url) throws IOException;
   89.56  
   89.57 +    @JavaScriptBody(args = { "url", "arr" }, body = ""
   89.58 +        + "var request = new XMLHttpRequest();\n"
   89.59 +        + "request.open('GET', url, false);\n"
   89.60 +        + "request.overrideMimeType('text\\/plain; charset=x-user-defined');\n"
   89.61 +        + "request.send();\n"
   89.62 +        + "var t = request.responseText;\n"
   89.63 +        + "for (var i = 0; i < t.length; i++) arr.push(t.charCodeAt(i) & 0xff);\n"
   89.64 +        + "return arr;\n"
   89.65 +    )
   89.66 +    private static native Object loadBytes(String url, byte[] arr) throws IOException;
   89.67 +
   89.68      /**
   89.69       * Gets the contents of this URL. This method is a shorthand for:
   89.70       * <blockquote><pre>
   89.71 @@ -1005,7 +1028,10 @@
   89.72      throws java.io.IOException {
   89.73          for (Class<?> c : classes) {
   89.74              if (c == String.class) {
   89.75 -                return getContent();
   89.76 +                return loadText(toExternalForm());
   89.77 +            }
   89.78 +            if (c == byte[].class) {
   89.79 +                return loadBytes(toExternalForm(), new byte[0]);
   89.80              }
   89.81          }
   89.82          return null;
   89.83 @@ -1016,6 +1042,23 @@
   89.84          return universal;
   89.85      }
   89.86  
   89.87 +    private static URL findContext(URL context) throws MalformedURLException {
   89.88 +        if (context == null) {
   89.89 +            String base = findBaseURL();
   89.90 +            if (base != null) {
   89.91 +                context = new URL(null, base, false);
   89.92 +            }
   89.93 +        }
   89.94 +        return context;
   89.95 +    }
   89.96 +    
   89.97 +    @JavaScriptBody(args = {}, body = 
   89.98 +          "if (typeof window !== 'object') return null;\n"
   89.99 +        + "if (!window.location) return null;\n"
  89.100 +        + "if (!window.location.href) return null;\n"
  89.101 +        + "return window.location.href;\n"
  89.102 +    )
  89.103 +    private static native String findBaseURL();
  89.104  }
  89.105  class Parts {
  89.106      String path, query, ref;
    90.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    90.2 +++ b/emul/mini/src/main/java/java/util/zip/Adler32.java	Tue Feb 05 17:04:22 2013 +0100
    90.3 @@ -0,0 +1,205 @@
    90.4 +/* Adler32.java - Computes Adler32 data checksum of a data stream
    90.5 +   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
    90.6 +
    90.7 +This file is part of GNU Classpath.
    90.8 +
    90.9 +GNU Classpath is free software; you can redistribute it and/or modify
   90.10 +it under the terms of the GNU General Public License as published by
   90.11 +the Free Software Foundation; either version 2, or (at your option)
   90.12 +any later version.
   90.13 +
   90.14 +GNU Classpath is distributed in the hope that it will be useful, but
   90.15 +WITHOUT ANY WARRANTY; without even the implied warranty of
   90.16 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   90.17 +General Public License for more details.
   90.18 +
   90.19 +You should have received a copy of the GNU General Public License
   90.20 +along with GNU Classpath; see the file COPYING.  If not, write to the
   90.21 +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   90.22 +02111-1307 USA.
   90.23 +
   90.24 +Linking this library statically or dynamically with other modules is
   90.25 +making a combined work based on this library.  Thus, the terms and
   90.26 +conditions of the GNU General Public License cover the whole
   90.27 +combination.
   90.28 +
   90.29 +As a special exception, the copyright holders of this library give you
   90.30 +permission to link this library with independent modules to produce an
   90.31 +executable, regardless of the license terms of these independent
   90.32 +modules, and to copy and distribute the resulting executable under
   90.33 +terms of your choice, provided that you also meet, for each linked
   90.34 +independent module, the terms and conditions of the license of that
   90.35 +module.  An independent module is a module which is not derived from
   90.36 +or based on this library.  If you modify this library, you may extend
   90.37 +this exception to your version of the library, but you are not
   90.38 +obligated to do so.  If you do not wish to do so, delete this
   90.39 +exception statement from your version. */
   90.40 +
   90.41 +package java.util.zip;
   90.42 +
   90.43 +/*
   90.44 + * Written using on-line Java Platform 1.2 API Specification, as well
   90.45 + * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
   90.46 + * The actual Adler32 algorithm is taken from RFC 1950.
   90.47 + * Status:  Believed complete and correct.
   90.48 + */
   90.49 +
   90.50 +/**
   90.51 + * Computes Adler32 checksum for a stream of data. An Adler32 
   90.52 + * checksum is not as reliable as a CRC32 checksum, but a lot faster to 
   90.53 + * compute.
   90.54 + *<p>
   90.55 + * The specification for Adler32 may be found in RFC 1950.
   90.56 + * (ZLIB Compressed Data Format Specification version 3.3)
   90.57 + *<p>
   90.58 + *<p>
   90.59 + * From that document:
   90.60 + *<p>
   90.61 + *      "ADLER32 (Adler-32 checksum)
   90.62 + *       This contains a checksum value of the uncompressed data
   90.63 + *       (excluding any dictionary data) computed according to Adler-32
   90.64 + *       algorithm. This algorithm is a 32-bit extension and improvement
   90.65 + *       of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
   90.66 + *       standard. 
   90.67 + *<p>
   90.68 + *       Adler-32 is composed of two sums accumulated per byte: s1 is
   90.69 + *       the sum of all bytes, s2 is the sum of all s1 values. Both sums
   90.70 + *       are done modulo 65521. s1 is initialized to 1, s2 to zero.  The
   90.71 + *       Adler-32 checksum is stored as s2*65536 + s1 in most-
   90.72 + *       significant-byte first (network) order."
   90.73 + *<p>
   90.74 + * "8.2. The Adler-32 algorithm
   90.75 + *<p>
   90.76 + *    The Adler-32 algorithm is much faster than the CRC32 algorithm yet
   90.77 + *    still provides an extremely low probability of undetected errors.
   90.78 + *<p>
   90.79 + *    The modulo on unsigned long accumulators can be delayed for 5552
   90.80 + *    bytes, so the modulo operation time is negligible.  If the bytes
   90.81 + *    are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
   90.82 + *    and order sensitive, unlike the first sum, which is just a
   90.83 + *    checksum.  That 65521 is prime is important to avoid a possible
   90.84 + *    large class of two-byte errors that leave the check unchanged.
   90.85 + *    (The Fletcher checksum uses 255, which is not prime and which also
   90.86 + *    makes the Fletcher check insensitive to single byte changes 0 <->
   90.87 + *    255.)
   90.88 + *<p>
   90.89 + *    The sum s1 is initialized to 1 instead of zero to make the length
   90.90 + *    of the sequence part of s2, so that the length does not have to be
   90.91 + *   checked separately. (Any sequence of zeroes has a Fletcher
   90.92 + *    checksum of zero.)"
   90.93 + *
   90.94 + * @author John Leuner, Per Bothner
   90.95 + * @since JDK 1.1
   90.96 + *
   90.97 + * @see InflaterInputStream
   90.98 + * @see DeflaterOutputStream
   90.99 + */
  90.100 +public class Adler32 implements Checksum
  90.101 +{
  90.102 +
  90.103 +  /** largest prime smaller than 65536 */
  90.104 +  private static final int BASE = 65521;
  90.105 +
  90.106 +  private int checksum; //we do all in int.
  90.107 +
  90.108 +  //Note that java doesn't have unsigned integers,
  90.109 +  //so we have to be careful with what arithmetic 
  90.110 +  //we do. We return the checksum as a long to 
  90.111 +  //avoid sign confusion.
  90.112 +
  90.113 +  /**
  90.114 +   * Creates a new instance of the <code>Adler32</code> class. 
  90.115 +   * The checksum starts off with a value of 1. 
  90.116 +   */
  90.117 +  public Adler32 ()
  90.118 +  {
  90.119 +    reset();
  90.120 +  }
  90.121 +
  90.122 +  /**
  90.123 +   * Resets the Adler32 checksum to the initial value.
  90.124 +   */
  90.125 +  public void reset () 
  90.126 +  {
  90.127 +    checksum = 1; //Initialize to 1    
  90.128 +  }
  90.129 +
  90.130 +  /**
  90.131 +   * Updates the checksum with the byte b. 
  90.132 +   *
  90.133 +   * @param bval the data value to add. The high byte of the int is ignored.
  90.134 +   */
  90.135 +  public void update (int bval)
  90.136 +  {
  90.137 +    //We could make a length 1 byte array and call update again, but I
  90.138 +    //would rather not have that overhead
  90.139 +    int s1 = checksum & 0xffff;
  90.140 +    int s2 = checksum >>> 16;
  90.141 +    
  90.142 +    s1 = (s1 + (bval & 0xFF)) % BASE;
  90.143 +    s2 = (s1 + s2) % BASE;
  90.144 +    
  90.145 +    checksum = (s2 << 16) + s1;
  90.146 +  }
  90.147 +
  90.148 +  /**
  90.149 +   * Updates the checksum with the bytes taken from the array. 
  90.150 +   * 
  90.151 +   * @param buffer an array of bytes
  90.152 +   */
  90.153 +  public void update (byte[] buffer)
  90.154 +  {
  90.155 +    update(buffer, 0, buffer.length);
  90.156 +  }
  90.157 +
  90.158 +  /**
  90.159 +   * Updates the checksum with the bytes taken from the array. 
  90.160 +   * 
  90.161 +   * @param buf an array of bytes
  90.162 +   * @param off the start of the data used for this update
  90.163 +   * @param len the number of bytes to use for this update
  90.164 +   */
  90.165 +  public void update (byte[] buf, int off, int len)
  90.166 +  {
  90.167 +    //(By Per Bothner)
  90.168 +    int s1 = checksum & 0xffff;
  90.169 +    int s2 = checksum >>> 16;
  90.170 +
  90.171 +    while (len > 0)
  90.172 +      {
  90.173 +	// We can defer the modulo operation:
  90.174 +	// s1 maximally grows from 65521 to 65521 + 255 * 3800
  90.175 +	// s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31
  90.176 +	int n = 3800;
  90.177 +	if (n > len)
  90.178 +	  n = len;
  90.179 +	len -= n;
  90.180 +	while (--n >= 0)
  90.181 +	  {
  90.182 +	    s1 = s1 + (buf[off++] & 0xFF);
  90.183 +	    s2 = s2 + s1;
  90.184 +	  }
  90.185 +	s1 %= BASE;
  90.186 +	s2 %= BASE;
  90.187 +      }
  90.188 +
  90.189 +    /*Old implementation, borrowed from somewhere:
  90.190 +    int n;
  90.191 +    
  90.192 +    while (len-- > 0) {
  90.193 +
  90.194 +      s1 = (s1 + (bs[offset++] & 0xff)) % BASE; 
  90.195 +      s2 = (s2 + s1) % BASE;
  90.196 +    }*/
  90.197 +    
  90.198 +    checksum = (s2 << 16) | s1;
  90.199 +  }
  90.200 +
  90.201 +  /**
  90.202 +   * Returns the Adler32 data checksum computed so far.
  90.203 +   */
  90.204 +  public long getValue()
  90.205 +  {
  90.206 +    return (long) checksum & 0xffffffffL;
  90.207 +  }
  90.208 +}
    91.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    91.2 +++ b/emul/mini/src/main/java/java/util/zip/CRC32.java	Tue Feb 05 17:04:22 2013 +0100
    91.3 @@ -0,0 +1,132 @@
    91.4 +/* CRC32.java - Computes CRC32 data checksum of a data stream
    91.5 +   Copyright (C) 1999. 2000, 2001 Free Software Foundation, Inc.
    91.6 +
    91.7 +This file is part of GNU Classpath.
    91.8 +
    91.9 +GNU Classpath is free software; you can redistribute it and/or modify
   91.10 +it under the terms of the GNU General Public License as published by
   91.11 +the Free Software Foundation; either version 2, or (at your option)
   91.12 +any later version.
   91.13 +
   91.14 +GNU Classpath is distributed in the hope that it will be useful, but
   91.15 +WITHOUT ANY WARRANTY; without even the implied warranty of
   91.16 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   91.17 +General Public License for more details.
   91.18 +
   91.19 +You should have received a copy of the GNU General Public License
   91.20 +along with GNU Classpath; see the file COPYING.  If not, write to the
   91.21 +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   91.22 +02111-1307 USA.
   91.23 +
   91.24 +Linking this library statically or dynamically with other modules is
   91.25 +making a combined work based on this library.  Thus, the terms and
   91.26 +conditions of the GNU General Public License cover the whole
   91.27 +combination.
   91.28 +
   91.29 +As a special exception, the copyright holders of this library give you
   91.30 +permission to link this library with independent modules to produce an
   91.31 +executable, regardless of the license terms of these independent
   91.32 +modules, and to copy and distribute the resulting executable under
   91.33 +terms of your choice, provided that you also meet, for each linked
   91.34 +independent module, the terms and conditions of the license of that
   91.35 +module.  An independent module is a module which is not derived from
   91.36 +or based on this library.  If you modify this library, you may extend
   91.37 +this exception to your version of the library, but you are not
   91.38 +obligated to do so.  If you do not wish to do so, delete this
   91.39 +exception statement from your version. */
   91.40 +
   91.41 +package java.util.zip;
   91.42 +
   91.43 +/*
   91.44 + * Written using on-line Java Platform 1.2 API Specification, as well
   91.45 + * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
   91.46 + * The actual CRC32 algorithm is taken from RFC 1952.
   91.47 + * Status:  Believed complete and correct.
   91.48 + */
   91.49 +
   91.50 +/**
   91.51 + * Computes CRC32 data checksum of a data stream.
   91.52 + * The actual CRC32 algorithm is described in RFC 1952
   91.53 + * (GZIP file format specification version 4.3).
   91.54 + * Can be used to get the CRC32 over a stream if used with checked input/output
   91.55 + * streams.
   91.56 + *
   91.57 + * @see InflaterInputStream
   91.58 + * @see DeflaterOutputStream
   91.59 + *
   91.60 + * @author Per Bothner
   91.61 + * @date April 1, 1999.
   91.62 + */
   91.63 +public class CRC32 implements Checksum
   91.64 +{
   91.65 +  /** The crc data checksum so far. */
   91.66 +  private int crc = 0;
   91.67 +
   91.68 +  /** The fast CRC table. Computed once when the CRC32 class is loaded. */
   91.69 +  private static int[] crc_table = make_crc_table();
   91.70 +
   91.71 +  /** Make the table for a fast CRC. */
   91.72 +  private static int[] make_crc_table ()
   91.73 +  {
   91.74 +    int[] crc_table = new int[256];
   91.75 +    for (int n = 0; n < 256; n++)
   91.76 +      {
   91.77 +	int c = n;
   91.78 +	for (int k = 8;  --k >= 0; )
   91.79 +	  {
   91.80 +	    if ((c & 1) != 0)
   91.81 +	      c = 0xedb88320 ^ (c >>> 1);
   91.82 +	    else
   91.83 +	      c = c >>> 1;
   91.84 +	  }
   91.85 +	crc_table[n] = c;
   91.86 +      }
   91.87 +    return crc_table;
   91.88 +  }
   91.89 +
   91.90 +  /**
   91.91 +   * Returns the CRC32 data checksum computed so far.
   91.92 +   */
   91.93 +  public long getValue ()
   91.94 +  {
   91.95 +    return (long) crc & 0xffffffffL;
   91.96 +  }
   91.97 +
   91.98 +  /**
   91.99 +   * Resets the CRC32 data checksum as if no update was ever called.
  91.100 +   */
  91.101 +  public void reset () { crc = 0; }
  91.102 +
  91.103 +  /**
  91.104 +   * Updates the checksum with the int bval. 
  91.105 +   *
  91.106 +   * @param bval (the byte is taken as the lower 8 bits of bval)
  91.107 +   */
  91.108 +
  91.109 +  public void update (int bval)
  91.110 +  {
  91.111 +    int c = ~crc;
  91.112 +    c = crc_table[(c ^ bval) & 0xff] ^ (c >>> 8);
  91.113 +    crc = ~c;
  91.114 +  }
  91.115 +
  91.116 +  /**
  91.117 +   * Adds the byte array to the data checksum.
  91.118 +   *
  91.119 +   * @param buf the buffer which contains the data
  91.120 +   * @param off the offset in the buffer where the data starts
  91.121 +   * @param len the length of the data
  91.122 +   */
  91.123 +  public void update (byte[] buf, int off, int len)
  91.124 +  {
  91.125 +    int c = ~crc;
  91.126 +    while (--len >= 0)
  91.127 +      c = crc_table[(c ^ buf[off++]) & 0xff] ^ (c >>> 8);
  91.128 +    crc = ~c;
  91.129 +  }
  91.130 +
  91.131 +  /**
  91.132 +   * Adds the complete byte array to the data checksum.
  91.133 +   */
  91.134 +  public void update (byte[] buf) { update(buf, 0, buf.length); }
  91.135 +}
    92.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.2 +++ b/emul/mini/src/main/java/java/util/zip/Checksum.java	Tue Feb 05 17:04:22 2013 +0100
    92.3 @@ -0,0 +1,60 @@
    92.4 +/*
    92.5 + * Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved.
    92.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    92.7 + *
    92.8 + * This code is free software; you can redistribute it and/or modify it
    92.9 + * under the terms of the GNU General Public License version 2 only, as
   92.10 + * published by the Free Software Foundation.  Oracle designates this
   92.11 + * particular file as subject to the "Classpath" exception as provided
   92.12 + * by Oracle in the LICENSE file that accompanied this code.
   92.13 + *
   92.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   92.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   92.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   92.17 + * version 2 for more details (a copy is included in the LICENSE file that
   92.18 + * accompanied this code).
   92.19 + *
   92.20 + * You should have received a copy of the GNU General Public License version
   92.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   92.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   92.23 + *
   92.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   92.25 + * or visit www.oracle.com if you need additional information or have any
   92.26 + * questions.
   92.27 + */
   92.28 +
   92.29 +package java.util.zip;
   92.30 +
   92.31 +/**
   92.32 + * An interface representing a data checksum.
   92.33 + *
   92.34 + * @author      David Connelly
   92.35 + */
   92.36 +public
   92.37 +interface Checksum {
   92.38 +    /**
   92.39 +     * Updates the current checksum with the specified byte.
   92.40 +     *
   92.41 +     * @param b the byte to update the checksum with
   92.42 +     */
   92.43 +    public void update(int b);
   92.44 +
   92.45 +    /**
   92.46 +     * Updates the current checksum with the specified array of bytes.
   92.47 +     * @param b the byte array to update the checksum with
   92.48 +     * @param off the start offset of the data
   92.49 +     * @param len the number of bytes to use for the update
   92.50 +     */
   92.51 +    public void update(byte[] b, int off, int len);
   92.52 +
   92.53 +    /**
   92.54 +     * Returns the current checksum value.
   92.55 +     * @return the current checksum value
   92.56 +     */
   92.57 +    public long getValue();
   92.58 +
   92.59 +    /**
   92.60 +     * Resets the checksum to its initial value.
   92.61 +     */
   92.62 +    public void reset();
   92.63 +}
    93.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    93.2 +++ b/emul/mini/src/main/java/java/util/zip/DataFormatException.java	Tue Feb 05 17:04:22 2013 +0100
    93.3 @@ -0,0 +1,52 @@
    93.4 +/*
    93.5 + * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
    93.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    93.7 + *
    93.8 + * This code is free software; you can redistribute it and/or modify it
    93.9 + * under the terms of the GNU General Public License version 2 only, as
   93.10 + * published by the Free Software Foundation.  Oracle designates this
   93.11 + * particular file as subject to the "Classpath" exception as provided
   93.12 + * by Oracle in the LICENSE file that accompanied this code.
   93.13 + *
   93.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   93.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   93.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   93.17 + * version 2 for more details (a copy is included in the LICENSE file that
   93.18 + * accompanied this code).
   93.19 + *
   93.20 + * You should have received a copy of the GNU General Public License version
   93.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   93.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   93.23 + *
   93.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   93.25 + * or visit www.oracle.com if you need additional information or have any
   93.26 + * questions.
   93.27 + */
   93.28 +
   93.29 +package java.util.zip;
   93.30 +
   93.31 +/**
   93.32 + * Signals that a data format error has occurred.
   93.33 + *
   93.34 + * @author      David Connelly
   93.35 + */
   93.36 +public
   93.37 +class DataFormatException extends Exception {
   93.38 +    private static final long serialVersionUID = 2219632870893641452L;
   93.39 +
   93.40 +    /**
   93.41 +     * Constructs a DataFormatException with no detail message.
   93.42 +     */
   93.43 +    public DataFormatException() {
   93.44 +        super();
   93.45 +    }
   93.46 +
   93.47 +    /**
   93.48 +     * Constructs a DataFormatException with the specified detail message.
   93.49 +     * A detail message is a String that describes this particular exception.
   93.50 +     * @param s the String containing a detail message
   93.51 +     */
   93.52 +    public DataFormatException(String s) {
   93.53 +        super(s);
   93.54 +    }
   93.55 +}
    94.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.2 +++ b/emul/mini/src/main/java/java/util/zip/Inflater.java	Tue Feb 05 17:04:22 2013 +0100
    94.3 @@ -0,0 +1,1475 @@
    94.4 +/* Inflater.java - Decompress a data stream
    94.5 +   Copyright (C) 1999, 2000, 2001, 2003  Free Software Foundation, Inc.
    94.6 +
    94.7 +This file is part of GNU Classpath.
    94.8 +
    94.9 +GNU Classpath is free software; you can redistribute it and/or modify
   94.10 +it under the terms of the GNU General Public License as published by
   94.11 +the Free Software Foundation; either version 2, or (at your option)
   94.12 +any later version.
   94.13 + 
   94.14 +GNU Classpath is distributed in the hope that it will be useful, but
   94.15 +WITHOUT ANY WARRANTY; without even the implied warranty of
   94.16 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   94.17 +General Public License for more details.
   94.18 +
   94.19 +You should have received a copy of the GNU General Public License
   94.20 +along with GNU Classpath; see the file COPYING.  If not, write to the
   94.21 +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   94.22 +02111-1307 USA.
   94.23 +
   94.24 +Linking this library statically or dynamically with other modules is
   94.25 +making a combined work based on this library.  Thus, the terms and
   94.26 +conditions of the GNU General Public License cover the whole
   94.27 +combination.
   94.28 +
   94.29 +As a special exception, the copyright holders of this library give you
   94.30 +permission to link this library with independent modules to produce an
   94.31 +executable, regardless of the license terms of these independent
   94.32 +modules, and to copy and distribute the resulting executable under
   94.33 +terms of your choice, provided that you also meet, for each linked
   94.34 +independent module, the terms and conditions of the license of that
   94.35 +module.  An independent module is a module which is not derived from
   94.36 +or based on this library.  If you modify this library, you may extend
   94.37 +this exception to your version of the library, but you are not
   94.38 +obligated to do so.  If you do not wish to do so, delete this
   94.39 +exception statement from your version. */
   94.40 +
   94.41 +package java.util.zip;
   94.42 +
   94.43 +import org.apidesign.bck2brwsr.emul.lang.System;
   94.44 +
   94.45 +/**
   94.46 + * This class provides support for general purpose decompression using the
   94.47 + * popular ZLIB compression library. The ZLIB compression library was
   94.48 + * initially developed as part of the PNG graphics standard and is not
   94.49 + * protected by patents. It is fully described in the specifications at
   94.50 + * the <a href="package-summary.html#package_description">java.util.zip
   94.51 + * package description</a>.
   94.52 + *
   94.53 + * <p>The following code fragment demonstrates a trivial compression
   94.54 + * and decompression of a string using <tt>Deflater</tt> and
   94.55 + * <tt>Inflater</tt>.
   94.56 + *
   94.57 + * <blockquote><pre>
   94.58 + * try {
   94.59 + *     // Encode a String into bytes
   94.60 + *     String inputString = "blahblahblah\u20AC\u20AC";
   94.61 + *     byte[] input = inputString.getBytes("UTF-8");
   94.62 + *
   94.63 + *     // Compress the bytes
   94.64 + *     byte[] output = new byte[100];
   94.65 + *     Deflater compresser = new Deflater();
   94.66 + *     compresser.setInput(input);
   94.67 + *     compresser.finish();
   94.68 + *     int compressedDataLength = compresser.deflate(output);
   94.69 + *
   94.70 + *     // Decompress the bytes
   94.71 + *     Inflater decompresser = new Inflater();
   94.72 + *     decompresser.setInput(output, 0, compressedDataLength);
   94.73 + *     byte[] result = new byte[100];
   94.74 + *     int resultLength = decompresser.inflate(result);
   94.75 + *     decompresser.end();
   94.76 + *
   94.77 + *     // Decode the bytes into a String
   94.78 + *     String outputString = new String(result, 0, resultLength, "UTF-8");
   94.79 + * } catch(java.io.UnsupportedEncodingException ex) {
   94.80 + *     // handle
   94.81 + * } catch (java.util.zip.DataFormatException ex) {
   94.82 + *     // handle
   94.83 + * }
   94.84 + * </pre></blockquote>
   94.85 + *
   94.86 + * @see         Deflater
   94.87 + * @author      David Connelly
   94.88 + *
   94.89 + */
   94.90 +
   94.91 +/* Written using on-line Java Platform 1.2 API Specification
   94.92 + * and JCL book.
   94.93 + * Believed complete and correct.
   94.94 + */
   94.95 +
   94.96 +/**
   94.97 + * Inflater is used to decompress data that has been compressed according 
   94.98 + * to the "deflate" standard described in rfc1950.
   94.99 + *
  94.100 + * The usage is as following.  First you have to set some input with
  94.101 + * <code>setInput()</code>, then inflate() it.  If inflate doesn't
  94.102 + * inflate any bytes there may be three reasons:
  94.103 + * <ul>
  94.104 + * <li>needsInput() returns true because the input buffer is empty.
  94.105 + * You have to provide more input with <code>setInput()</code>.  
  94.106 + * NOTE: needsInput() also returns true when, the stream is finished.
  94.107 + * </li>
  94.108 + * <li>needsDictionary() returns true, you have to provide a preset 
  94.109 + *     dictionary with <code>setDictionary()</code>.</li>
  94.110 + * <li>finished() returns true, the inflater has finished.</li>
  94.111 + * </ul>
  94.112 + * Once the first output byte is produced, a dictionary will not be
  94.113 + * needed at a later stage.
  94.114 + *
  94.115 + * @author John Leuner, Jochen Hoenicke
  94.116 + * @author Tom Tromey
  94.117 + * @date May 17, 1999
  94.118 + * @since JDK 1.1
  94.119 + */
  94.120 +public class Inflater
  94.121 +{
  94.122 +  /* Copy lengths for literal codes 257..285 */
  94.123 +  private static final int CPLENS[] = 
  94.124 +  { 
  94.125 +    3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
  94.126 +    35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258
  94.127 +  };
  94.128 +  
  94.129 +  /* Extra bits for literal codes 257..285 */  
  94.130 +  private static final int CPLEXT[] = 
  94.131 +  { 
  94.132 +    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
  94.133 +    3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
  94.134 +  };
  94.135 +
  94.136 +  /* Copy offsets for distance codes 0..29 */
  94.137 +  private static final int CPDIST[] = {
  94.138 +    1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
  94.139 +    257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
  94.140 +    8193, 12289, 16385, 24577
  94.141 +  };
  94.142 +  
  94.143 +  /* Extra bits for distance codes */
  94.144 +  private static final int CPDEXT[] = {
  94.145 +    0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
  94.146 +    7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 
  94.147 +    12, 12, 13, 13
  94.148 +  };
  94.149 +
  94.150 +  /* This are the state in which the inflater can be.  */
  94.151 +  private static final int DECODE_HEADER           = 0;
  94.152 +  private static final int DECODE_DICT             = 1;
  94.153 +  private static final int DECODE_BLOCKS           = 2;
  94.154 +  private static final int DECODE_STORED_LEN1      = 3;
  94.155 +  private static final int DECODE_STORED_LEN2      = 4;
  94.156 +  private static final int DECODE_STORED           = 5;
  94.157 +  private static final int DECODE_DYN_HEADER       = 6;
  94.158 +  private static final int DECODE_HUFFMAN          = 7;
  94.159 +  private static final int DECODE_HUFFMAN_LENBITS  = 8;
  94.160 +  private static final int DECODE_HUFFMAN_DIST     = 9;
  94.161 +  private static final int DECODE_HUFFMAN_DISTBITS = 10;
  94.162 +  private static final int DECODE_CHKSUM           = 11;
  94.163 +  private static final int FINISHED                = 12;
  94.164 +
  94.165 +  /** This variable contains the current state. */
  94.166 +  private int mode;
  94.167 +
  94.168 +  /**
  94.169 +   * The adler checksum of the dictionary or of the decompressed
  94.170 +   * stream, as it is written in the header resp. footer of the
  94.171 +   * compressed stream.  <br>
  94.172 +   *
  94.173 +   * Only valid if mode is DECODE_DICT or DECODE_CHKSUM.
  94.174 +   */
  94.175 +  private int readAdler;
  94.176 +  /** 
  94.177 +   * The number of bits needed to complete the current state.  This
  94.178 +   * is valid, if mode is DECODE_DICT, DECODE_CHKSUM,
  94.179 +   * DECODE_HUFFMAN_LENBITS or DECODE_HUFFMAN_DISTBITS.  
  94.180 +   */
  94.181 +  private int neededBits;
  94.182 +  private int repLength, repDist;
  94.183 +  private int uncomprLen;
  94.184 +  /**
  94.185 +   * True, if the last block flag was set in the last block of the
  94.186 +   * inflated stream.  This means that the stream ends after the
  94.187 +   * current block.  
  94.188 +   */
  94.189 +  private boolean isLastBlock;
  94.190 +
  94.191 +  /**
  94.192 +   * The total number of inflated bytes.
  94.193 +   */
  94.194 +  private long totalOut;
  94.195 +  /**
  94.196 +   * The total number of bytes set with setInput().  This is not the
  94.197 +   * value returned by getTotalIn(), since this also includes the 
  94.198 +   * unprocessed input.
  94.199 +   */
  94.200 +  private long totalIn;
  94.201 +  /**
  94.202 +   * This variable stores the nowrap flag that was given to the constructor.
  94.203 +   * True means, that the inflated stream doesn't contain a header nor the
  94.204 +   * checksum in the footer.
  94.205 +   */
  94.206 +  private boolean nowrap;
  94.207 +
  94.208 +  private StreamManipulator input;
  94.209 +  private OutputWindow outputWindow;
  94.210 +  private InflaterDynHeader dynHeader;
  94.211 +  private InflaterHuffmanTree litlenTree, distTree;
  94.212 +  private Adler32 adler;
  94.213 +
  94.214 +  /**
  94.215 +   * Creates a new inflater.
  94.216 +   */
  94.217 +  public Inflater ()
  94.218 +  {
  94.219 +    this (false);
  94.220 +  }
  94.221 +
  94.222 +  /**
  94.223 +   * Creates a new inflater.
  94.224 +   * @param nowrap true if no header and checksum field appears in the
  94.225 +   * stream.  This is used for GZIPed input.  For compatibility with
  94.226 +   * Sun JDK you should provide one byte of input more than needed in
  94.227 +   * this case.
  94.228 +   */
  94.229 +  public Inflater (boolean nowrap)
  94.230 +  {
  94.231 +    this.nowrap = nowrap;
  94.232 +    this.adler = new Adler32();
  94.233 +    input = new StreamManipulator();
  94.234 +    outputWindow = new OutputWindow();
  94.235 +    mode = nowrap ? DECODE_BLOCKS : DECODE_HEADER;
  94.236 +  }
  94.237 +
  94.238 +  /**
  94.239 +   * Finalizes this object.
  94.240 +   */
  94.241 +  protected void finalize ()
  94.242 +  {
  94.243 +    /* Exists only for compatibility */
  94.244 +  }
  94.245 +
  94.246 +  /**
  94.247 +   * Frees all objects allocated by the inflater.  There's no reason
  94.248 +   * to call this, since you can just rely on garbage collection (even
  94.249 +   * for the Sun implementation).  Exists only for compatibility
  94.250 +   * with Sun's JDK, where the compressor allocates native memory.
  94.251 +   * If you call any method (even reset) afterwards the behaviour is
  94.252 +   * <i>undefined</i>.  
  94.253 +   * @deprecated Just clear all references to inflater instead.
  94.254 +   */
  94.255 +  public void end ()
  94.256 +  {
  94.257 +    outputWindow = null;
  94.258 +    input = null;
  94.259 +    dynHeader = null;
  94.260 +    litlenTree = null;
  94.261 +    distTree = null;
  94.262 +    adler = null;
  94.263 +  }
  94.264 +
  94.265 +  /**
  94.266 +   * Returns true, if the inflater has finished.  This means, that no
  94.267 +   * input is needed and no output can be produced.
  94.268 +   */
  94.269 +  public boolean finished() 
  94.270 +  {
  94.271 +    return mode == FINISHED && outputWindow.getAvailable() == 0;
  94.272 +  }
  94.273 +
  94.274 +  /**
  94.275 +   * Gets the adler checksum.  This is either the checksum of all
  94.276 +   * uncompressed bytes returned by inflate(), or if needsDictionary()
  94.277 +   * returns true (and thus no output was yet produced) this is the
  94.278 +   * adler checksum of the expected dictionary.
  94.279 +   * @returns the adler checksum.
  94.280 +   */
  94.281 +  public int getAdler()
  94.282 +  {
  94.283 +    return needsDictionary() ? readAdler : (int) adler.getValue();
  94.284 +  }
  94.285 +  
  94.286 +  /**
  94.287 +   * Gets the number of unprocessed input.  Useful, if the end of the
  94.288 +   * stream is reached and you want to further process the bytes after
  94.289 +   * the deflate stream.  
  94.290 +   * @return the number of bytes of the input which were not processed.
  94.291 +   */
  94.292 +  public int getRemaining()
  94.293 +  {
  94.294 +    return input.getAvailableBytes();
  94.295 +  }
  94.296 +  
  94.297 +  /**
  94.298 +   * Gets the total number of processed compressed input bytes.
  94.299 +   * @return the total number of bytes of processed input bytes.
  94.300 +   */
  94.301 +  public int getTotalIn()
  94.302 +  {
  94.303 +    return (int)getBytesRead();
  94.304 +  }
  94.305 +  
  94.306 +  /**
  94.307 +   * Gets the total number of output bytes returned by inflate().
  94.308 +   * @return the total number of output bytes.
  94.309 +   */
  94.310 +  public int getTotalOut()
  94.311 +  {
  94.312 +    return (int)totalOut;
  94.313 +  }
  94.314 +  
  94.315 +  public long getBytesWritten() {
  94.316 +     return totalOut;
  94.317 +  }
  94.318 +
  94.319 +  public long getBytesRead() {
  94.320 +    return totalIn - getRemaining();
  94.321 +  }
  94.322 +  
  94.323 +
  94.324 +  /**
  94.325 +   * Inflates the compressed stream to the output buffer.  If this
  94.326 +   * returns 0, you should check, whether needsDictionary(),
  94.327 +   * needsInput() or finished() returns true, to determine why no 
  94.328 +   * further output is produced.
  94.329 +   * @param buffer the output buffer.
  94.330 +   * @return the number of bytes written to the buffer, 0 if no further
  94.331 +   * output can be produced.  
  94.332 +   * @exception DataFormatException if deflated stream is invalid.
  94.333 +   * @exception IllegalArgumentException if buf has length 0.
  94.334 +   */
  94.335 +  public int inflate (byte[] buf) throws DataFormatException
  94.336 +  {
  94.337 +    return inflate (buf, 0, buf.length);
  94.338 +  }
  94.339 +
  94.340 +  /**
  94.341 +   * Inflates the compressed stream to the output buffer.  If this
  94.342 +   * returns 0, you should check, whether needsDictionary(),
  94.343 +   * needsInput() or finished() returns true, to determine why no 
  94.344 +   * further output is produced.
  94.345 +   * @param buffer the output buffer.
  94.346 +   * @param off the offset into buffer where the output should start.
  94.347 +   * @param len the maximum length of the output.
  94.348 +   * @return the number of bytes written to the buffer, 0 if no further
  94.349 +   * output can be produced.  
  94.350 +   * @exception DataFormatException if deflated stream is invalid.
  94.351 +   * @exception IndexOutOfBoundsException if the off and/or len are wrong.
  94.352 +   */
  94.353 +  public int inflate (byte[] buf, int off, int len) throws DataFormatException
  94.354 +  {
  94.355 +    /* Special case: len may be zero */
  94.356 +    if (len == 0)
  94.357 +      return 0;
  94.358 +    /* Check for correct buff, off, len triple */
  94.359 +    if (0 > off || off > off + len || off + len > buf.length)
  94.360 +      throw new ArrayIndexOutOfBoundsException();
  94.361 +    int count = 0;
  94.362 +    int more;
  94.363 +    do
  94.364 +      {
  94.365 +	if (mode != DECODE_CHKSUM)
  94.366 +	  {
  94.367 +	    /* Don't give away any output, if we are waiting for the
  94.368 +	     * checksum in the input stream.
  94.369 +	     *
  94.370 +	     * With this trick we have always:
  94.371 +	     *   needsInput() and not finished() 
  94.372 +	     *   implies more output can be produced.  
  94.373 +	     */
  94.374 +	    more = outputWindow.copyOutput(buf, off, len);
  94.375 +	    adler.update(buf, off, more);
  94.376 +	    off += more;
  94.377 +	    count += more;
  94.378 +	    totalOut += more;
  94.379 +	    len -= more;
  94.380 +	    if (len == 0)
  94.381 +	      return count;
  94.382 +	  }
  94.383 +      }
  94.384 +    while (decode() || (outputWindow.getAvailable() > 0
  94.385 +			&& mode != DECODE_CHKSUM));
  94.386 +    return count;
  94.387 +  }
  94.388 +
  94.389 +  /**
  94.390 +   * Returns true, if a preset dictionary is needed to inflate the input.
  94.391 +   */
  94.392 +  public boolean needsDictionary ()
  94.393 +  {
  94.394 +    return mode == DECODE_DICT && neededBits == 0;
  94.395 +  }
  94.396 +
  94.397 +  /**
  94.398 +   * Returns true, if the input buffer is empty.
  94.399 +   * You should then call setInput(). <br>
  94.400 +   *
  94.401 +   * <em>NOTE</em>: This method also returns true when the stream is finished.
  94.402 +   */
  94.403 +  public boolean needsInput () 
  94.404 +  {
  94.405 +    return input.needsInput ();
  94.406 +  }
  94.407 +
  94.408 +  /**
  94.409 +   * Resets the inflater so that a new stream can be decompressed.  All
  94.410 +   * pending input and output will be discarded.
  94.411 +   */
  94.412 +  public void reset ()
  94.413 +  {
  94.414 +    mode = nowrap ? DECODE_BLOCKS : DECODE_HEADER;
  94.415 +    totalIn = totalOut = 0;
  94.416 +    input.reset();
  94.417 +    outputWindow.reset();
  94.418 +    dynHeader = null;
  94.419 +    litlenTree = null;
  94.420 +    distTree = null;
  94.421 +    isLastBlock = false;
  94.422 +    adler.reset();
  94.423 +  }
  94.424 +
  94.425 +  /**
  94.426 +   * Sets the preset dictionary.  This should only be called, if
  94.427 +   * needsDictionary() returns true and it should set the same
  94.428 +   * dictionary, that was used for deflating.  The getAdler()
  94.429 +   * function returns the checksum of the dictionary needed.
  94.430 +   * @param buffer the dictionary.
  94.431 +   * @exception IllegalStateException if no dictionary is needed.
  94.432 +   * @exception IllegalArgumentException if the dictionary checksum is
  94.433 +   * wrong.  
  94.434 +   */
  94.435 +  public void setDictionary (byte[] buffer)
  94.436 +  {
  94.437 +    setDictionary(buffer, 0, buffer.length);
  94.438 +  }
  94.439 +
  94.440 +  /**
  94.441 +   * Sets the preset dictionary.  This should only be called, if
  94.442 +   * needsDictionary() returns true and it should set the same
  94.443 +   * dictionary, that was used for deflating.  The getAdler()
  94.444 +   * function returns the checksum of the dictionary needed.
  94.445 +   * @param buffer the dictionary.
  94.446 +   * @param off the offset into buffer where the dictionary starts.
  94.447 +   * @param len the length of the dictionary.
  94.448 +   * @exception IllegalStateException if no dictionary is needed.
  94.449 +   * @exception IllegalArgumentException if the dictionary checksum is
  94.450 +   * wrong.  
  94.451 +   * @exception IndexOutOfBoundsException if the off and/or len are wrong.
  94.452 +   */
  94.453 +  public void setDictionary (byte[] buffer, int off, int len)
  94.454 +  {
  94.455 +    if (!needsDictionary())
  94.456 +      throw new IllegalStateException();
  94.457 +
  94.458 +    adler.update(buffer, off, len);
  94.459 +    if ((int) adler.getValue() != readAdler)
  94.460 +      throw new IllegalArgumentException("Wrong adler checksum");
  94.461 +    adler.reset();
  94.462 +    outputWindow.copyDict(buffer, off, len);
  94.463 +    mode = DECODE_BLOCKS;
  94.464 +  }
  94.465 +
  94.466 +  /**
  94.467 +   * Sets the input.  This should only be called, if needsInput()
  94.468 +   * returns true.
  94.469 +   * @param buffer the input.
  94.470 +   * @exception IllegalStateException if no input is needed.
  94.471 +   */
  94.472 +  public void setInput (byte[] buf) 
  94.473 +  {
  94.474 +    setInput (buf, 0, buf.length);
  94.475 +  }
  94.476 +
  94.477 +  /**
  94.478 +   * Sets the input.  This should only be called, if needsInput()
  94.479 +   * returns true.
  94.480 +   * @param buffer the input.
  94.481 +   * @param off the offset into buffer where the input starts.
  94.482 +   * @param len the length of the input.  
  94.483 +   * @exception IllegalStateException if no input is needed.
  94.484 +   * @exception IndexOutOfBoundsException if the off and/or len are wrong.
  94.485 +   */
  94.486 +  public void setInput (byte[] buf, int off, int len) 
  94.487 +  {
  94.488 +    input.setInput (buf, off, len);
  94.489 +    totalIn += len;
  94.490 +  }
  94.491 +  private static final int DEFLATED = 8;
  94.492 +  /**
  94.493 +   * Decodes the deflate header.
  94.494 +   * @return false if more input is needed. 
  94.495 +   * @exception DataFormatException if header is invalid.
  94.496 +   */
  94.497 +  private boolean decodeHeader () throws DataFormatException
  94.498 +  {
  94.499 +    int header = input.peekBits(16);
  94.500 +    if (header < 0)
  94.501 +      return false;
  94.502 +    input.dropBits(16);
  94.503 +    
  94.504 +    /* The header is written in "wrong" byte order */
  94.505 +    header = ((header << 8) | (header >> 8)) & 0xffff;
  94.506 +    if (header % 31 != 0)
  94.507 +      throw new DataFormatException("Header checksum illegal");
  94.508 +    
  94.509 +    if ((header & 0x0f00) != (DEFLATED << 8))
  94.510 +      throw new DataFormatException("Compression Method unknown");
  94.511 +
  94.512 +    /* Maximum size of the backwards window in bits. 
  94.513 +     * We currently ignore this, but we could use it to make the
  94.514 +     * inflater window more space efficient. On the other hand the
  94.515 +     * full window (15 bits) is needed most times, anyway.
  94.516 +     int max_wbits = ((header & 0x7000) >> 12) + 8;
  94.517 +     */
  94.518 +    
  94.519 +    if ((header & 0x0020) == 0) // Dictionary flag?
  94.520 +      {
  94.521 +	mode = DECODE_BLOCKS;
  94.522 +      }
  94.523 +    else
  94.524 +      {
  94.525 +	mode = DECODE_DICT;
  94.526 +	neededBits = 32;      
  94.527 +      }
  94.528 +    return true;
  94.529 +  }
  94.530 +   
  94.531 +  /**
  94.532 +   * Decodes the dictionary checksum after the deflate header.
  94.533 +   * @return false if more input is needed. 
  94.534 +   */
  94.535 +  private boolean decodeDict ()
  94.536 +  {
  94.537 +    while (neededBits > 0)
  94.538 +      {
  94.539 +	int dictByte = input.peekBits(8);
  94.540 +	if (dictByte < 0)
  94.541 +	  return false;
  94.542 +	input.dropBits(8);
  94.543 +	readAdler = (readAdler << 8) | dictByte;
  94.544 +	neededBits -= 8;
  94.545 +      }
  94.546 +    return false;
  94.547 +  }
  94.548 +
  94.549 +  /**
  94.550 +   * Decodes the huffman encoded symbols in the input stream.
  94.551 +   * @return false if more input is needed, true if output window is
  94.552 +   * full or the current block ends.
  94.553 +   * @exception DataFormatException if deflated stream is invalid.  
  94.554 +   */
  94.555 +  private boolean decodeHuffman () throws DataFormatException
  94.556 +  {
  94.557 +    int free = outputWindow.getFreeSpace();
  94.558 +    while (free >= 258)
  94.559 +      {
  94.560 +	int symbol;
  94.561 +	switch (mode)
  94.562 +	  {
  94.563 +	  case DECODE_HUFFMAN:
  94.564 +	    /* This is the inner loop so it is optimized a bit */
  94.565 +	    while (((symbol = litlenTree.getSymbol(input)) & ~0xff) == 0)
  94.566 +	      {
  94.567 +		outputWindow.write(symbol);
  94.568 +		if (--free < 258)
  94.569 +		  return true;
  94.570 +	      } 
  94.571 +	    if (symbol < 257)
  94.572 +	      {
  94.573 +		if (symbol < 0)
  94.574 +		  return false;
  94.575 +		else
  94.576 +		  {
  94.577 +		    /* symbol == 256: end of block */
  94.578 +		    distTree = null;
  94.579 +		    litlenTree = null;
  94.580 +		    mode = DECODE_BLOCKS;
  94.581 +		    return true;
  94.582 +		  }
  94.583 +	      }
  94.584 +		
  94.585 +	    try
  94.586 +	      {
  94.587 +		repLength = CPLENS[symbol - 257];
  94.588 +		neededBits = CPLEXT[symbol - 257];
  94.589 +	      }
  94.590 +	    catch (ArrayIndexOutOfBoundsException ex)
  94.591 +	      {
  94.592 +		throw new DataFormatException("Illegal rep length code");
  94.593 +	      }
  94.594 +	    /* fall through */
  94.595 +	  case DECODE_HUFFMAN_LENBITS:
  94.596 +	    if (neededBits > 0)
  94.597 +	      {
  94.598 +		mode = DECODE_HUFFMAN_LENBITS;
  94.599 +		int i = input.peekBits(neededBits);
  94.600 +		if (i < 0)
  94.601 +		  return false;
  94.602 +		input.dropBits(neededBits);
  94.603 +		repLength += i;
  94.604 +	      }
  94.605 +	    mode = DECODE_HUFFMAN_DIST;
  94.606 +	    /* fall through */
  94.607 +	  case DECODE_HUFFMAN_DIST:
  94.608 +	    symbol = distTree.getSymbol(input);
  94.609 +	    if (symbol < 0)
  94.610 +	      return false;
  94.611 +	    try 
  94.612 +	      {
  94.613 +		repDist = CPDIST[symbol];
  94.614 +		neededBits = CPDEXT[symbol];
  94.615 +	      }
  94.616 +	    catch (ArrayIndexOutOfBoundsException ex)
  94.617 +	      {
  94.618 +		throw new DataFormatException("Illegal rep dist code");
  94.619 +	      }
  94.620 +	    /* fall through */
  94.621 +	  case DECODE_HUFFMAN_DISTBITS:
  94.622 +	    if (neededBits > 0)
  94.623 +	      {
  94.624 +		mode = DECODE_HUFFMAN_DISTBITS;
  94.625 +		int i = input.peekBits(neededBits);
  94.626 +		if (i < 0)
  94.627 +		  return false;
  94.628 +		input.dropBits(neededBits);
  94.629 +		repDist += i;
  94.630 +	      }
  94.631 +	    outputWindow.repeat(repLength, repDist);
  94.632 +	    free -= repLength;
  94.633 +	    mode = DECODE_HUFFMAN;
  94.634 +	    break;
  94.635 +	  default:
  94.636 +	    throw new IllegalStateException();
  94.637 +	  }
  94.638 +      }
  94.639 +    return true;
  94.640 +  }
  94.641 +
  94.642 +  /**
  94.643 +   * Decodes the adler checksum after the deflate stream.
  94.644 +   * @return false if more input is needed. 
  94.645 +   * @exception DataFormatException if checksum doesn't match.
  94.646 +   */
  94.647 +  private boolean decodeChksum () throws DataFormatException
  94.648 +  {
  94.649 +    while (neededBits > 0)
  94.650 +      {
  94.651 +	int chkByte = input.peekBits(8);
  94.652 +	if (chkByte < 0)
  94.653 +	  return false;
  94.654 +	input.dropBits(8);
  94.655 +	readAdler = (readAdler << 8) | chkByte;
  94.656 +	neededBits -= 8;
  94.657 +      }
  94.658 +    if ((int) adler.getValue() != readAdler)
  94.659 +      throw new DataFormatException("Adler chksum doesn't match: "
  94.660 +				    +Integer.toHexString((int)adler.getValue())
  94.661 +				    +" vs. "+Integer.toHexString(readAdler));
  94.662 +    mode = FINISHED;
  94.663 +    return false;
  94.664 +  }
  94.665 +
  94.666 +  /**
  94.667 +   * Decodes the deflated stream.
  94.668 +   * @return false if more input is needed, or if finished. 
  94.669 +   * @exception DataFormatException if deflated stream is invalid.
  94.670 +   */
  94.671 +  private boolean decode () throws DataFormatException
  94.672 +  {
  94.673 +    switch (mode) 
  94.674 +      {
  94.675 +      case DECODE_HEADER:
  94.676 +	return decodeHeader();
  94.677 +      case DECODE_DICT:
  94.678 +	return decodeDict();
  94.679 +      case DECODE_CHKSUM:
  94.680 +	return decodeChksum();
  94.681 +
  94.682 +      case DECODE_BLOCKS:
  94.683 +	if (isLastBlock)
  94.684 +	  {
  94.685 +	    if (nowrap)
  94.686 +	      {
  94.687 +		mode = FINISHED;
  94.688 +		return false;
  94.689 +	      }
  94.690 +	    else
  94.691 +	      {
  94.692 +		input.skipToByteBoundary();
  94.693 +		neededBits = 32;
  94.694 +		mode = DECODE_CHKSUM;
  94.695 +		return true;
  94.696 +	      }
  94.697 +	  }
  94.698 +
  94.699 +	int type = input.peekBits(3);
  94.700 +	if (type < 0)
  94.701 +	  return false;
  94.702 +	input.dropBits(3);
  94.703 +
  94.704 +	if ((type & 1) != 0)
  94.705 +	  isLastBlock = true;
  94.706 +	switch (type >> 1)
  94.707 +	  {
  94.708 +	  case DeflaterConstants.STORED_BLOCK:
  94.709 +	    input.skipToByteBoundary();
  94.710 +	    mode = DECODE_STORED_LEN1;
  94.711 +	    break;
  94.712 +	  case DeflaterConstants.STATIC_TREES:
  94.713 +	    litlenTree = InflaterHuffmanTree.defLitLenTree;
  94.714 +	    distTree = InflaterHuffmanTree.defDistTree;
  94.715 +	    mode = DECODE_HUFFMAN;
  94.716 +	    break;
  94.717 +	  case DeflaterConstants.DYN_TREES:
  94.718 +	    dynHeader = new InflaterDynHeader();
  94.719 +	    mode = DECODE_DYN_HEADER;
  94.720 +	    break;
  94.721 +	  default:
  94.722 +	    throw new DataFormatException("Unknown block type "+type);
  94.723 +	  }
  94.724 +	return true;
  94.725 +
  94.726 +      case DECODE_STORED_LEN1:
  94.727 +	{
  94.728 +	  if ((uncomprLen = input.peekBits(16)) < 0)
  94.729 +	    return false;
  94.730 +	  input.dropBits(16);
  94.731 +	  mode = DECODE_STORED_LEN2;
  94.732 +	}
  94.733 +	/* fall through */
  94.734 +      case DECODE_STORED_LEN2:
  94.735 +	{
  94.736 +	  int nlen = input.peekBits(16);
  94.737 +	  if (nlen < 0)
  94.738 +	    return false;
  94.739 +	  input.dropBits(16);
  94.740 +	  if (nlen != (uncomprLen ^ 0xffff))
  94.741 +	    throw new DataFormatException("broken uncompressed block");
  94.742 +	  mode = DECODE_STORED;
  94.743 +	}
  94.744 +	/* fall through */
  94.745 +      case DECODE_STORED:
  94.746 +	{
  94.747 +	  int more = outputWindow.copyStored(input, uncomprLen);
  94.748 +	  uncomprLen -= more;
  94.749 +	  if (uncomprLen == 0)
  94.750 +	    {
  94.751 +	      mode = DECODE_BLOCKS;
  94.752 +	      return true;
  94.753 +	    }
  94.754 +	  return !input.needsInput();
  94.755 +	}
  94.756 +
  94.757 +      case DECODE_DYN_HEADER:
  94.758 +	if (!dynHeader.decode(input))
  94.759 +	  return false;
  94.760 +	litlenTree = dynHeader.buildLitLenTree();
  94.761 +	distTree = dynHeader.buildDistTree();
  94.762 +	mode = DECODE_HUFFMAN;
  94.763 +	/* fall through */
  94.764 +      case DECODE_HUFFMAN:
  94.765 +      case DECODE_HUFFMAN_LENBITS:
  94.766 +      case DECODE_HUFFMAN_DIST:
  94.767 +      case DECODE_HUFFMAN_DISTBITS:
  94.768 +	return decodeHuffman();
  94.769 +      case FINISHED:
  94.770 +	return false;
  94.771 +      default:
  94.772 +	throw new IllegalStateException();
  94.773 +      }	
  94.774 +  }
  94.775 +
  94.776 +
  94.777 +    interface DeflaterConstants {
  94.778 +      final static boolean DEBUGGING = false;
  94.779 +
  94.780 +      final static int STORED_BLOCK = 0;
  94.781 +      final static int STATIC_TREES = 1;
  94.782 +      final static int DYN_TREES    = 2;
  94.783 +      final static int PRESET_DICT  = 0x20;
  94.784 +
  94.785 +      final static int DEFAULT_MEM_LEVEL = 8;
  94.786 +
  94.787 +      final static int MAX_MATCH = 258;
  94.788 +      final static int MIN_MATCH = 3;
  94.789 +
  94.790 +      final static int MAX_WBITS = 15;
  94.791 +      final static int WSIZE = 1 << MAX_WBITS;
  94.792 +      final static int WMASK = WSIZE - 1;
  94.793 +
  94.794 +      final static int HASH_BITS = DEFAULT_MEM_LEVEL + 7;
  94.795 +      final static int HASH_SIZE = 1 << HASH_BITS;
  94.796 +      final static int HASH_MASK = HASH_SIZE - 1;
  94.797 +      final static int HASH_SHIFT = (HASH_BITS + MIN_MATCH - 1) / MIN_MATCH;
  94.798 +
  94.799 +      final static int MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1;
  94.800 +      final static int MAX_DIST = WSIZE - MIN_LOOKAHEAD;
  94.801 +
  94.802 +      final static int PENDING_BUF_SIZE = 1 << (DEFAULT_MEM_LEVEL + 8);
  94.803 +      final static int MAX_BLOCK_SIZE = Math.min(65535, PENDING_BUF_SIZE-5);
  94.804 +
  94.805 +      final static int DEFLATE_STORED = 0;
  94.806 +      final static int DEFLATE_FAST   = 1;
  94.807 +      final static int DEFLATE_SLOW   = 2;
  94.808 +
  94.809 +      final static int GOOD_LENGTH[] = { 0,4, 4, 4, 4, 8,  8,  8,  32,  32 };
  94.810 +      final static int MAX_LAZY[]    = { 0,4, 5, 6, 4,16, 16, 32, 128, 258 };
  94.811 +      final static int NICE_LENGTH[] = { 0,8,16,32,16,32,128,128, 258, 258 };
  94.812 +      final static int MAX_CHAIN[]   = { 0,4, 8,32,16,32,128,256,1024,4096 };
  94.813 +      final static int COMPR_FUNC[]  = { 0,1, 1, 1, 1, 2,  2,  2,   2,   2 };
  94.814 +    }
  94.815 +    private static class InflaterHuffmanTree {
  94.816 +      private final static int MAX_BITLEN = 15;
  94.817 +      private short[] tree;
  94.818 +
  94.819 +      public static InflaterHuffmanTree defLitLenTree, defDistTree;
  94.820 +
  94.821 +      static
  94.822 +      {
  94.823 +        try 
  94.824 +          {
  94.825 +        byte[] codeLengths = new byte[288];
  94.826 +        int i = 0;
  94.827 +        while (i < 144)
  94.828 +          codeLengths[i++] = 8;
  94.829 +        while (i < 256)
  94.830 +          codeLengths[i++] = 9;
  94.831 +        while (i < 280)
  94.832 +          codeLengths[i++] = 7;
  94.833 +        while (i < 288)
  94.834 +          codeLengths[i++] = 8;
  94.835 +        defLitLenTree = new InflaterHuffmanTree(codeLengths);
  94.836 +
  94.837 +        codeLengths = new byte[32];
  94.838 +        i = 0;
  94.839 +        while (i < 32)
  94.840 +          codeLengths[i++] = 5;
  94.841 +        defDistTree = new InflaterHuffmanTree(codeLengths);
  94.842 +          } 
  94.843 +        catch (DataFormatException ex)
  94.844 +          {
  94.845 +        throw new IllegalStateException
  94.846 +          ("InflaterHuffmanTree: static tree length illegal");
  94.847 +          }
  94.848 +      }
  94.849 +
  94.850 +      /**
  94.851 +       * Constructs a Huffman tree from the array of code lengths.
  94.852 +       *
  94.853 +       * @param codeLengths the array of code lengths
  94.854 +       */
  94.855 +      public InflaterHuffmanTree(byte[] codeLengths) throws DataFormatException
  94.856 +      {
  94.857 +        buildTree(codeLengths);
  94.858 +      }
  94.859 +
  94.860 +      private void buildTree(byte[] codeLengths) throws DataFormatException
  94.861 +      {
  94.862 +        int[] blCount = new int[MAX_BITLEN+1];
  94.863 +        int[] nextCode = new int[MAX_BITLEN+1];
  94.864 +        for (int i = 0; i < codeLengths.length; i++)
  94.865 +          {
  94.866 +        int bits = codeLengths[i];
  94.867 +        if (bits > 0)
  94.868 +          blCount[bits]++;
  94.869 +          }
  94.870 +
  94.871 +        int code = 0;
  94.872 +        int treeSize = 512;
  94.873 +        for (int bits = 1; bits <= MAX_BITLEN; bits++)
  94.874 +          {
  94.875 +        nextCode[bits] = code;
  94.876 +        code += blCount[bits] << (16 - bits);
  94.877 +        if (bits >= 10)
  94.878 +          {
  94.879 +            /* We need an extra table for bit lengths >= 10. */
  94.880 +            int start = nextCode[bits] & 0x1ff80;
  94.881 +            int end   = code & 0x1ff80;
  94.882 +            treeSize += (end - start) >> (16 - bits);
  94.883 +          }
  94.884 +          }
  94.885 +        if (code != 65536)
  94.886 +          throw new DataFormatException("Code lengths don't add up properly.");
  94.887 +
  94.888 +        /* Now create and fill the extra tables from longest to shortest
  94.889 +         * bit len.  This way the sub trees will be aligned.
  94.890 +         */
  94.891 +        tree = new short[treeSize];
  94.892 +        int treePtr = 512;
  94.893 +        for (int bits = MAX_BITLEN; bits >= 10; bits--)
  94.894 +          {
  94.895 +        int end   = code & 0x1ff80;
  94.896 +        code -= blCount[bits] << (16 - bits);
  94.897 +        int start = code & 0x1ff80;
  94.898 +        for (int i = start; i < end; i += 1 << 7)
  94.899 +          {
  94.900 +            tree[bitReverse(i)]
  94.901 +              = (short) ((-treePtr << 4) | bits);
  94.902 +            treePtr += 1 << (bits-9);
  94.903 +          }
  94.904 +          }
  94.905 +
  94.906 +        for (int i = 0; i < codeLengths.length; i++)
  94.907 +          {
  94.908 +        int bits = codeLengths[i];
  94.909 +        if (bits == 0)
  94.910 +          continue;
  94.911 +        code = nextCode[bits];
  94.912 +        int revcode = bitReverse(code);
  94.913 +        if (bits <= 9)
  94.914 +          {
  94.915 +            do
  94.916 +              {
  94.917 +            tree[revcode] = (short) ((i << 4) | bits);
  94.918 +            revcode += 1 << bits;
  94.919 +              }
  94.920 +            while (revcode < 512);
  94.921 +          }
  94.922 +        else
  94.923 +          {
  94.924 +            int subTree = tree[revcode & 511];
  94.925 +            int treeLen = 1 << (subTree & 15);
  94.926 +            subTree = -(subTree >> 4);
  94.927 +            do
  94.928 +              { 
  94.929 +            tree[subTree | (revcode >> 9)] = (short) ((i << 4) | bits);
  94.930 +            revcode += 1 << bits;
  94.931 +              }
  94.932 +            while (revcode < treeLen);
  94.933 +          }
  94.934 +        nextCode[bits] = code + (1 << (16 - bits));
  94.935 +          }
  94.936 +      }
  94.937 +      private final static String bit4Reverse =
  94.938 +        "\000\010\004\014\002\012\006\016\001\011\005\015\003\013\007\017";
  94.939 +      static short bitReverse(int value) {
  94.940 +            return (short) (bit4Reverse.charAt(value & 0xf) << 12
  94.941 +                | bit4Reverse.charAt((value >> 4) & 0xf) << 8
  94.942 +                | bit4Reverse.charAt((value >> 8) & 0xf) << 4
  94.943 +                | bit4Reverse.charAt(value >> 12));
  94.944 +      }
  94.945 +
  94.946 +      /**
  94.947 +       * Reads the next symbol from input.  The symbol is encoded using the
  94.948 +       * huffman tree.
  94.949 +       * @param input the input source.
  94.950 +       * @return the next symbol, or -1 if not enough input is available.
  94.951 +       */
  94.952 +      public int getSymbol(StreamManipulator input) throws DataFormatException
  94.953 +      {
  94.954 +        int lookahead, symbol;
  94.955 +        if ((lookahead = input.peekBits(9)) >= 0)
  94.956 +          {
  94.957 +        if ((symbol = tree[lookahead]) >= 0)
  94.958 +          {
  94.959 +            input.dropBits(symbol & 15);
  94.960 +            return symbol >> 4;
  94.961 +          }
  94.962 +        int subtree = -(symbol >> 4);
  94.963 +        int bitlen = symbol & 15;
  94.964 +        if ((lookahead = input.peekBits(bitlen)) >= 0)
  94.965 +          {
  94.966 +            symbol = tree[subtree | (lookahead >> 9)];
  94.967 +            input.dropBits(symbol & 15);
  94.968 +            return symbol >> 4;
  94.969 +          }
  94.970 +        else
  94.971 +          {
  94.972 +            int bits = input.getAvailableBits();
  94.973 +            lookahead = input.peekBits(bits);
  94.974 +            symbol = tree[subtree | (lookahead >> 9)];
  94.975 +            if ((symbol & 15) <= bits)
  94.976 +              {
  94.977 +            input.dropBits(symbol & 15);
  94.978 +            return symbol >> 4;
  94.979 +              }
  94.980 +            else
  94.981 +              return -1;
  94.982 +          }
  94.983 +          }
  94.984 +        else
  94.985 +          {
  94.986 +        int bits = input.getAvailableBits();
  94.987 +        lookahead = input.peekBits(bits);
  94.988 +        symbol = tree[lookahead];
  94.989 +        if (symbol >= 0 && (symbol & 15) <= bits)
  94.990 +          {
  94.991 +            input.dropBits(symbol & 15);
  94.992 +            return symbol >> 4;
  94.993 +          }
  94.994 +        else
  94.995 +          return -1;
  94.996 +          }
  94.997 +      }
  94.998 +    }
  94.999 +    private static class InflaterDynHeader
 94.1000 +    {
 94.1001 +      private static final int LNUM   = 0;
 94.1002 +      private static final int DNUM   = 1;
 94.1003 +      private static final int BLNUM  = 2;
 94.1004 +      private static final int BLLENS = 3;
 94.1005 +      private static final int LENS   = 4;
 94.1006 +      private static final int REPS   = 5;
 94.1007 +
 94.1008 +      private static final int repMin[]  = { 3, 3, 11 };
 94.1009 +      private static final int repBits[] = { 2, 3,  7 };
 94.1010 +
 94.1011 +
 94.1012 +      private byte[] blLens;
 94.1013 +      private byte[] litdistLens;
 94.1014 +
 94.1015 +      private InflaterHuffmanTree blTree;
 94.1016 +
 94.1017 +      private int mode;
 94.1018 +      private int lnum, dnum, blnum, num;
 94.1019 +      private int repSymbol;
 94.1020 +      private byte lastLen;
 94.1021 +      private int ptr;
 94.1022 +
 94.1023 +      private static final int[] BL_ORDER =
 94.1024 +      { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
 94.1025 +
 94.1026 +      public InflaterDynHeader()
 94.1027 +      {
 94.1028 +      }
 94.1029 +
 94.1030 +      public boolean decode(StreamManipulator input) throws DataFormatException
 94.1031 +      {
 94.1032 +      decode_loop:
 94.1033 +        for (;;)
 94.1034 +          {
 94.1035 +        switch (mode)
 94.1036 +          {
 94.1037 +          case LNUM:
 94.1038 +            lnum = input.peekBits(5);
 94.1039 +            if (lnum < 0)
 94.1040 +              return false;
 94.1041 +            lnum += 257;
 94.1042 +            input.dropBits(5);
 94.1043 +    //  	    System.err.println("LNUM: "+lnum);
 94.1044 +            mode = DNUM;
 94.1045 +            /* fall through */
 94.1046 +          case DNUM:
 94.1047 +            dnum = input.peekBits(5);
 94.1048 +            if (dnum < 0)
 94.1049 +              return false;
 94.1050 +            dnum++;
 94.1051 +            input.dropBits(5);
 94.1052 +    //  	    System.err.println("DNUM: "+dnum);
 94.1053 +            num = lnum+dnum;
 94.1054 +            litdistLens = new byte[num];
 94.1055 +            mode = BLNUM;
 94.1056 +            /* fall through */
 94.1057 +          case BLNUM:
 94.1058 +            blnum = input.peekBits(4);
 94.1059 +            if (blnum < 0)
 94.1060 +              return false;
 94.1061 +            blnum += 4;
 94.1062 +            input.dropBits(4);
 94.1063 +            blLens = new byte[19];
 94.1064 +            ptr = 0;
 94.1065 +    //  	    System.err.println("BLNUM: "+blnum);
 94.1066 +            mode = BLLENS;
 94.1067 +            /* fall through */
 94.1068 +          case BLLENS:
 94.1069 +            while (ptr < blnum)
 94.1070 +              {
 94.1071 +            int len = input.peekBits(3);
 94.1072 +            if (len < 0)
 94.1073 +              return false;
 94.1074 +            input.dropBits(3);
 94.1075 +    //  		System.err.println("blLens["+BL_ORDER[ptr]+"]: "+len);
 94.1076 +            blLens[BL_ORDER[ptr]] = (byte) len;
 94.1077 +            ptr++;
 94.1078 +              }
 94.1079 +            blTree = new InflaterHuffmanTree(blLens);
 94.1080 +            blLens = null;
 94.1081 +            ptr = 0;
 94.1082 +            mode = LENS;
 94.1083 +            /* fall through */
 94.1084 +          case LENS:
 94.1085 +            {
 94.1086 +              int symbol;
 94.1087 +              while (((symbol = blTree.getSymbol(input)) & ~15) == 0)
 94.1088 +            {
 94.1089 +              /* Normal case: symbol in [0..15] */
 94.1090 +
 94.1091 +    //  		  System.err.println("litdistLens["+ptr+"]: "+symbol);
 94.1092 +              litdistLens[ptr++] = lastLen = (byte) symbol;
 94.1093 +
 94.1094 +              if (ptr == num)
 94.1095 +                {
 94.1096 +                  /* Finished */
 94.1097 +                  return true;
 94.1098 +                }
 94.1099 +            }
 94.1100 +
 94.1101 +              /* need more input ? */
 94.1102 +              if (symbol < 0)
 94.1103 +            return false;
 94.1104 +
 94.1105 +              /* otherwise repeat code */
 94.1106 +              if (symbol >= 17)
 94.1107 +            {
 94.1108 +              /* repeat zero */
 94.1109 +    //  		  System.err.println("repeating zero");
 94.1110 +              lastLen = 0;
 94.1111 +            }
 94.1112 +              else
 94.1113 +            {
 94.1114 +              if (ptr == 0)
 94.1115 +                throw new DataFormatException();
 94.1116 +            }
 94.1117 +              repSymbol = symbol-16;
 94.1118 +              mode = REPS;
 94.1119 +            }
 94.1120 +            /* fall through */
 94.1121 +
 94.1122 +          case REPS:
 94.1123 +            {
 94.1124 +              int bits = repBits[repSymbol];
 94.1125 +              int count = input.peekBits(bits);
 94.1126 +              if (count < 0)
 94.1127 +            return false;
 94.1128 +              input.dropBits(bits);
 94.1129 +              count += repMin[repSymbol];
 94.1130 +    //  	      System.err.println("litdistLens repeated: "+count);
 94.1131 +
 94.1132 +              if (ptr + count > num)
 94.1133 +            throw new DataFormatException();
 94.1134 +              while (count-- > 0)
 94.1135 +            litdistLens[ptr++] = lastLen;
 94.1136 +
 94.1137 +              if (ptr == num)
 94.1138 +            {
 94.1139 +              /* Finished */
 94.1140 +              return true;
 94.1141 +            }
 94.1142 +            }
 94.1143 +            mode = LENS;
 94.1144 +            continue decode_loop;
 94.1145 +          }
 94.1146 +          }
 94.1147 +      }
 94.1148 +
 94.1149 +      public InflaterHuffmanTree buildLitLenTree() throws DataFormatException
 94.1150 +      {
 94.1151 +        byte[] litlenLens = new byte[lnum];
 94.1152 +        System.arraycopy(litdistLens, 0, litlenLens, 0, lnum);
 94.1153 +        return new InflaterHuffmanTree(litlenLens);
 94.1154 +      }
 94.1155 +
 94.1156 +      public InflaterHuffmanTree buildDistTree() throws DataFormatException
 94.1157 +      {
 94.1158 +        byte[] distLens = new byte[dnum];
 94.1159 +        System.arraycopy(litdistLens, lnum, distLens, 0, dnum);
 94.1160 +        return new InflaterHuffmanTree(distLens);
 94.1161 +      }
 94.1162 +    }
 94.1163 +    /**
 94.1164 +     * This class allows us to retrieve a specified amount of bits from
 94.1165 +     * the input buffer, as well as copy big byte blocks.
 94.1166 +     *
 94.1167 +     * It uses an int buffer to store up to 31 bits for direct
 94.1168 +     * manipulation.  This guarantees that we can get at least 16 bits,
 94.1169 +     * but we only need at most 15, so this is all safe.
 94.1170 +     *
 94.1171 +     * There are some optimizations in this class, for example, you must
 94.1172 +     * never peek more then 8 bits more than needed, and you must first 
 94.1173 +     * peek bits before you may drop them.  This is not a general purpose
 94.1174 +     * class but optimized for the behaviour of the Inflater.
 94.1175 +     *
 94.1176 +     * @author John Leuner, Jochen Hoenicke
 94.1177 +     */
 94.1178 +
 94.1179 +    private static class StreamManipulator
 94.1180 +    {
 94.1181 +      private byte[] window;
 94.1182 +      private int window_start = 0;
 94.1183 +      private int window_end = 0;
 94.1184 +
 94.1185 +      private int buffer = 0;
 94.1186 +      private int bits_in_buffer = 0;
 94.1187 +
 94.1188 +      /**
 94.1189 +       * Get the next n bits but don't increase input pointer.  n must be
 94.1190 +       * less or equal 16 and if you if this call succeeds, you must drop
 94.1191 +       * at least n-8 bits in the next call.
 94.1192 +       * 
 94.1193 +       * @return the value of the bits, or -1 if not enough bits available.  */
 94.1194 +      public final int peekBits(int n)
 94.1195 +      {
 94.1196 +        if (bits_in_buffer < n)
 94.1197 +          {
 94.1198 +        if (window_start == window_end)
 94.1199 +          return -1;
 94.1200 +        buffer |= (window[window_start++] & 0xff
 94.1201 +               | (window[window_start++] & 0xff) << 8) << bits_in_buffer;
 94.1202 +        bits_in_buffer += 16;
 94.1203 +          }
 94.1204 +        return buffer & ((1 << n) - 1);
 94.1205 +      }
 94.1206 +
 94.1207 +      /* Drops the next n bits from the input.  You should have called peekBits
 94.1208 +       * with a bigger or equal n before, to make sure that enough bits are in
 94.1209 +       * the bit buffer.
 94.1210 +       */
 94.1211 +      public final void dropBits(int n)
 94.1212 +      {
 94.1213 +        buffer >>>= n;
 94.1214 +        bits_in_buffer -= n;
 94.1215 +      }
 94.1216 +
 94.1217 +      /**
 94.1218 +       * Gets the next n bits and increases input pointer.  This is equivalent
 94.1219 +       * to peekBits followed by dropBits, except for correct error handling.
 94.1220 +       * @return the value of the bits, or -1 if not enough bits available. 
 94.1221 +       */
 94.1222 +      public final int getBits(int n)
 94.1223 +      {
 94.1224 +        int bits = peekBits(n);
 94.1225 +        if (bits >= 0)
 94.1226 +          dropBits(n);
 94.1227 +        return bits;
 94.1228 +      }
 94.1229 +      /**
 94.1230 +       * Gets the number of bits available in the bit buffer.  This must be
 94.1231 +       * only called when a previous peekBits() returned -1.
 94.1232 +       * @return the number of bits available.
 94.1233 +       */
 94.1234 +      public final int getAvailableBits()
 94.1235 +      {
 94.1236 +        return bits_in_buffer;
 94.1237 +      }
 94.1238 +
 94.1239 +      /**
 94.1240 +       * Gets the number of bytes available.  
 94.1241 +       * @return the number of bytes available.
 94.1242 +       */
 94.1243 +      public final int getAvailableBytes()
 94.1244 +      {
 94.1245 +        return window_end - window_start + (bits_in_buffer >> 3);
 94.1246 +      }
 94.1247 +
 94.1248 +      /**
 94.1249 +       * Skips to the next byte boundary.
 94.1250 +       */
 94.1251 +      public void skipToByteBoundary()
 94.1252 +      {
 94.1253 +        buffer >>= (bits_in_buffer & 7);
 94.1254 +        bits_in_buffer &= ~7;
 94.1255 +      }
 94.1256 +
 94.1257 +      public final boolean needsInput() {
 94.1258 +        return window_start == window_end;
 94.1259 +      }
 94.1260 +
 94.1261 +
 94.1262 +      /* Copies length bytes from input buffer to output buffer starting
 94.1263 +       * at output[offset].  You have to make sure, that the buffer is
 94.1264 +       * byte aligned.  If not enough bytes are available, copies fewer
 94.1265 +       * bytes.
 94.1266 +       * @param length the length to copy, 0 is allowed.
 94.1267 +       * @return the number of bytes copied, 0 if no byte is available.  
 94.1268 +       */
 94.1269 +      public int copyBytes(byte[] output, int offset, int length)
 94.1270 +      {
 94.1271 +        if (length < 0)
 94.1272 +          throw new IllegalArgumentException("length negative");
 94.1273 +        if ((bits_in_buffer & 7) != 0)  
 94.1274 +          /* bits_in_buffer may only be 0 or 8 */
 94.1275 +          throw new IllegalStateException("Bit buffer is not aligned!");
 94.1276 +
 94.1277 +        int count = 0;
 94.1278 +        while (bits_in_buffer > 0 && length > 0)
 94.1279 +          {
 94.1280 +        output[offset++] = (byte) buffer;
 94.1281 +        buffer >>>= 8;
 94.1282 +        bits_in_buffer -= 8;
 94.1283 +        length--;
 94.1284 +        count++;
 94.1285 +          }
 94.1286 +        if (length == 0)
 94.1287 +          return count;
 94.1288 +
 94.1289 +        int avail = window_end - window_start;
 94.1290 +        if (length > avail)
 94.1291 +          length = avail;
 94.1292 +        System.arraycopy(window, window_start, output, offset, length);
 94.1293 +        window_start += length;
 94.1294 +
 94.1295 +        if (((window_start - window_end) & 1) != 0)
 94.1296 +          {
 94.1297 +        /* We always want an even number of bytes in input, see peekBits */
 94.1298 +        buffer = (window[window_start++] & 0xff);
 94.1299 +        bits_in_buffer = 8;
 94.1300 +          }
 94.1301 +        return count + length;
 94.1302 +      }
 94.1303 +
 94.1304 +      public StreamManipulator()
 94.1305 +      {
 94.1306 +      }
 94.1307 +
 94.1308 +      public void reset()
 94.1309 +      {
 94.1310 +        window_start = window_end = buffer = bits_in_buffer = 0;
 94.1311 +      }
 94.1312 +
 94.1313 +      public void setInput(byte[] buf, int off, int len)
 94.1314 +      {
 94.1315 +        if (window_start < window_end)
 94.1316 +          throw new IllegalStateException
 94.1317 +        ("Old input was not completely processed");
 94.1318 +
 94.1319 +        int end = off + len;
 94.1320 +
 94.1321 +        /* We want to throw an ArrayIndexOutOfBoundsException early.  The
 94.1322 +         * check is very tricky: it also handles integer wrap around.  
 94.1323 +         */
 94.1324 +        if (0 > off || off > end || end > buf.length)
 94.1325 +          throw new ArrayIndexOutOfBoundsException();
 94.1326 +
 94.1327 +        if ((len & 1) != 0)
 94.1328 +          {
 94.1329 +        /* We always want an even number of bytes in input, see peekBits */
 94.1330 +        buffer |= (buf[off++] & 0xff) << bits_in_buffer;
 94.1331 +        bits_in_buffer += 8;
 94.1332 +          }
 94.1333 +
 94.1334 +        window = buf;
 94.1335 +        window_start = off;
 94.1336 +        window_end = end;
 94.1337 +      }
 94.1338 +    }
 94.1339 +    /*
 94.1340 +     * Contains the output from the Inflation process.
 94.1341 +     *
 94.1342 +     * We need to have a window so that we can refer backwards into the output stream
 94.1343 +     * to repeat stuff.
 94.1344 +     *
 94.1345 +     * @author John Leuner
 94.1346 +     * @since JDK 1.1
 94.1347 +     */
 94.1348 +
 94.1349 +    private static class OutputWindow
 94.1350 +    {
 94.1351 +      private final int WINDOW_SIZE = 1 << 15;
 94.1352 +      private final int WINDOW_MASK = WINDOW_SIZE - 1;
 94.1353 +
 94.1354 +      private byte[] window = new byte[WINDOW_SIZE]; //The window is 2^15 bytes
 94.1355 +      private int window_end  = 0;
 94.1356 +      private int window_filled = 0;
 94.1357 +
 94.1358 +      public void write(int abyte)
 94.1359 +      {
 94.1360 +        if (window_filled++ == WINDOW_SIZE)
 94.1361 +          throw new IllegalStateException("Window full");
 94.1362 +        window[window_end++] = (byte) abyte;
 94.1363 +        window_end &= WINDOW_MASK;
 94.1364 +      }
 94.1365 +
 94.1366 +
 94.1367 +      private final void slowRepeat(int rep_start, int len, int dist)
 94.1368 +      {
 94.1369 +        while (len-- > 0)
 94.1370 +          {
 94.1371 +        window[window_end++] = window[rep_start++];
 94.1372 +        window_end &= WINDOW_MASK;
 94.1373 +        rep_start &= WINDOW_MASK;
 94.1374 +          }
 94.1375 +      }
 94.1376 +
 94.1377 +      public void repeat(int len, int dist)
 94.1378 +      {
 94.1379 +        if ((window_filled += len) > WINDOW_SIZE)
 94.1380 +          throw new IllegalStateException("Window full");
 94.1381 +
 94.1382 +        int rep_start = (window_end - dist) & WINDOW_MASK;
 94.1383 +        int border = WINDOW_SIZE - len;
 94.1384 +        if (rep_start <= border && window_end < border)
 94.1385 +          {
 94.1386 +        if (len <= dist)
 94.1387 +          {
 94.1388 +            System.arraycopy(window, rep_start, window, window_end, len);
 94.1389 +            window_end += len;
 94.1390 +          }
 94.1391 +        else
 94.1392 +          {
 94.1393 +            /* We have to copy manually, since the repeat pattern overlaps.
 94.1394 +             */
 94.1395 +            while (len-- > 0)
 94.1396 +              window[window_end++] = window[rep_start++];
 94.1397 +          }
 94.1398 +          }
 94.1399 +        else
 94.1400 +          slowRepeat(rep_start, len, dist);
 94.1401 +      }
 94.1402 +
 94.1403 +      public int copyStored(StreamManipulator input, int len)
 94.1404 +      {
 94.1405 +        len = Math.min(Math.min(len, WINDOW_SIZE - window_filled), 
 94.1406 +               input.getAvailableBytes());
 94.1407 +        int copied;
 94.1408 +
 94.1409 +        int tailLen = WINDOW_SIZE - window_end;
 94.1410 +        if (len > tailLen)
 94.1411 +          {
 94.1412 +        copied = input.copyBytes(window, window_end, tailLen);
 94.1413 +        if (copied == tailLen)
 94.1414 +          copied += input.copyBytes(window, 0, len - tailLen);
 94.1415 +          }
 94.1416 +        else
 94.1417 +          copied = input.copyBytes(window, window_end, len);
 94.1418 +
 94.1419 +        window_end = (window_end + copied) & WINDOW_MASK;
 94.1420 +        window_filled += copied;
 94.1421 +        return copied;
 94.1422 +      }
 94.1423 +
 94.1424 +      public void copyDict(byte[] dict, int offset, int len)
 94.1425 +      {
 94.1426 +        if (window_filled > 0)
 94.1427 +          throw new IllegalStateException();
 94.1428 +
 94.1429 +        if (len > WINDOW_SIZE)
 94.1430 +          {
 94.1431 +        offset += len - WINDOW_SIZE;
 94.1432 +        len = WINDOW_SIZE;
 94.1433 +          }
 94.1434 +        System.arraycopy(dict, offset, window, 0, len);
 94.1435 +        window_end = len & WINDOW_MASK;
 94.1436 +      }
 94.1437 +
 94.1438 +      public int getFreeSpace()
 94.1439 +      {
 94.1440 +        return WINDOW_SIZE - window_filled;
 94.1441 +      }
 94.1442 +
 94.1443 +      public int getAvailable()
 94.1444 +      {
 94.1445 +        return window_filled;
 94.1446 +      }
 94.1447 +
 94.1448 +      public int copyOutput(byte[] output, int offset, int len)
 94.1449 +      {
 94.1450 +        int copy_end = window_end;
 94.1451 +        if (len > window_filled)
 94.1452 +          len = window_filled;
 94.1453 +        else
 94.1454 +          copy_end = (window_end - window_filled + len) & WINDOW_MASK;
 94.1455 +
 94.1456 +        int copied = len;
 94.1457 +        int tailLen = len - copy_end;
 94.1458 +
 94.1459 +        if (tailLen > 0)
 94.1460 +          {
 94.1461 +        System.arraycopy(window, WINDOW_SIZE - tailLen,
 94.1462 +                 output, offset, tailLen);
 94.1463 +        offset += tailLen;
 94.1464 +        len = copy_end;
 94.1465 +          }
 94.1466 +        System.arraycopy(window, copy_end - len, output, offset, len);
 94.1467 +        window_filled -= copied;
 94.1468 +        if (window_filled < 0)
 94.1469 +          throw new IllegalStateException();
 94.1470 +        return copied;
 94.1471 +      }
 94.1472 +
 94.1473 +      public void reset() {
 94.1474 +        window_filled = window_end = 0;
 94.1475 +      }
 94.1476 +    }
 94.1477 +  
 94.1478 +}
    95.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.2 +++ b/emul/mini/src/main/java/java/util/zip/InflaterInputStream.java	Tue Feb 05 17:04:22 2013 +0100
    95.3 @@ -0,0 +1,288 @@
    95.4 +/*
    95.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
    95.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    95.7 + *
    95.8 + * This code is free software; you can redistribute it and/or modify it
    95.9 + * under the terms of the GNU General Public License version 2 only, as
   95.10 + * published by the Free Software Foundation.  Oracle designates this
   95.11 + * particular file as subject to the "Classpath" exception as provided
   95.12 + * by Oracle in the LICENSE file that accompanied this code.
   95.13 + *
   95.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   95.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   95.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   95.17 + * version 2 for more details (a copy is included in the LICENSE file that
   95.18 + * accompanied this code).
   95.19 + *
   95.20 + * You should have received a copy of the GNU General Public License version
   95.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   95.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   95.23 + *
   95.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   95.25 + * or visit www.oracle.com if you need additional information or have any
   95.26 + * questions.
   95.27 + */
   95.28 +
   95.29 +package java.util.zip;
   95.30 +
   95.31 +import java.io.FilterInputStream;
   95.32 +import java.io.InputStream;
   95.33 +import java.io.IOException;
   95.34 +import java.io.EOFException;
   95.35 +
   95.36 +/**
   95.37 + * This class implements a stream filter for uncompressing data in the
   95.38 + * "deflate" compression format. It is also used as the basis for other
   95.39 + * decompression filters, such as GZIPInputStream.
   95.40 + *
   95.41 + * @see         Inflater
   95.42 + * @author      David Connelly
   95.43 + */
   95.44 +public
   95.45 +class InflaterInputStream extends FilterInputStream {
   95.46 +    /**
   95.47 +     * Decompressor for this stream.
   95.48 +     */
   95.49 +    protected Inflater inf;
   95.50 +
   95.51 +    /**
   95.52 +     * Input buffer for decompression.
   95.53 +     */
   95.54 +    protected byte[] buf;
   95.55 +
   95.56 +    /**
   95.57 +     * Length of input buffer.
   95.58 +     */
   95.59 +    protected int len;
   95.60 +
   95.61 +    private boolean closed = false;
   95.62 +    // this flag is set to true after EOF has reached
   95.63 +    private boolean reachEOF = false;
   95.64 +
   95.65 +    /**
   95.66 +     * Check to make sure that this stream has not been closed
   95.67 +     */
   95.68 +    private void ensureOpen() throws IOException {
   95.69 +        if (closed) {
   95.70 +            throw new IOException("Stream closed");
   95.71 +        }
   95.72 +    }
   95.73 +
   95.74 +
   95.75 +    /**
   95.76 +     * Creates a new input stream with the specified decompressor and
   95.77 +     * buffer size.
   95.78 +     * @param in the input stream
   95.79 +     * @param inf the decompressor ("inflater")
   95.80 +     * @param size the input buffer size
   95.81 +     * @exception IllegalArgumentException if size is <= 0
   95.82 +     */
   95.83 +    public InflaterInputStream(InputStream in, Inflater inf, int size) {
   95.84 +        super(in);
   95.85 +        if (in == null || inf == null) {
   95.86 +            throw new NullPointerException();
   95.87 +        } else if (size <= 0) {
   95.88 +            throw new IllegalArgumentException("buffer size <= 0");
   95.89 +        }
   95.90 +        this.inf = inf;
   95.91 +        buf = new byte[size];
   95.92 +    }
   95.93 +
   95.94 +    /**
   95.95 +     * Creates a new input stream with the specified decompressor and a
   95.96 +     * default buffer size.
   95.97 +     * @param in the input stream
   95.98 +     * @param inf the decompressor ("inflater")
   95.99 +     */
  95.100 +    public InflaterInputStream(InputStream in, Inflater inf) {
  95.101 +        this(in, inf, 512);
  95.102 +    }
  95.103 +
  95.104 +    boolean usesDefaultInflater = false;
  95.105 +
  95.106 +    /**
  95.107 +     * Creates a new input stream with a default decompressor and buffer size.
  95.108 +     * @param in the input stream
  95.109 +     */
  95.110 +    public InflaterInputStream(InputStream in) {
  95.111 +        this(in, new Inflater());
  95.112 +        usesDefaultInflater = true;
  95.113 +    }
  95.114 +
  95.115 +    private byte[] singleByteBuf = new byte[1];
  95.116 +
  95.117 +    /**
  95.118 +     * Reads a byte of uncompressed data. This method will block until
  95.119 +     * enough input is available for decompression.
  95.120 +     * @return the byte read, or -1 if end of compressed input is reached
  95.121 +     * @exception IOException if an I/O error has occurred
  95.122 +     */
  95.123 +    public int read() throws IOException {
  95.124 +        ensureOpen();
  95.125 +        return read(singleByteBuf, 0, 1) == -1 ? -1 : singleByteBuf[0] & 0xff;
  95.126 +    }
  95.127 +
  95.128 +    /**
  95.129 +     * Reads uncompressed data into an array of bytes. If <code>len</code> is not
  95.130 +     * zero, the method will block until some input can be decompressed; otherwise,
  95.131 +     * no bytes are read and <code>0</code> is returned.
  95.132 +     * @param b the buffer into which the data is read
  95.133 +     * @param off the start offset in the destination array <code>b</code>
  95.134 +     * @param len the maximum number of bytes read
  95.135 +     * @return the actual number of bytes read, or -1 if the end of the
  95.136 +     *         compressed input is reached or a preset dictionary is needed
  95.137 +     * @exception  NullPointerException If <code>b</code> is <code>null</code>.
  95.138 +     * @exception  IndexOutOfBoundsException If <code>off</code> is negative,
  95.139 +     * <code>len</code> is negative, or <code>len</code> is greater than
  95.140 +     * <code>b.length - off</code>
  95.141 +     * @exception ZipException if a ZIP format error has occurred
  95.142 +     * @exception IOException if an I/O error has occurred
  95.143 +     */
  95.144 +    public int read(byte[] b, int off, int len) throws IOException {
  95.145 +        ensureOpen();
  95.146 +        if (b == null) {
  95.147 +            throw new NullPointerException();
  95.148 +        } else if (off < 0 || len < 0 || len > b.length - off) {
  95.149 +            throw new IndexOutOfBoundsException();
  95.150 +        } else if (len == 0) {
  95.151 +            return 0;
  95.152 +        }
  95.153 +        try {
  95.154 +            int n;
  95.155 +            while ((n = inf.inflate(b, off, len)) == 0) {
  95.156 +                if (inf.finished() || inf.needsDictionary()) {
  95.157 +                    reachEOF = true;
  95.158 +                    return -1;
  95.159 +                }
  95.160 +                if (inf.needsInput()) {
  95.161 +                    fill();
  95.162 +                }
  95.163 +            }
  95.164 +            return n;
  95.165 +        } catch (DataFormatException e) {
  95.166 +            String s = e.getMessage();
  95.167 +            throw new ZipException(s != null ? s : "Invalid ZLIB data format");
  95.168 +        }
  95.169 +    }
  95.170 +
  95.171 +    /**
  95.172 +     * Returns 0 after EOF has been reached, otherwise always return 1.
  95.173 +     * <p>
  95.174 +     * Programs should not count on this method to return the actual number
  95.175 +     * of bytes that could be read without blocking.
  95.176 +     *
  95.177 +     * @return     1 before EOF and 0 after EOF.
  95.178 +     * @exception  IOException  if an I/O error occurs.
  95.179 +     *
  95.180 +     */
  95.181 +    public int available() throws IOException {
  95.182 +        ensureOpen();
  95.183 +        if (reachEOF) {
  95.184 +            return 0;
  95.185 +        } else {
  95.186 +            return 1;
  95.187 +        }
  95.188 +    }
  95.189 +
  95.190 +    private byte[] b = new byte[512];
  95.191 +
  95.192 +    /**
  95.193 +     * Skips specified number of bytes of uncompressed data.
  95.194 +     * @param n the number of bytes to skip
  95.195 +     * @return the actual number of bytes skipped.
  95.196 +     * @exception IOException if an I/O error has occurred
  95.197 +     * @exception IllegalArgumentException if n < 0
  95.198 +     */
  95.199 +    public long skip(long n) throws IOException {
  95.200 +        if (n < 0) {
  95.201 +            throw new IllegalArgumentException("negative skip length");
  95.202 +        }
  95.203 +        ensureOpen();
  95.204 +        int max = (int)Math.min(n, Integer.MAX_VALUE);
  95.205 +        int total = 0;
  95.206 +        while (total < max) {
  95.207 +            int len = max - total;
  95.208 +            if (len > b.length) {
  95.209 +                len = b.length;
  95.210 +            }
  95.211 +            len = read(b, 0, len);
  95.212 +            if (len == -1) {
  95.213 +                reachEOF = true;
  95.214 +                break;
  95.215 +            }
  95.216 +            total += len;
  95.217 +        }
  95.218 +        return total;
  95.219 +    }
  95.220 +
  95.221 +    /**
  95.222 +     * Closes this input stream and releases any system resources associated
  95.223 +     * with the stream.
  95.224 +     * @exception IOException if an I/O error has occurred
  95.225 +     */
  95.226 +    public void close() throws IOException {
  95.227 +        if (!closed) {
  95.228 +            if (usesDefaultInflater)
  95.229 +                inf.end();
  95.230 +            in.close();
  95.231 +            closed = true;
  95.232 +        }
  95.233 +    }
  95.234 +
  95.235 +    /**
  95.236 +     * Fills input buffer with more data to decompress.
  95.237 +     * @exception IOException if an I/O error has occurred
  95.238 +     */
  95.239 +    protected void fill() throws IOException {
  95.240 +        ensureOpen();
  95.241 +        len = in.read(buf, 0, buf.length);
  95.242 +        if (len == -1) {
  95.243 +            throw new EOFException("Unexpected end of ZLIB input stream");
  95.244 +        }
  95.245 +        inf.setInput(buf, 0, len);
  95.246 +    }
  95.247 +
  95.248 +    /**
  95.249 +     * Tests if this input stream supports the <code>mark</code> and
  95.250 +     * <code>reset</code> methods. The <code>markSupported</code>
  95.251 +     * method of <code>InflaterInputStream</code> returns
  95.252 +     * <code>false</code>.
  95.253 +     *
  95.254 +     * @return  a <code>boolean</code> indicating if this stream type supports
  95.255 +     *          the <code>mark</code> and <code>reset</code> methods.
  95.256 +     * @see     java.io.InputStream#mark(int)
  95.257 +     * @see     java.io.InputStream#reset()
  95.258 +     */
  95.259 +    public boolean markSupported() {
  95.260 +        return false;
  95.261 +    }
  95.262 +
  95.263 +    /**
  95.264 +     * Marks the current position in this input stream.
  95.265 +     *
  95.266 +     * <p> The <code>mark</code> method of <code>InflaterInputStream</code>
  95.267 +     * does nothing.
  95.268 +     *
  95.269 +     * @param   readlimit   the maximum limit of bytes that can be read before
  95.270 +     *                      the mark position becomes invalid.
  95.271 +     * @see     java.io.InputStream#reset()
  95.272 +     */
  95.273 +    public synchronized void mark(int readlimit) {
  95.274 +    }
  95.275 +
  95.276 +    /**
  95.277 +     * Repositions this stream to the position at the time the
  95.278 +     * <code>mark</code> method was last called on this input stream.
  95.279 +     *
  95.280 +     * <p> The method <code>reset</code> for class
  95.281 +     * <code>InflaterInputStream</code> does nothing except throw an
  95.282 +     * <code>IOException</code>.
  95.283 +     *
  95.284 +     * @exception  IOException  if this method is invoked.
  95.285 +     * @see     java.io.InputStream#mark(int)
  95.286 +     * @see     java.io.IOException
  95.287 +     */
  95.288 +    public synchronized void reset() throws IOException {
  95.289 +        throw new IOException("mark/reset not supported");
  95.290 +    }
  95.291 +}
    96.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    96.2 +++ b/emul/mini/src/main/java/java/util/zip/ZStreamRef.java	Tue Feb 05 17:04:22 2013 +0100
    96.3 @@ -0,0 +1,46 @@
    96.4 +/*
    96.5 + * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
    96.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    96.7 + *
    96.8 + * This code is free software; you can redistribute it and/or modify it
    96.9 + * under the terms of the GNU General Public License version 2 only, as
   96.10 + * published by the Free Software Foundation.  Oracle designates this
   96.11 + * particular file as subject to the "Classpath" exception as provided
   96.12 + * by Oracle in the LICENSE file that accompanied this code.
   96.13 + *
   96.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   96.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   96.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   96.17 + * version 2 for more details (a copy is included in the LICENSE file that
   96.18 + * accompanied this code).
   96.19 + *
   96.20 + * You should have received a copy of the GNU General Public License version
   96.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   96.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   96.23 + *
   96.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   96.25 + * or visit www.oracle.com if you need additional information or have any
   96.26 + * questions.
   96.27 + */
   96.28 +
   96.29 +package java.util.zip;
   96.30 +
   96.31 +/**
   96.32 + * A reference to the native zlib's z_stream structure.
   96.33 + */
   96.34 +
   96.35 +class ZStreamRef {
   96.36 +
   96.37 +    private long address;
   96.38 +    ZStreamRef (long address) {
   96.39 +        this.address = address;
   96.40 +    }
   96.41 +
   96.42 +    long address() {
   96.43 +        return address;
   96.44 +    }
   96.45 +
   96.46 +    void clear() {
   96.47 +        address = 0;
   96.48 +    }
   96.49 +}
    97.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.2 +++ b/emul/mini/src/main/java/java/util/zip/ZipConstants.java	Tue Feb 05 17:04:22 2013 +0100
    97.3 @@ -0,0 +1,98 @@
    97.4 +/*
    97.5 + * Copyright (c) 1995, 1996, Oracle and/or its affiliates. All rights reserved.
    97.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    97.7 + *
    97.8 + * This code is free software; you can redistribute it and/or modify it
    97.9 + * under the terms of the GNU General Public License version 2 only, as
   97.10 + * published by the Free Software Foundation.  Oracle designates this
   97.11 + * particular file as subject to the "Classpath" exception as provided
   97.12 + * by Oracle in the LICENSE file that accompanied this code.
   97.13 + *
   97.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   97.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   97.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   97.17 + * version 2 for more details (a copy is included in the LICENSE file that
   97.18 + * accompanied this code).
   97.19 + *
   97.20 + * You should have received a copy of the GNU General Public License version
   97.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   97.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   97.23 + *
   97.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   97.25 + * or visit www.oracle.com if you need additional information or have any
   97.26 + * questions.
   97.27 + */
   97.28 +
   97.29 +package java.util.zip;
   97.30 +
   97.31 +/*
   97.32 + * This interface defines the constants that are used by the classes
   97.33 + * which manipulate ZIP files.
   97.34 + *
   97.35 + * @author      David Connelly
   97.36 + */
   97.37 +interface ZipConstants {
   97.38 +    /*
   97.39 +     * Header signatures
   97.40 +     */
   97.41 +    static long LOCSIG = 0x04034b50L;   // "PK\003\004"
   97.42 +    static long EXTSIG = 0x08074b50L;   // "PK\007\008"
   97.43 +    static long CENSIG = 0x02014b50L;   // "PK\001\002"
   97.44 +    static long ENDSIG = 0x06054b50L;   // "PK\005\006"
   97.45 +
   97.46 +    /*
   97.47 +     * Header sizes in bytes (including signatures)
   97.48 +     */
   97.49 +    static final int LOCHDR = 30;       // LOC header size
   97.50 +    static final int EXTHDR = 16;       // EXT header size
   97.51 +    static final int CENHDR = 46;       // CEN header size
   97.52 +    static final int ENDHDR = 22;       // END header size
   97.53 +
   97.54 +    /*
   97.55 +     * Local file (LOC) header field offsets
   97.56 +     */
   97.57 +    static final int LOCVER = 4;        // version needed to extract
   97.58 +    static final int LOCFLG = 6;        // general purpose bit flag
   97.59 +    static final int LOCHOW = 8;        // compression method
   97.60 +    static final int LOCTIM = 10;       // modification time
   97.61 +    static final int LOCCRC = 14;       // uncompressed file crc-32 value
   97.62 +    static final int LOCSIZ = 18;       // compressed size
   97.63 +    static final int LOCLEN = 22;       // uncompressed size
   97.64 +    static final int LOCNAM = 26;       // filename length
   97.65 +    static final int LOCEXT = 28;       // extra field length
   97.66 +
   97.67 +    /*
   97.68 +     * Extra local (EXT) header field offsets
   97.69 +     */
   97.70 +    static final int EXTCRC = 4;        // uncompressed file crc-32 value
   97.71 +    static final int EXTSIZ = 8;        // compressed size
   97.72 +    static final int EXTLEN = 12;       // uncompressed size
   97.73 +
   97.74 +    /*
   97.75 +     * Central directory (CEN) header field offsets
   97.76 +     */
   97.77 +    static final int CENVEM = 4;        // version made by
   97.78 +    static final int CENVER = 6;        // version needed to extract
   97.79 +    static final int CENFLG = 8;        // encrypt, decrypt flags
   97.80 +    static final int CENHOW = 10;       // compression method
   97.81 +    static final int CENTIM = 12;       // modification time
   97.82 +    static final int CENCRC = 16;       // uncompressed file crc-32 value
   97.83 +    static final int CENSIZ = 20;       // compressed size
   97.84 +    static final int CENLEN = 24;       // uncompressed size
   97.85 +    static final int CENNAM = 28;       // filename length
   97.86 +    static final int CENEXT = 30;       // extra field length
   97.87 +    static final int CENCOM = 32;       // comment length
   97.88 +    static final int CENDSK = 34;       // disk number start
   97.89 +    static final int CENATT = 36;       // internal file attributes
   97.90 +    static final int CENATX = 38;       // external file attributes
   97.91 +    static final int CENOFF = 42;       // LOC header offset
   97.92 +
   97.93 +    /*
   97.94 +     * End of central directory (END) header field offsets
   97.95 +     */
   97.96 +    static final int ENDSUB = 8;        // number of entries on this disk
   97.97 +    static final int ENDTOT = 10;       // total number of entries
   97.98 +    static final int ENDSIZ = 12;       // central directory size in bytes
   97.99 +    static final int ENDOFF = 16;       // offset of first CEN header
  97.100 +    static final int ENDCOM = 20;       // zip file comment length
  97.101 +}
    98.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.2 +++ b/emul/mini/src/main/java/java/util/zip/ZipConstants64.java	Tue Feb 05 17:04:22 2013 +0100
    98.3 @@ -0,0 +1,84 @@
    98.4 +/*
    98.5 + * Copyright (c) 1995, 1996, Oracle and/or its affiliates. All rights reserved.
    98.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    98.7 + *
    98.8 + * This code is free software; you can redistribute it and/or modify it
    98.9 + * under the terms of the GNU General Public License version 2 only, as
   98.10 + * published by the Free Software Foundation.  Oracle designates this
   98.11 + * particular file as subject to the "Classpath" exception as provided
   98.12 + * by Oracle in the LICENSE file that accompanied this code.
   98.13 + *
   98.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   98.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   98.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   98.17 + * version 2 for more details (a copy is included in the LICENSE file that
   98.18 + * accompanied this code).
   98.19 + *
   98.20 + * You should have received a copy of the GNU General Public License version
   98.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   98.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   98.23 + *
   98.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   98.25 + * or visit www.oracle.com if you need additional information or have any
   98.26 + * questions.
   98.27 + */
   98.28 +
   98.29 +package java.util.zip;
   98.30 +
   98.31 +/*
   98.32 + * This class defines the constants that are used by the classes
   98.33 + * which manipulate Zip64 files.
   98.34 + */
   98.35 +
   98.36 +class ZipConstants64 {
   98.37 +
   98.38 +    /*
   98.39 +     * ZIP64 constants
   98.40 +     */
   98.41 +    static final long ZIP64_ENDSIG = 0x06064b50L;  // "PK\006\006"
   98.42 +    static final long ZIP64_LOCSIG = 0x07064b50L;  // "PK\006\007"
   98.43 +    static final int  ZIP64_ENDHDR = 56;           // ZIP64 end header size
   98.44 +    static final int  ZIP64_LOCHDR = 20;           // ZIP64 end loc header size
   98.45 +    static final int  ZIP64_EXTHDR = 24;           // EXT header size
   98.46 +    static final int  ZIP64_EXTID  = 0x0001;       // Extra field Zip64 header ID
   98.47 +
   98.48 +    static final int  ZIP64_MAGICCOUNT = 0xFFFF;
   98.49 +    static final long ZIP64_MAGICVAL = 0xFFFFFFFFL;
   98.50 +
   98.51 +    /*
   98.52 +     * Zip64 End of central directory (END) header field offsets
   98.53 +     */
   98.54 +    static final int  ZIP64_ENDLEN = 4;       // size of zip64 end of central dir
   98.55 +    static final int  ZIP64_ENDVEM = 12;      // version made by
   98.56 +    static final int  ZIP64_ENDVER = 14;      // version needed to extract
   98.57 +    static final int  ZIP64_ENDNMD = 16;      // number of this disk
   98.58 +    static final int  ZIP64_ENDDSK = 20;      // disk number of start
   98.59 +    static final int  ZIP64_ENDTOD = 24;      // total number of entries on this disk
   98.60 +    static final int  ZIP64_ENDTOT = 32;      // total number of entries
   98.61 +    static final int  ZIP64_ENDSIZ = 40;      // central directory size in bytes
   98.62 +    static final int  ZIP64_ENDOFF = 48;      // offset of first CEN header
   98.63 +    static final int  ZIP64_ENDEXT = 56;      // zip64 extensible data sector
   98.64 +
   98.65 +    /*
   98.66 +     * Zip64 End of central directory locator field offsets
   98.67 +     */
   98.68 +    static final int  ZIP64_LOCDSK = 4;       // disk number start
   98.69 +    static final int  ZIP64_LOCOFF = 8;       // offset of zip64 end
   98.70 +    static final int  ZIP64_LOCTOT = 16;      // total number of disks
   98.71 +
   98.72 +    /*
   98.73 +     * Zip64 Extra local (EXT) header field offsets
   98.74 +     */
   98.75 +    static final int  ZIP64_EXTCRC = 4;       // uncompressed file crc-32 value
   98.76 +    static final int  ZIP64_EXTSIZ = 8;       // compressed size, 8-byte
   98.77 +    static final int  ZIP64_EXTLEN = 16;      // uncompressed size, 8-byte
   98.78 +
   98.79 +    /*
   98.80 +     * Language encoding flag EFS
   98.81 +     */
   98.82 +    static final int EFS = 0x800;       // If this bit is set the filename and
   98.83 +                                        // comment fields for this file must be
   98.84 +                                        // encoded using UTF-8.
   98.85 +
   98.86 +    private ZipConstants64() {}
   98.87 +}
    99.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.2 +++ b/emul/mini/src/main/java/java/util/zip/ZipEntry.java	Tue Feb 05 17:04:22 2013 +0100
    99.3 @@ -0,0 +1,331 @@
    99.4 +/*
    99.5 + * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
    99.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    99.7 + *
    99.8 + * This code is free software; you can redistribute it and/or modify it
    99.9 + * under the terms of the GNU General Public License version 2 only, as
   99.10 + * published by the Free Software Foundation.  Oracle designates this
   99.11 + * particular file as subject to the "Classpath" exception as provided
   99.12 + * by Oracle in the LICENSE file that accompanied this code.
   99.13 + *
   99.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   99.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   99.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   99.17 + * version 2 for more details (a copy is included in the LICENSE file that
   99.18 + * accompanied this code).
   99.19 + *
   99.20 + * You should have received a copy of the GNU General Public License version
   99.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   99.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   99.23 + *
   99.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   99.25 + * or visit www.oracle.com if you need additional information or have any
   99.26 + * questions.
   99.27 + */
   99.28 +
   99.29 +package java.util.zip;
   99.30 +
   99.31 +/**
   99.32 + * This class is used to represent a ZIP file entry.
   99.33 + *
   99.34 + * @author      David Connelly
   99.35 + */
   99.36 +public
   99.37 +class ZipEntry implements ZipConstants, Cloneable {
   99.38 +    String name;        // entry name
   99.39 +    long time = -1;     // modification time (in DOS time)
   99.40 +    long crc = -1;      // crc-32 of entry data
   99.41 +    long size = -1;     // uncompressed size of entry data
   99.42 +    long csize = -1;    // compressed size of entry data
   99.43 +    int method = -1;    // compression method
   99.44 +    int flag = 0;       // general purpose flag
   99.45 +    byte[] extra;       // optional extra field data for entry
   99.46 +    String comment;     // optional comment string for entry
   99.47 +
   99.48 +    /**
   99.49 +     * Compression method for uncompressed entries.
   99.50 +     */
   99.51 +    public static final int STORED = 0;
   99.52 +
   99.53 +    /**
   99.54 +     * Compression method for compressed (deflated) entries.
   99.55 +     */
   99.56 +    public static final int DEFLATED = 8;
   99.57 +
   99.58 +    /**
   99.59 +     * Creates a new zip entry with the specified name.
   99.60 +     *
   99.61 +     * @param name the entry name
   99.62 +     * @exception NullPointerException if the entry name is null
   99.63 +     * @exception IllegalArgumentException if the entry name is longer than
   99.64 +     *            0xFFFF bytes
   99.65 +     */
   99.66 +    public ZipEntry(String name) {
   99.67 +        if (name == null) {
   99.68 +            throw new NullPointerException();
   99.69 +        }
   99.70 +        if (name.length() > 0xFFFF) {
   99.71 +            throw new IllegalArgumentException("entry name too long");
   99.72 +        }
   99.73 +        this.name = name;
   99.74 +    }
   99.75 +
   99.76 +    /**
   99.77 +     * Creates a new zip entry with fields taken from the specified
   99.78 +     * zip entry.
   99.79 +     * @param e a zip Entry object
   99.80 +     */
   99.81 +    public ZipEntry(ZipEntry e) {
   99.82 +        name = e.name;
   99.83 +        time = e.time;
   99.84 +        crc = e.crc;
   99.85 +        size = e.size;
   99.86 +        csize = e.csize;
   99.87 +        method = e.method;
   99.88 +        flag = e.flag;
   99.89 +        extra = e.extra;
   99.90 +        comment = e.comment;
   99.91 +    }
   99.92 +
   99.93 +    /*
   99.94 +     * Creates a new un-initialized zip entry
   99.95 +     */
   99.96 +    ZipEntry() {}
   99.97 +
   99.98 +    /**
   99.99 +     * Returns the name of the entry.
  99.100 +     * @return the name of the entry
  99.101 +     */
  99.102 +    public String getName() {
  99.103 +        return name;
  99.104 +    }
  99.105 +
  99.106 +    /**
  99.107 +     * Sets the modification time of the entry.
  99.108 +     * @param time the entry modification time in number of milliseconds
  99.109 +     *             since the epoch
  99.110 +     * @see #getTime()
  99.111 +     */
  99.112 +    public void setTime(long time) {
  99.113 +        this.time = javaToDosTime(time);
  99.114 +    }
  99.115 +
  99.116 +    /**
  99.117 +     * Returns the modification time of the entry, or -1 if not specified.
  99.118 +     * @return the modification time of the entry, or -1 if not specified
  99.119 +     * @see #setTime(long)
  99.120 +     */
  99.121 +    public long getTime() {
  99.122 +        return time != -1 ? dosToJavaTime(time) : -1;
  99.123 +    }
  99.124 +
  99.125 +    /**
  99.126 +     * Sets the uncompressed size of the entry data.
  99.127 +     * @param size the uncompressed size in bytes
  99.128 +     * @exception IllegalArgumentException if the specified size is less
  99.129 +     *            than 0, is greater than 0xFFFFFFFF when
  99.130 +     *            <a href="package-summary.html#zip64">ZIP64 format</a> is not supported,
  99.131 +     *            or is less than 0 when ZIP64 is supported
  99.132 +     * @see #getSize()
  99.133 +     */
  99.134 +    public void setSize(long size) {
  99.135 +        if (size < 0) {
  99.136 +            throw new IllegalArgumentException("invalid entry size");
  99.137 +        }
  99.138 +        this.size = size;
  99.139 +    }
  99.140 +
  99.141 +    /**
  99.142 +     * Returns the uncompressed size of the entry data, or -1 if not known.
  99.143 +     * @return the uncompressed size of the entry data, or -1 if not known
  99.144 +     * @see #setSize(long)
  99.145 +     */
  99.146 +    public long getSize() {
  99.147 +        return size;
  99.148 +    }
  99.149 +
  99.150 +    /**
  99.151 +     * Returns the size of the compressed entry data, or -1 if not known.
  99.152 +     * In the case of a stored entry, the compressed size will be the same
  99.153 +     * as the uncompressed size of the entry.
  99.154 +     * @return the size of the compressed entry data, or -1 if not known
  99.155 +     * @see #setCompressedSize(long)
  99.156 +     */
  99.157 +    public long getCompressedSize() {
  99.158 +        return csize;
  99.159 +    }
  99.160 +
  99.161 +    /**
  99.162 +     * Sets the size of the compressed entry data.
  99.163 +     * @param csize the compressed size to set to
  99.164 +     * @see #getCompressedSize()
  99.165 +     */
  99.166 +    public void setCompressedSize(long csize) {
  99.167 +        this.csize = csize;
  99.168 +    }
  99.169 +
  99.170 +    /**
  99.171 +     * Sets the CRC-32 checksum of the uncompressed entry data.
  99.172 +     * @param crc the CRC-32 value
  99.173 +     * @exception IllegalArgumentException if the specified CRC-32 value is
  99.174 +     *            less than 0 or greater than 0xFFFFFFFF
  99.175 +     * @see #getCrc()
  99.176 +     */
  99.177 +    public void setCrc(long crc) {
  99.178 +        if (crc < 0 || crc > 0xFFFFFFFFL) {
  99.179 +            throw new IllegalArgumentException("invalid entry crc-32");
  99.180 +        }
  99.181 +        this.crc = crc;
  99.182 +    }
  99.183 +
  99.184 +    /**
  99.185 +     * Returns the CRC-32 checksum of the uncompressed entry data, or -1 if
  99.186 +     * not known.
  99.187 +     * @return the CRC-32 checksum of the uncompressed entry data, or -1 if
  99.188 +     * not known
  99.189 +     * @see #setCrc(long)
  99.190 +     */
  99.191 +    public long getCrc() {
  99.192 +        return crc;
  99.193 +    }
  99.194 +
  99.195 +    /**
  99.196 +     * Sets the compression method for the entry.
  99.197 +     * @param method the compression method, either STORED or DEFLATED
  99.198 +     * @exception IllegalArgumentException if the specified compression
  99.199 +     *            method is invalid
  99.200 +     * @see #getMethod()
  99.201 +     */
  99.202 +    public void setMethod(int method) {
  99.203 +        if (method != STORED && method != DEFLATED) {
  99.204 +            throw new IllegalArgumentException("invalid compression method");
  99.205 +        }
  99.206 +        this.method = method;
  99.207 +    }
  99.208 +
  99.209 +    /**
  99.210 +     * Returns the compression method of the entry, or -1 if not specified.
  99.211 +     * @return the compression method of the entry, or -1 if not specified
  99.212 +     * @see #setMethod(int)
  99.213 +     */
  99.214 +    public int getMethod() {
  99.215 +        return method;
  99.216 +    }
  99.217 +
  99.218 +    /**
  99.219 +     * Sets the optional extra field data for the entry.
  99.220 +     * @param extra the extra field data bytes
  99.221 +     * @exception IllegalArgumentException if the length of the specified
  99.222 +     *            extra field data is greater than 0xFFFF bytes
  99.223 +     * @see #getExtra()
  99.224 +     */
  99.225 +    public void setExtra(byte[] extra) {
  99.226 +        if (extra != null && extra.length > 0xFFFF) {
  99.227 +            throw new IllegalArgumentException("invalid extra field length");
  99.228 +        }
  99.229 +        this.extra = extra;
  99.230 +    }
  99.231 +
  99.232 +    /**
  99.233 +     * Returns the extra field data for the entry, or null if none.
  99.234 +     * @return the extra field data for the entry, or null if none
  99.235 +     * @see #setExtra(byte[])
  99.236 +     */
  99.237 +    public byte[] getExtra() {
  99.238 +        return extra;
  99.239 +    }
  99.240 +
  99.241 +    /**
  99.242 +     * Sets the optional comment string for the entry.
  99.243 +     *
  99.244 +     * <p>ZIP entry comments have maximum length of 0xffff. If the length of the
  99.245 +     * specified comment string is greater than 0xFFFF bytes after encoding, only
  99.246 +     * the first 0xFFFF bytes are output to the ZIP file entry.
  99.247 +     *
  99.248 +     * @param comment the comment string
  99.249 +     *
  99.250 +     * @see #getComment()
  99.251 +     */
  99.252 +    public void setComment(String comment) {
  99.253 +        this.comment = comment;
  99.254 +    }
  99.255 +
  99.256 +    /**
  99.257 +     * Returns the comment string for the entry, or null if none.
  99.258 +     * @return the comment string for the entry, or null if none
  99.259 +     * @see #setComment(String)
  99.260 +     */
  99.261 +    public String getComment() {
  99.262 +        return comment;
  99.263 +    }
  99.264 +
  99.265 +    /**
  99.266 +     * Returns true if this is a directory entry. A directory entry is
  99.267 +     * defined to be one whose name ends with a '/'.
  99.268 +     * @return true if this is a directory entry
  99.269 +     */
  99.270 +    public boolean isDirectory() {
  99.271 +        return name.endsWith("/");
  99.272 +    }
  99.273 +
  99.274 +    /**
  99.275 +     * Returns a string representation of the ZIP entry.
  99.276 +     */
  99.277 +    public String toString() {
  99.278 +        return getName();
  99.279 +    }
  99.280 +
  99.281 +    /*
  99.282 +     * Converts DOS time to Java time (number of milliseconds since epoch).
  99.283 +     */
  99.284 +    private static long dosToJavaTime(long dtime) {
  99.285 +        return dtime;
  99.286 +        /* XXX:
  99.287 +        Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
  99.288 +                          (int)(((dtime >> 21) & 0x0f) - 1),
  99.289 +                          (int)((dtime >> 16) & 0x1f),
  99.290 +                          (int)((dtime >> 11) & 0x1f),
  99.291 +                          (int)((dtime >> 5) & 0x3f),
  99.292 +                          (int)((dtime << 1) & 0x3e));
  99.293 +        return d.getTime();
  99.294 +        */
  99.295 +    }
  99.296 +
  99.297 +    /*
  99.298 +     * Converts Java time to DOS time.
  99.299 +     */
  99.300 +    private static long javaToDosTime(long time) {
  99.301 +        return time;
  99.302 +        /* XXX:
  99.303 +        Date d = new Date(time);
  99.304 +        int year = d.getYear() + 1900;
  99.305 +        if (year < 1980) {
  99.306 +            return (1 << 21) | (1 << 16);
  99.307 +        }
  99.308 +        return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
  99.309 +               d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
  99.310 +               d.getSeconds() >> 1;
  99.311 +        */
  99.312 +    }
  99.313 +
  99.314 +    /**
  99.315 +     * Returns the hash code value for this entry.
  99.316 +     */
  99.317 +    public int hashCode() {
  99.318 +        return name.hashCode();
  99.319 +    }
  99.320 +
  99.321 +    /**
  99.322 +     * Returns a copy of this entry.
  99.323 +     */
  99.324 +    public Object clone() {
  99.325 +        try {
  99.326 +            ZipEntry e = (ZipEntry)super.clone();
  99.327 +            e.extra = (extra == null) ? null : extra.clone();
  99.328 +            return e;
  99.329 +        } catch (CloneNotSupportedException e) {
  99.330 +            // This should never happen, since we are Cloneable
  99.331 +            throw new IllegalStateException();
  99.332 +        }
  99.333 +    }
  99.334 +}
   100.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   100.2 +++ b/emul/mini/src/main/java/java/util/zip/ZipException.java	Tue Feb 05 17:04:22 2013 +0100
   100.3 @@ -0,0 +1,60 @@
   100.4 +/*
   100.5 + * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
   100.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   100.7 + *
   100.8 + * This code is free software; you can redistribute it and/or modify it
   100.9 + * under the terms of the GNU General Public License version 2 only, as
  100.10 + * published by the Free Software Foundation.  Oracle designates this
  100.11 + * particular file as subject to the "Classpath" exception as provided
  100.12 + * by Oracle in the LICENSE file that accompanied this code.
  100.13 + *
  100.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
  100.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  100.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  100.17 + * version 2 for more details (a copy is included in the LICENSE file that
  100.18 + * accompanied this code).
  100.19 + *
  100.20 + * You should have received a copy of the GNU General Public License version
  100.21 + * 2 along with this work; if not, write to the Free Software Foundation,
  100.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  100.23 + *
  100.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  100.25 + * or visit www.oracle.com if you need additional information or have any
  100.26 + * questions.
  100.27 + */
  100.28 +
  100.29 +package java.util.zip;
  100.30 +
  100.31 +import java.io.IOException;
  100.32 +
  100.33 +/**
  100.34 + * Signals that a Zip exception of some sort has occurred.
  100.35 + *
  100.36 + * @author  unascribed
  100.37 + * @see     java.io.IOException
  100.38 + * @since   JDK1.0
  100.39 + */
  100.40 +
  100.41 +public
  100.42 +class ZipException extends IOException {
  100.43 +    private static final long serialVersionUID = 8000196834066748623L;
  100.44 +
  100.45 +    /**
  100.46 +     * Constructs a <code>ZipException</code> with <code>null</code>
  100.47 +     * as its error detail message.
  100.48 +     */
  100.49 +    public ZipException() {
  100.50 +        super();
  100.51 +    }
  100.52 +
  100.53 +    /**
  100.54 +     * Constructs a <code>ZipException</code> with the specified detail
  100.55 +     * message.
  100.56 +     *
  100.57 +     * @param   s   the detail message.
  100.58 +     */
  100.59 +
  100.60 +    public ZipException(String s) {
  100.61 +        super(s);
  100.62 +    }
  100.63 +}
   101.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.2 +++ b/emul/mini/src/main/java/java/util/zip/ZipInputStream.java	Tue Feb 05 17:04:22 2013 +0100
   101.3 @@ -0,0 +1,467 @@
   101.4 +/*
   101.5 + * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
   101.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   101.7 + *
   101.8 + * This code is free software; you can redistribute it and/or modify it
   101.9 + * under the terms of the GNU General Public License version 2 only, as
  101.10 + * published by the Free Software Foundation.  Oracle designates this
  101.11 + * particular file as subject to the "Classpath" exception as provided
  101.12 + * by Oracle in the LICENSE file that accompanied this code.
  101.13 + *
  101.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
  101.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  101.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  101.17 + * version 2 for more details (a copy is included in the LICENSE file that
  101.18 + * accompanied this code).
  101.19 + *
  101.20 + * You should have received a copy of the GNU General Public License version
  101.21 + * 2 along with this work; if not, write to the Free Software Foundation,
  101.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  101.23 + *
  101.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  101.25 + * or visit www.oracle.com if you need additional information or have any
  101.26 + * questions.
  101.27 + */
  101.28 +
  101.29 +package java.util.zip;
  101.30 +
  101.31 +import java.io.InputStream;
  101.32 +import java.io.IOException;
  101.33 +import java.io.EOFException;
  101.34 +import java.io.PushbackInputStream;
  101.35 +import static java.util.zip.ZipConstants64.*;
  101.36 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
  101.37 +
  101.38 +/**
  101.39 + * This class implements an input stream filter for reading files in the
  101.40 + * ZIP file format. Includes support for both compressed and uncompressed
  101.41 + * entries.
  101.42 + *
  101.43 + * @author      David Connelly
  101.44 + */
  101.45 +public
  101.46 +class ZipInputStream extends InflaterInputStream implements ZipConstants {
  101.47 +    private ZipEntry entry;
  101.48 +    private int flag;
  101.49 +    private CRC32 crc = new CRC32();
  101.50 +    private long remaining;
  101.51 +    private byte[] tmpbuf = new byte[512];
  101.52 +
  101.53 +    private static final int STORED = ZipEntry.STORED;
  101.54 +    private static final int DEFLATED = ZipEntry.DEFLATED;
  101.55 +
  101.56 +    private boolean closed = false;
  101.57 +    // this flag is set to true after EOF has reached for
  101.58 +    // one entry
  101.59 +    private boolean entryEOF = false;
  101.60 +
  101.61 +    /**
  101.62 +     * Check to make sure that this stream has not been closed
  101.63 +     */
  101.64 +    private void ensureOpen() throws IOException {
  101.65 +        if (closed) {
  101.66 +            throw new IOException("Stream closed");
  101.67 +        }
  101.68 +    }
  101.69 +
  101.70 +    /**
  101.71 +     * Creates a new ZIP input stream.
  101.72 +     *
  101.73 +     * <p>The UTF-8 {@link java.nio.charset.Charset charset} is used to
  101.74 +     * decode the entry names.
  101.75 +     *
  101.76 +     * @param in the actual input stream
  101.77 +     */
  101.78 +    public ZipInputStream(InputStream in) {
  101.79 +//        this(in, "UTF-8");
  101.80 +        super(new PushbackInputStream(in, 512), new Inflater(true), 512);
  101.81 +        usesDefaultInflater = true;
  101.82 +        if(in == null) {
  101.83 +            throw new NullPointerException("in is null");
  101.84 +        }
  101.85 +    }
  101.86 +
  101.87 +    /**
  101.88 +     * Creates a new ZIP input stream.
  101.89 +     *
  101.90 +     * @param in the actual input stream
  101.91 +     *
  101.92 +     * @param charset
  101.93 +     *        The {@linkplain java.nio.charset.Charset charset} to be
  101.94 +     *        used to decode the ZIP entry name (ignored if the
  101.95 +     *        <a href="package-summary.html#lang_encoding"> language
  101.96 +     *        encoding bit</a> of the ZIP entry's general purpose bit
  101.97 +     *        flag is set).
  101.98 +     *
  101.99 +     * @since 1.7
 101.100 +     *
 101.101 +    public ZipInputStream(InputStream in, Charset charset) {
 101.102 +        super(new PushbackInputStream(in, 512), new Inflater(true), 512);
 101.103 +        usesDefaultInflater = true;
 101.104 +        if(in == null) {
 101.105 +            throw new NullPointerException("in is null");
 101.106 +        }
 101.107 +        if (charset == null)
 101.108 +            throw new NullPointerException("charset is null");
 101.109 +        this.zc = ZipCoder.get(charset);
 101.110 +    }
 101.111 +    */
 101.112 +
 101.113 +    /**
 101.114 +     * Reads the next ZIP file entry and positions the stream at the
 101.115 +     * beginning of the entry data.
 101.116 +     * @return the next ZIP file entry, or null if there are no more entries
 101.117 +     * @exception ZipException if a ZIP file error has occurred
 101.118 +     * @exception IOException if an I/O error has occurred
 101.119 +     */
 101.120 +    public ZipEntry getNextEntry() throws IOException {
 101.121 +        ensureOpen();
 101.122 +        if (entry != null) {
 101.123 +            closeEntry();
 101.124 +        }
 101.125 +        crc.reset();
 101.126 +        inf.reset();
 101.127 +        if ((entry = readLOC()) == null) {
 101.128 +            return null;
 101.129 +        }
 101.130 +        if (entry.method == STORED) {
 101.131 +            remaining = entry.size;
 101.132 +        }
 101.133 +        entryEOF = false;
 101.134 +        return entry;
 101.135 +    }
 101.136 +
 101.137 +    /**
 101.138 +     * Closes the current ZIP entry and positions the stream for reading the
 101.139 +     * next entry.
 101.140 +     * @exception ZipException if a ZIP file error has occurred
 101.141 +     * @exception IOException if an I/O error has occurred
 101.142 +     */
 101.143 +    public void closeEntry() throws IOException {
 101.144 +        ensureOpen();
 101.145 +        while (read(tmpbuf, 0, tmpbuf.length) != -1) ;
 101.146 +        entryEOF = true;
 101.147 +    }
 101.148 +
 101.149 +    /**
 101.150 +     * Returns 0 after EOF has reached for the current entry data,
 101.151 +     * otherwise always return 1.
 101.152 +     * <p>
 101.153 +     * Programs should not count on this method to return the actual number
 101.154 +     * of bytes that could be read without blocking.
 101.155 +     *
 101.156 +     * @return     1 before EOF and 0 after EOF has reached for current entry.
 101.157 +     * @exception  IOException  if an I/O error occurs.
 101.158 +     *
 101.159 +     */
 101.160 +    public int available() throws IOException {
 101.161 +        ensureOpen();
 101.162 +        if (entryEOF) {
 101.163 +            return 0;
 101.164 +        } else {
 101.165 +            return 1;
 101.166 +        }
 101.167 +    }
 101.168 +
 101.169 +    /**
 101.170 +     * Reads from the current ZIP entry into an array of bytes.
 101.171 +     * If <code>len</code> is not zero, the method
 101.172 +     * blocks until some input is available; otherwise, no
 101.173 +     * bytes are read and <code>0</code> is returned.
 101.174 +     * @param b the buffer into which the data is read
 101.175 +     * @param off the start offset in the destination array <code>b</code>
 101.176 +     * @param len the maximum number of bytes read
 101.177 +     * @return the actual number of bytes read, or -1 if the end of the
 101.178 +     *         entry is reached
 101.179 +     * @exception  NullPointerException if <code>b</code> is <code>null</code>.
 101.180 +     * @exception  IndexOutOfBoundsException if <code>off</code> is negative,
 101.181 +     * <code>len</code> is negative, or <code>len</code> is greater than
 101.182 +     * <code>b.length - off</code>
 101.183 +     * @exception ZipException if a ZIP file error has occurred
 101.184 +     * @exception IOException if an I/O error has occurred
 101.185 +     */
 101.186 +    public int read(byte[] b, int off, int len) throws IOException {
 101.187 +        ensureOpen();
 101.188 +        if (off < 0 || len < 0 || off > b.length - len) {
 101.189 +            throw new IndexOutOfBoundsException();
 101.190 +        } else if (len == 0) {
 101.191 +            return 0;
 101.192 +        }
 101.193 +
 101.194 +        if (entry == null) {
 101.195 +            return -1;
 101.196 +        }
 101.197 +        switch (entry.method) {
 101.198 +        case DEFLATED:
 101.199 +            len = super.read(b, off, len);
 101.200 +            if (len == -1) {
 101.201 +                readEnd(entry);
 101.202 +                entryEOF = true;
 101.203 +                entry = null;
 101.204 +            } else {
 101.205 +                crc.update(b, off, len);
 101.206 +            }
 101.207 +            return len;
 101.208 +        case STORED:
 101.209 +            if (remaining <= 0) {
 101.210 +                entryEOF = true;
 101.211 +                entry = null;
 101.212 +                return -1;
 101.213 +            }
 101.214 +            if (len > remaining) {
 101.215 +                len = (int)remaining;
 101.216 +            }
 101.217 +            len = in.read(b, off, len);
 101.218 +            if (len == -1) {
 101.219 +                throw new ZipException("unexpected EOF");
 101.220 +            }
 101.221 +            crc.update(b, off, len);
 101.222 +            remaining -= len;
 101.223 +            if (remaining == 0 && entry.crc != crc.getValue()) {
 101.224 +                throw new ZipException(
 101.225 +                    "invalid entry CRC (expected 0x" + Long.toHexString(entry.crc) +
 101.226 +                    " but got 0x" + Long.toHexString(crc.getValue()) + ")");
 101.227 +            }
 101.228 +            return len;
 101.229 +        default:
 101.230 +            throw new ZipException("invalid compression method");
 101.231 +        }
 101.232 +    }
 101.233 +
 101.234 +    /**
 101.235 +     * Skips specified number of bytes in the current ZIP entry.
 101.236 +     * @param n the number of bytes to skip
 101.237 +     * @return the actual number of bytes skipped
 101.238 +     * @exception ZipException if a ZIP file error has occurred
 101.239 +     * @exception IOException if an I/O error has occurred
 101.240 +     * @exception IllegalArgumentException if n < 0
 101.241 +     */
 101.242 +    public long skip(long n) throws IOException {
 101.243 +        if (n < 0) {
 101.244 +            throw new IllegalArgumentException("negative skip length");
 101.245 +        }
 101.246 +        ensureOpen();
 101.247 +        int max = (int)Math.min(n, Integer.MAX_VALUE);
 101.248 +        int total = 0;
 101.249 +        while (total < max) {
 101.250 +            int len = max - total;
 101.251 +            if (len > tmpbuf.length) {
 101.252 +                len = tmpbuf.length;
 101.253 +            }
 101.254 +            len = read(tmpbuf, 0, len);
 101.255 +            if (len == -1) {
 101.256 +                entryEOF = true;
 101.257 +                break;
 101.258 +            }
 101.259 +            total += len;
 101.260 +        }
 101.261 +        return total;
 101.262 +    }
 101.263 +
 101.264 +    /**
 101.265 +     * Closes this input stream and releases any system resources associated
 101.266 +     * with the stream.
 101.267 +     * @exception IOException if an I/O error has occurred
 101.268 +     */
 101.269 +    public void close() throws IOException {
 101.270 +        if (!closed) {
 101.271 +            super.close();
 101.272 +            closed = true;
 101.273 +        }
 101.274 +    }
 101.275 +
 101.276 +    private byte[] b = new byte[256];
 101.277 +
 101.278 +    /*
 101.279 +     * Reads local file (LOC) header for next entry.
 101.280 +     */
 101.281 +    private ZipEntry readLOC() throws IOException {
 101.282 +        try {
 101.283 +            readFully(tmpbuf, 0, LOCHDR);
 101.284 +        } catch (EOFException e) {
 101.285 +            return null;
 101.286 +        }
 101.287 +        if (get32(tmpbuf, 0) != LOCSIG) {
 101.288 +            return null;
 101.289 +        }
 101.290 +        // get flag first, we need check EFS.
 101.291 +        flag = get16(tmpbuf, LOCFLG);
 101.292 +        // get the entry name and create the ZipEntry first
 101.293 +        int len = get16(tmpbuf, LOCNAM);
 101.294 +        int blen = b.length;
 101.295 +        if (len > blen) {
 101.296 +            do
 101.297 +                blen = blen * 2;
 101.298 +            while (len > blen);
 101.299 +            b = new byte[blen];
 101.300 +        }
 101.301 +        readFully(b, 0, len);
 101.302 +        // Force to use UTF-8 if the EFS bit is ON, even the cs is NOT UTF-8
 101.303 +        ZipEntry e = createZipEntry(((flag & EFS) != 0)
 101.304 +                                    ? toStringUTF8(b, len)
 101.305 +                                    : toString(b, len));
 101.306 +        // now get the remaining fields for the entry
 101.307 +        if ((flag & 1) == 1) {
 101.308 +            throw new ZipException("encrypted ZIP entry not supported");
 101.309 +        }
 101.310 +        e.method = get16(tmpbuf, LOCHOW);
 101.311 +        e.time = get32(tmpbuf, LOCTIM);
 101.312 +        if ((flag & 8) == 8) {
 101.313 +            /* "Data Descriptor" present */
 101.314 +            if (e.method != DEFLATED) {
 101.315 +                throw new ZipException(
 101.316 +                        "only DEFLATED entries can have EXT descriptor");
 101.317 +            }
 101.318 +        } else {
 101.319 +            e.crc = get32(tmpbuf, LOCCRC);
 101.320 +            e.csize = get32(tmpbuf, LOCSIZ);
 101.321 +            e.size = get32(tmpbuf, LOCLEN);
 101.322 +        }
 101.323 +        len = get16(tmpbuf, LOCEXT);
 101.324 +        if (len > 0) {
 101.325 +            byte[] bb = new byte[len];
 101.326 +            readFully(bb, 0, len);
 101.327 +            e.setExtra(bb);
 101.328 +            // extra fields are in "HeaderID(2)DataSize(2)Data... format
 101.329 +            if (e.csize == ZIP64_MAGICVAL || e.size == ZIP64_MAGICVAL) {
 101.330 +                int off = 0;
 101.331 +                while (off + 4 < len) {
 101.332 +                    int sz = get16(bb, off + 2);
 101.333 +                    if (get16(bb, off) == ZIP64_EXTID) {
 101.334 +                        off += 4;
 101.335 +                        // LOC extra zip64 entry MUST include BOTH original and
 101.336 +                        // compressed file size fields
 101.337 +                        if (sz < 16 || (off + sz) > len ) {
 101.338 +                            // Invalid zip64 extra fields, simply skip. Even it's
 101.339 +                            // rare, it's possible the entry size happens to be
 101.340 +                            // the magic value and it "accidnetly" has some bytes
 101.341 +                            // in extra match the id.
 101.342 +                            return e;
 101.343 +                        }
 101.344 +                        e.size = get64(bb, off);
 101.345 +                        e.csize = get64(bb, off + 8);
 101.346 +                        break;
 101.347 +                    }
 101.348 +                    off += (sz + 4);
 101.349 +                }
 101.350 +            }
 101.351 +        }
 101.352 +        return e;
 101.353 +    }
 101.354 +
 101.355 +    /**
 101.356 +     * Creates a new <code>ZipEntry</code> object for the specified
 101.357 +     * entry name.
 101.358 +     *
 101.359 +     * @param name the ZIP file entry name
 101.360 +     * @return the ZipEntry just created
 101.361 +     */
 101.362 +    protected ZipEntry createZipEntry(String name) {
 101.363 +        return new ZipEntry(name);
 101.364 +    }
 101.365 +
 101.366 +    /*
 101.367 +     * Reads end of deflated entry as well as EXT descriptor if present.
 101.368 +     */
 101.369 +    private void readEnd(ZipEntry e) throws IOException {
 101.370 +        int n = inf.getRemaining();
 101.371 +        if (n > 0) {
 101.372 +            ((PushbackInputStream)in).unread(buf, len - n, n);
 101.373 +        }
 101.374 +        if ((flag & 8) == 8) {
 101.375 +            /* "Data Descriptor" present */
 101.376 +            if (inf.getBytesWritten() > ZIP64_MAGICVAL ||
 101.377 +                inf.getBytesRead() > ZIP64_MAGICVAL) {
 101.378 +                // ZIP64 format
 101.379 +                readFully(tmpbuf, 0, ZIP64_EXTHDR);
 101.380 +                long sig = get32(tmpbuf, 0);
 101.381 +                if (sig != EXTSIG) { // no EXTSIG present
 101.382 +                    e.crc = sig;
 101.383 +                    e.csize = get64(tmpbuf, ZIP64_EXTSIZ - ZIP64_EXTCRC);
 101.384 +                    e.size = get64(tmpbuf, ZIP64_EXTLEN - ZIP64_EXTCRC);
 101.385 +                    ((PushbackInputStream)in).unread(
 101.386 +                        tmpbuf, ZIP64_EXTHDR - ZIP64_EXTCRC - 1, ZIP64_EXTCRC);
 101.387 +                } else {
 101.388 +                    e.crc = get32(tmpbuf, ZIP64_EXTCRC);
 101.389 +                    e.csize = get64(tmpbuf, ZIP64_EXTSIZ);
 101.390 +                    e.size = get64(tmpbuf, ZIP64_EXTLEN);
 101.391 +                }
 101.392 +            } else {
 101.393 +                readFully(tmpbuf, 0, EXTHDR);
 101.394 +                long sig = get32(tmpbuf, 0);
 101.395 +                if (sig != EXTSIG) { // no EXTSIG present
 101.396 +                    e.crc = sig;
 101.397 +                    e.csize = get32(tmpbuf, EXTSIZ - EXTCRC);
 101.398 +                    e.size = get32(tmpbuf, EXTLEN - EXTCRC);
 101.399 +                    ((PushbackInputStream)in).unread(
 101.400 +                                               tmpbuf, EXTHDR - EXTCRC - 1, EXTCRC);
 101.401 +                } else {
 101.402 +                    e.crc = get32(tmpbuf, EXTCRC);
 101.403 +                    e.csize = get32(tmpbuf, EXTSIZ);
 101.404 +                    e.size = get32(tmpbuf, EXTLEN);
 101.405 +                }
 101.406 +            }
 101.407 +        }
 101.408 +        if (e.size != inf.getBytesWritten()) {
 101.409 +            throw new ZipException(
 101.410 +                "invalid entry size (expected " + e.size +
 101.411 +                " but got " + inf.getBytesWritten() + " bytes)");
 101.412 +        }
 101.413 +        if (e.csize != inf.getBytesRead()) {
 101.414 +            throw new ZipException(
 101.415 +                "invalid entry compressed size (expected " + e.csize +
 101.416 +                " but got " + inf.getBytesRead() + " bytes)");
 101.417 +        }
 101.418 +        if (e.crc != crc.getValue()) {
 101.419 +            throw new ZipException(
 101.420 +                "invalid entry CRC (expected 0x" + Long.toHexString(e.crc) +
 101.421 +                " but got 0x" + Long.toHexString(crc.getValue()) + ")");
 101.422 +        }
 101.423 +    }
 101.424 +
 101.425 +    /*
 101.426 +     * Reads bytes, blocking until all bytes are read.
 101.427 +     */
 101.428 +    private void readFully(byte[] b, int off, int len) throws IOException {
 101.429 +        while (len > 0) {
 101.430 +            int n = in.read(b, off, len);
 101.431 +            if (n == -1) {
 101.432 +                throw new EOFException();
 101.433 +            }
 101.434 +            off += n;
 101.435 +            len -= n;
 101.436 +        }
 101.437 +    }
 101.438 +
 101.439 +    /*
 101.440 +     * Fetches unsigned 16-bit value from byte array at specified offset.
 101.441 +     * The bytes are assumed to be in Intel (little-endian) byte order.
 101.442 +     */
 101.443 +    private static final int get16(byte b[], int off) {
 101.444 +        return (b[off] & 0xff) | ((b[off+1] & 0xff) << 8);
 101.445 +    }
 101.446 +
 101.447 +    /*
 101.448 +     * Fetches unsigned 32-bit value from byte array at specified offset.
 101.449 +     * The bytes are assumed to be in Intel (little-endian) byte order.
 101.450 +     */
 101.451 +    private static final long get32(byte b[], int off) {
 101.452 +        return (get16(b, off) | ((long)get16(b, off+2) << 16)) & 0xffffffffL;
 101.453 +    }
 101.454 +
 101.455 +    /*
 101.456 +     * Fetches signed 64-bit value from byte array at specified offset.
 101.457 +     * The bytes are assumed to be in Intel (little-endian) byte order.
 101.458 +     */
 101.459 +    private static final long get64(byte b[], int off) {
 101.460 +        return get32(b, off) | (get32(b, off+4) << 32);
 101.461 +    }
 101.462 +
 101.463 +    private static String toStringUTF8(byte[] arr, int len) {
 101.464 +        return new String(arr, 0, len);
 101.465 +    }
 101.466 +    
 101.467 +    private static String toString(byte[] b, int len) {
 101.468 +        return new String(b, 0, len);
 101.469 +    }
 101.470 +}
   102.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.2 +++ b/emul/mini/src/main/java/java/util/zip/package.html	Tue Feb 05 17:04:22 2013 +0100
   102.3 @@ -0,0 +1,98 @@
   102.4 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
   102.5 +<html>
   102.6 +<head>
   102.7 +<!--
   102.8 +Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
   102.9 +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  102.10 +
  102.11 +This code is free software; you can redistribute it and/or modify it
  102.12 +under the terms of the GNU General Public License version 2 only, as
  102.13 +published by the Free Software Foundation.  Oracle designates this
  102.14 +particular file as subject to the "Classpath" exception as provided
  102.15 +by Oracle in the LICENSE file that accompanied this code.
  102.16 +
  102.17 +This code is distributed in the hope that it will be useful, but WITHOUT
  102.18 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  102.19 +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  102.20 +version 2 for more details (a copy is included in the LICENSE file that
  102.21 +accompanied this code).
  102.22 +
  102.23 +You should have received a copy of the GNU General Public License version
  102.24 +2 along with this work; if not, write to the Free Software Foundation,
  102.25 +Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  102.26 +
  102.27 +Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  102.28 +or visit www.oracle.com if you need additional information or have any
  102.29 +questions.
  102.30 +-->
  102.31 +
  102.32 +</head>
  102.33 +<body bgcolor="white">
  102.34 +
  102.35 +Provides classes for reading and writing the standard ZIP and GZIP
  102.36 +file formats.  Also includes classes for compressing and decompressing
  102.37 +data using the DEFLATE compression algorithm, which is used by the
  102.38 +ZIP and GZIP file formats. Additionally, there are utility classes
  102.39 +for computing the CRC-32 and Adler-32 checksums of arbitrary
  102.40 +input streams.
  102.41 +
  102.42 +
  102.43 +<h2>Package Specification</h2>
  102.44 +
  102.45 +</a>
  102.46 +<ul>
  102.47 +  <li><a href="ftp://ftp.uu.net/pub/archiving/zip/doc/appnote-970311-iz.zip">
  102.48 +      Info-ZIP Application Note 970311
  102.49 +      </a> - a detailed description of the Info-ZIP format upon which
  102.50 +      the <code>java.util.zip</code> classes are based.
  102.51 +<p>
  102.52 +  <a name="zip64">
  102.53 +  <li>An implementation may optionally support the ZIP64(tm) format extensions
  102.54 +      defined by the 
  102.55 +      <a href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">
  102.56 +      PKWARE ZIP File Format Specification</a>. The ZIP64(tm) format extensions
  102.57 +      are used to overcome the size limitations of the original ZIP format.
  102.58 +<p>
  102.59 +  <a name="lang_encoding">
  102.60 +  <li>APPENDIX D of <a href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">
  102.61 +      PKWARE ZIP File Format Specification</a> - Language Encoding Flag (EFS) to
  102.62 +      encode ZIP entry filename and comment fields using UTF-8.
  102.63 +<p>
  102.64 +  <li><a href="http://www.ietf.org/rfc/rfc1950.txt">
  102.65 +      ZLIB Compressed Data Format Specification version 3.3</a>
  102.66 +      &nbsp;
  102.67 +      <a href="http://www.ietf.org/rfc/rfc1950.txt.pdf">(pdf)</a>
  102.68 +      (RFC 1950)
  102.69 +<p>
  102.70 +  <li><a href="http://www.ietf.org/rfc/rfc1951.txt">
  102.71 +      DEFLATE Compressed Data Format Specification version 1.3</a>
  102.72 +      &nbsp;
  102.73 +      <a href="http://www.ietf.org/rfc/rfc1951.txt.pdf">(pdf)</a>
  102.74 +      (RFC 1951)
  102.75 +<p>
  102.76 +  <li><a href="http://www.ietf.org/rfc/rfc1952.txt">
  102.77 +      GZIP file format specification version 4.3</a>
  102.78 +      &nbsp;
  102.79 +      <a href="http://www.ietf.org/rfc/rfc1952.txt.pdf">(pdf)</a>
  102.80 +      (RFC 1952)
  102.81 +<p>
  102.82 +  <li>CRC-32 checksum is described in RFC 1952 (above)
  102.83 +<p>
  102.84 +  <li>Adler-32 checksum is described in RFC 1950 (above)
  102.85 +</ul>
  102.86 +
  102.87 +
  102.88 +<!--
  102.89 +<h2>Related Documentation</h2>
  102.90 +
  102.91 +For overviews, tutorials, examples, guides, and tool documentation, please see:
  102.92 +<ul>
  102.93 +  <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a>
  102.94 +</ul>
  102.95 +-->
  102.96 +
  102.97 +@since JDK1.1
  102.98 +</body>
  102.99 +</html>
 102.100 +
 102.101 +
   103.1 --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java	Tue Feb 05 16:40:01 2013 +0100
   103.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java	Tue Feb 05 17:04:22 2013 +0100
   103.3 @@ -39,4 +39,19 @@
   103.4          "}"
   103.5      )
   103.6      public static native void arraycopy(Object value, int srcBegin, Object dst, int dstBegin, int count);
   103.7 +
   103.8 +    @JavaScriptBody(args = { "arr", "expectedSize" }, body = 
   103.9 +        "while (expectedSize-- > arr.length) { arr.push(0); }; return arr;"
  103.10 +    )
  103.11 +    public static native byte[] expandArray(byte[] arr, int expectedSize);
  103.12 +
  103.13 +    @JavaScriptBody(args = {}, body = "new Date().getMilliseconds();")
  103.14 +    public static native long currentTimeMillis();
  103.15 +    
  103.16 +    public static long nanoTime() {
  103.17 +        return 1000000L * currentTimeMillis();
  103.18 +    }
  103.19 +    @JavaScriptBody(args = { "obj" }, body="return vm.java_lang_Object(false).hashCode__I.call(obj);")
  103.20 +    public static native int identityHashCode(Object obj);
  103.21 +    
  103.22  }
   104.1 --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java	Tue Feb 05 16:40:01 2013 +0100
   104.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java	Tue Feb 05 17:04:22 2013 +0100
   104.3 @@ -1,26 +1,19 @@
   104.4 -/*
   104.5 - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
   104.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   104.7 +/**
   104.8 + * Back 2 Browser Bytecode Translator
   104.9 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
  104.10   *
  104.11 - * This code is free software; you can redistribute it and/or modify it
  104.12 - * under the terms of the GNU General Public License version 2 only, as
  104.13 - * published by the Free Software Foundation.  Oracle designates this
  104.14 - * particular file as subject to the "Classpath" exception as provided
  104.15 - * by Oracle in the LICENSE file that accompanied this code.
  104.16 + * This program is free software: you can redistribute it and/or modify
  104.17 + * it under the terms of the GNU General Public License as published by
  104.18 + * the Free Software Foundation, version 2 of the License.
  104.19   *
  104.20 - * This code is distributed in the hope that it will be useful, but WITHOUT
  104.21 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  104.22 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  104.23 - * version 2 for more details (a copy is included in the LICENSE file that
  104.24 - * accompanied this code).
  104.25 + * This program is distributed in the hope that it will be useful,
  104.26 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  104.27 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  104.28 + * GNU General Public License for more details.
  104.29   *
  104.30 - * You should have received a copy of the GNU General Public License version
  104.31 - * 2 along with this work; if not, write to the Free Software Foundation,
  104.32 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  104.33 - *
  104.34 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  104.35 - * or visit www.oracle.com if you need additional information or have any
  104.36 - * questions.
  104.37 + * You should have received a copy of the GNU General Public License
  104.38 + * along with this program. Look for COPYING file in the top folder.
  104.39 + * If not, see http://opensource.org/licenses/GPL-2.0.
  104.40   */
  104.41  package org.apidesign.bck2brwsr.emul.reflect;
  104.42  
   105.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   105.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/TypeProvider.java	Tue Feb 05 17:04:22 2013 +0100
   105.3 @@ -0,0 +1,40 @@
   105.4 +/**
   105.5 + * Back 2 Browser Bytecode Translator
   105.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   105.7 + *
   105.8 + * This program is free software: you can redistribute it and/or modify
   105.9 + * it under the terms of the GNU General Public License as published by
  105.10 + * the Free Software Foundation, version 2 of the License.
  105.11 + *
  105.12 + * This program is distributed in the hope that it will be useful,
  105.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  105.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  105.15 + * GNU General Public License for more details.
  105.16 + *
  105.17 + * You should have received a copy of the GNU General Public License
  105.18 + * along with this program. Look for COPYING file in the top folder.
  105.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
  105.20 + */
  105.21 +package org.apidesign.bck2brwsr.emul.reflect;
  105.22 +
  105.23 +import java.lang.reflect.Constructor;
  105.24 +import java.lang.reflect.Type;
  105.25 +import java.lang.reflect.TypeVariable;
  105.26 +
  105.27 +/**
  105.28 + *
  105.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
  105.30 + */
  105.31 +public abstract class TypeProvider {
  105.32 +    private TypeProvider() {
  105.33 +    }
  105.34 +    
  105.35 +    public static TypeProvider getDefault() {
  105.36 +        return null;
  105.37 +    }
  105.38 +    
  105.39 +    public abstract <T> TypeVariable<Constructor<T>>[] getTypeParameters(Constructor<T> c);
  105.40 +    public abstract <T> Type[] getGenericParameterTypes(Constructor<T> c);
  105.41 +    public abstract <T> Type[] getGenericExceptionTypes(Constructor<T> c);
  105.42 +    
  105.43 +}
   106.1 --- a/javaquery/api/pom.xml	Tue Feb 05 16:40:01 2013 +0100
   106.2 +++ b/javaquery/api/pom.xml	Tue Feb 05 17:04:22 2013 +0100
   106.3 @@ -43,6 +43,7 @@
   106.4      <dependency>
   106.5        <groupId>org.netbeans.api</groupId>
   106.6        <artifactId>org-openide-util-lookup</artifactId>
   106.7 +      <scope>provided</scope>
   106.8      </dependency>
   106.9      <dependency>
  106.10        <groupId>org.apidesign.bck2brwsr</groupId>
   107.1 --- a/javaquery/demo-calculator/nbactions.xml	Tue Feb 05 16:40:01 2013 +0100
   107.2 +++ b/javaquery/demo-calculator/nbactions.xml	Tue Feb 05 17:04:22 2013 +0100
   107.3 @@ -23,7 +23,7 @@
   107.4              <actionName>run</actionName>
   107.5              <goals>
   107.6                  <goal>process-classes</goal>
   107.7 -                <goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec</goal>
   107.8 +                <goal>org.apidesign.bck2brwsr:mojo:0.3-SNAPSHOT:brwsr</goal>
   107.9              </goals>
  107.10          </action>
  107.11      </actions>
   108.1 --- a/javaquery/demo-calculator/pom.xml	Tue Feb 05 16:40:01 2013 +0100
   108.2 +++ b/javaquery/demo-calculator/pom.xml	Tue Feb 05 17:04:22 2013 +0100
   108.3 @@ -16,34 +16,21 @@
   108.4    </properties>
   108.5    <build>
   108.6        <plugins>
   108.7 -          <plugin>
   108.8 -              <groupId>org.apidesign.bck2brwsr</groupId>
   108.9 -              <artifactId>mojo</artifactId>
  108.10 -              <version>0.3-SNAPSHOT</version>
  108.11 -              <executions>
  108.12 -                  <execution>
  108.13 -                      <goals>
  108.14 -                          <goal>j2js</goal>
  108.15 -                      </goals>
  108.16 -                  </execution>
  108.17 -              </executions>
  108.18 -          </plugin>
  108.19              <plugin>
  108.20 -                <groupId>org.codehaus.mojo</groupId>
  108.21 -                <artifactId>exec-maven-plugin</artifactId>
  108.22 -                <version>1.2.1</version>
  108.23 +                <groupId>org.apidesign.bck2brwsr</groupId>
  108.24 +                <artifactId>mojo</artifactId>
  108.25 +                <version>0.3-SNAPSHOT</version>
  108.26                  <executions>
  108.27                      <execution>
  108.28                          <goals>
  108.29 -                            <goal>exec</goal>
  108.30 +                            <goal>j2js</goal>
  108.31 +                            <goal>brwsr</goal>
  108.32                          </goals>
  108.33                      </execution>
  108.34                  </executions>
  108.35                  <configuration>
  108.36 -                    <executable>xdg-open</executable>
  108.37 -                    <arguments>
  108.38 -                        <argument>${project.build.directory}/classes/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml</argument>
  108.39 -                    </arguments>
  108.40 +                    <directory>${project.build.directory}/${project.build.finalName}-bck2brwsr/public_html/</directory>
  108.41 +                    <startpage>index.xhtml</startpage>
  108.42                  </configuration>
  108.43              </plugin>
  108.44           <plugin>
  108.45 @@ -55,6 +42,24 @@
  108.46                 <target>1.7</target>
  108.47              </configuration>
  108.48           </plugin>
  108.49 +         <plugin>
  108.50 +            <artifactId>maven-assembly-plugin</artifactId>
  108.51 +                <version>2.4</version>
  108.52 +                <executions>
  108.53 +                    <execution>
  108.54 +                        <id>distro-assembly</id>
  108.55 +                        <phase>package</phase>
  108.56 +                        <goals>
  108.57 +                            <goal>single</goal>
  108.58 +                        </goals>
  108.59 +                        <configuration>
  108.60 +                            <descriptors>
  108.61 +                                <descriptor>src/main/assembly/bck2brwsr.xml</descriptor>
  108.62 +                            </descriptors>
  108.63 +                        </configuration>
  108.64 +                    </execution>
  108.65 +                </executions>                
  108.66 +            </plugin>      
  108.67        </plugins>
  108.68    </build>
  108.69  
   109.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   109.2 +++ b/javaquery/demo-calculator/src/main/assembly/bck2brwsr.xml	Tue Feb 05 17:04:22 2013 +0100
   109.3 @@ -0,0 +1,54 @@
   109.4 +<?xml version="1.0"?>
   109.5 +<!--
   109.6 +
   109.7 +    Back 2 Browser Bytecode Translator
   109.8 +    Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   109.9 +
  109.10 +    This program is free software: you can redistribute it and/or modify
  109.11 +    it under the terms of the GNU General Public License as published by
  109.12 +    the Free Software Foundation, version 2 of the License.
  109.13 +
  109.14 +    This program is distributed in the hope that it will be useful,
  109.15 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
  109.16 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  109.17 +    GNU General Public License for more details.
  109.18 +
  109.19 +    You should have received a copy of the GNU General Public License
  109.20 +    along with this program. Look for COPYING file in the top folder.
  109.21 +    If not, see http://opensource.org/licenses/GPL-2.0.
  109.22 +
  109.23 +-->
  109.24 +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  109.25 +  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
  109.26 +  
  109.27 +  <id>bck2brwsr</id>
  109.28 +  <formats>
  109.29 +      <format>zip</format>
  109.30 +      <format>dir</format>
  109.31 +  </formats>
  109.32 +  <baseDirectory>public_html</baseDirectory>
  109.33 +  <dependencySets>
  109.34 +    <dependencySet>
  109.35 +        <useProjectArtifact>false</useProjectArtifact>
  109.36 +        <scope>runtime</scope>
  109.37 +        <outputDirectory>lib</outputDirectory>
  109.38 +    </dependencySet>
  109.39 +  </dependencySets> 
  109.40 +  <files>
  109.41 +    <file>
  109.42 +      <source>${project.build.directory}/${project.build.finalName}.jar</source>
  109.43 +      <outputDirectory>/</outputDirectory>
  109.44 +    </file>
  109.45 +    <file>
  109.46 +      <source>${project.build.directory}/classes/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml</source>
  109.47 +      <outputDirectory>/</outputDirectory>
  109.48 +      <destName>index.xhtml</destName>
  109.49 +    </file>
  109.50 +    <file>
  109.51 +      <source>${project.build.directory}/classes/org/apidesign/bck2brwsr/demo/calc/staticcompilation/bootjava.js</source>
  109.52 +      <outputDirectory>/</outputDirectory>
  109.53 +      <destName>bck2brwsr.js</destName>
  109.54 +    </file>
  109.55 +  </files>
  109.56 +
  109.57 +</assembly>
  109.58 \ No newline at end of file
   110.1 --- a/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml	Tue Feb 05 16:40:01 2013 +0100
   110.2 +++ b/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml	Tue Feb 05 17:04:22 2013 +0100
   110.3 @@ -77,78 +77,6 @@
   110.4              </tbody>
   110.5          </table>
   110.6          <div data-bind="text: displayPreview"></div>
   110.7 -        <script src="bootjava.js"/>
   110.8 -        
   110.9 -        <hr/>
  110.10 -    <pre>
  110.11 -    <span class="keyword-directive">package</span> org.apidesign.bck2brwsr.mavenhtml;
  110.12 -
  110.13 -    <span class="keyword-directive">import</span> org.apidesign.bck2brwsr.htmlpage.api.OnClick;
  110.14 -    <span class="keyword-directive">import</span> org.apidesign.bck2brwsr.htmlpage.api.Page;
  110.15 -
  110.16 -    <span class="comment">/**</span> <span class="comment">HTML5</span><span class="comment"> &amp; </span><span class="comment">Java</span> <span class="comment">demo</span> <span class="comment">showing</span> <span class="comment">the</span> <span class="comment">power</span> <span class="comment">of</span> <a href="http://wiki.apidesign.org/wiki/AnnotationProcessor">annotation processors</a>
  110.17 -    <span class="comment"> * </span><span class="comment">as</span> <span class="comment">well</span> <span class="comment">as</span> <span class="comment">other</span> <span class="comment">goodies</span><span class="comment">, including type-safe association between</span>
  110.18 -    <span class="comment"> * </span><span class="comment">an XHTML page and Java.</span>
  110.19 -    <span class="comment"> * </span>
  110.20 -    <span class="comment"> * </span><span class="ST1">@author</span> <span class="comment">Jaroslav</span> <span class="comment">Tulach</span> <span class="ST0">&lt;jaroslav.tulach@apidesign.org&gt;</span>
  110.21 -     <span class="comment">*/</span>
  110.22 -    @Page(xhtml=<span class="string">&quot;</span><span class="string">Calculator.xhtml</span><span class="string">&quot;</span>)
  110.23 -    <span class="keyword-directive">public</span> <span class="keyword-directive">class</span> App {
  110.24 -        <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> <span class="keyword-directive">double</span> memory;
  110.25 -        <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> String operation;
  110.26 -
  110.27 -        @OnClick(id=<span class="string">&quot;</span><span class="string">clear</span><span class="string">&quot;</span>)
  110.28 -        <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> clear() {
  110.29 -            memory = <span class="number">0</span>;
  110.30 -            operation = <span class="keyword-directive">null</span>;
  110.31 -            Calculator.DISPLAY.setValue(<span class="string">&quot;</span><span class="string">0</span><span class="string">&quot;</span>);
  110.32 -        }
  110.33 -
  110.34 -        @OnClick(id= { <span class="string">&quot;</span><span class="string">plus</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">minus</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">mul</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">div</span><span class="string">&quot;</span> })
  110.35 -        <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> applyOp(String op) {
  110.36 -            memory = getValue();
  110.37 -            operation = op;
  110.38 -            Calculator.DISPLAY.setValue(<span class="string">&quot;</span><span class="string">0</span><span class="string">&quot;</span>);
  110.39 -        }
  110.40 -
  110.41 -        @OnClick(id=<span class="string">&quot;</span><span class="string">result</span><span class="string">&quot;</span>)
  110.42 -        <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> computeTheValue() {
  110.43 -            <span class="keyword-directive">switch</span> (operation) {
  110.44 -                <span class="keyword-directive">case</span> <span class="string">&quot;</span><span class="string">plus</span><span class="string">&quot;</span>: setValue(memory + getValue()); <span class="keyword-directive">break</span>;
  110.45 -                <span class="keyword-directive">case</span> <span class="string">&quot;</span><span class="string">minus</span><span class="string">&quot;</span>: setValue(memory - getValue()); <span class="keyword-directive">break</span>;
  110.46 -                <span class="keyword-directive">case</span> <span class="string">&quot;</span><span class="string">mul</span><span class="string">&quot;</span>: setValue(memory * getValue()); <span class="keyword-directive">break</span>;
  110.47 -                <span class="keyword-directive">case</span> <span class="string">&quot;</span><span class="string">div</span><span class="string">&quot;</span>: setValue(memory / getValue()); <span class="keyword-directive">break</span>;
  110.48 -                <span class="keyword-directive">default</span>: <span class="keyword-directive">throw</span> <span class="keyword-directive">new</span> IllegalStateException(operation);
  110.49 -            }
  110.50 -        }
  110.51 -
  110.52 -        @OnClick(id={<span class="string">&quot;</span><span class="string">n0</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n1</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n2</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n3</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n4</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n5</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n6</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n7</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n8</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n9</span><span class="string">&quot;</span>}) 
  110.53 -        <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> addDigit(String digit) {
  110.54 -            digit = digit.substring(<span class="number">1</span>);
  110.55 -            String v = Calculator.DISPLAY.getValue();
  110.56 -            <span class="keyword-directive">if</span> (getValue() == <span class="number">0.0</span>) {
  110.57 -                Calculator.DISPLAY.setValue(digit);
  110.58 -            } <span class="keyword-directive">else</span> {
  110.59 -                Calculator.DISPLAY.setValue(v + digit);
  110.60 -            }
  110.61 -        }
  110.62 -
  110.63 -        <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> setValue(<span class="keyword-directive">double</span> v) {
  110.64 -            StringBuilder sb = <span class="keyword-directive">new</span> StringBuilder();
  110.65 -            sb.append(v);
  110.66 -            Calculator.DISPLAY.setValue(sb.toString());
  110.67 -        }
  110.68 -
  110.69 -        <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> <span class="keyword-directive">double</span> getValue() {
  110.70 -            <span class="keyword-directive">try</span> {
  110.71 -                <span class="keyword-directive">return</span> Double.parseDouble(Calculator.DISPLAY.getValue());
  110.72 -            } <span class="keyword-directive">catch</span> (NumberFormatException ex) {
  110.73 -                Calculator.DISPLAY.setValue(<span class="string">&quot;</span><span class="string">err</span><span class="string">&quot;</span>);
  110.74 -                <span class="keyword-directive">return</span> <span class="number">0.0</span>;
  110.75 -            }
  110.76 -        }
  110.77 -    }
  110.78 -
  110.79 -    </pre>
  110.80 +        <script src="bck2brwsr.js"/>
  110.81      </body>
  110.82  </html>
   111.1 --- a/launcher/pom.xml	Tue Feb 05 16:40:01 2013 +0100
   111.2 +++ b/launcher/pom.xml	Tue Feb 05 17:04:22 2013 +0100
   111.3 @@ -23,6 +23,14 @@
   111.4                      <target>1.7</target>
   111.5                  </configuration>
   111.6              </plugin>
   111.7 +            <plugin>
   111.8 +                <groupId>org.apache.maven.plugins</groupId>
   111.9 +                <artifactId>maven-javadoc-plugin</artifactId>
  111.10 +                <version>2.8.1</version>
  111.11 +                <configuration>
  111.12 +                    <excludePackageNames>org.apidesign.bck2brwsr.launcher.impl</excludePackageNames>
  111.13 +                </configuration>
  111.14 +            </plugin>
  111.15          </plugins>
  111.16      </build>
  111.17      <properties>
   112.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java	Tue Feb 05 16:40:01 2013 +0100
   112.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java	Tue Feb 05 17:04:22 2013 +0100
   112.3 @@ -55,24 +55,23 @@
   112.4   */
   112.5  final class Bck2BrwsrLauncher extends Launcher implements Closeable {
   112.6      private static final Logger LOG = Logger.getLogger(Bck2BrwsrLauncher.class.getName());
   112.7 -    private static final MethodInvocation END = new MethodInvocation(null, null, null);
   112.8 -    private Set<ClassLoader> loaders = new LinkedHashSet<>();
   112.9 -    private BlockingQueue<MethodInvocation> methods = new LinkedBlockingQueue<>();
  112.10 +    private static final InvocationContext END = new InvocationContext(null, null, null);
  112.11 +    private final Set<ClassLoader> loaders = new LinkedHashSet<>();
  112.12 +    private final BlockingQueue<InvocationContext> methods = new LinkedBlockingQueue<>();
  112.13      private long timeOut;
  112.14      private final Res resources = new Res();
  112.15      private final String cmd;
  112.16      private Object[] brwsr;
  112.17      private HttpServer server;
  112.18      private CountDownLatch wait;
  112.19 -
  112.20 +    
  112.21      public Bck2BrwsrLauncher(String cmd) {
  112.22          this.cmd = cmd;
  112.23      }
  112.24      
  112.25      @Override
  112.26 -     MethodInvocation addMethod(Class<?> clazz, String method, String html) throws IOException {
  112.27 -        loaders.add(clazz.getClassLoader());
  112.28 -        MethodInvocation c = new MethodInvocation(clazz.getName(), method, html);
  112.29 +    InvocationContext runMethod(InvocationContext c) throws IOException {
  112.30 +        loaders.add(c.clazz.getClassLoader());
  112.31          methods.add(c);
  112.32          try {
  112.33              c.await(timeOut);
  112.34 @@ -94,7 +93,7 @@
  112.35          if (!startpage.startsWith("/")) {
  112.36              startpage = "/" + startpage;
  112.37          }
  112.38 -        HttpServer s = initServer();
  112.39 +        HttpServer s = initServer(".", true);
  112.40          s.getServerConfiguration().addHttpHandler(new Page(resources, null), "/");
  112.41          try {
  112.42              launchServerAndBrwsr(s, startpage);
  112.43 @@ -103,6 +102,18 @@
  112.44          }
  112.45      }
  112.46  
  112.47 +    void showDirectory(File dir, String startpage) throws IOException {
  112.48 +        if (!startpage.startsWith("/")) {
  112.49 +            startpage = "/" + startpage;
  112.50 +        }
  112.51 +        HttpServer s = initServer(dir.getPath(), false);
  112.52 +        try {
  112.53 +            launchServerAndBrwsr(s, startpage);
  112.54 +        } catch (URISyntaxException | InterruptedException ex) {
  112.55 +            throw new IOException(ex);
  112.56 +        }
  112.57 +    }
  112.58 +
  112.59      @Override
  112.60      public void initialize() throws IOException {
  112.61          try {
  112.62 @@ -122,25 +133,54 @@
  112.63          }
  112.64      }
  112.65      
  112.66 -    private HttpServer initServer() throws IOException {
  112.67 -        HttpServer s = HttpServer.createSimpleServer(".", new PortRange(8080, 65535));
  112.68 +    private HttpServer initServer(String path, boolean addClasses) throws IOException {
  112.69 +        HttpServer s = HttpServer.createSimpleServer(path, new PortRange(8080, 65535));
  112.70  
  112.71          final ServerConfiguration conf = s.getServerConfiguration();
  112.72 -        conf.addHttpHandler(new VM(resources), "/vm.js");
  112.73 -        conf.addHttpHandler(new Classes(resources), "/classes/");
  112.74 +        if (addClasses) {
  112.75 +            conf.addHttpHandler(new VM(resources), "/vm.js");
  112.76 +            conf.addHttpHandler(new Classes(resources), "/classes/");
  112.77 +        }
  112.78          return s;
  112.79      }
  112.80      
  112.81      private void executeInBrowser() throws InterruptedException, URISyntaxException, IOException {
  112.82          wait = new CountDownLatch(1);
  112.83 -        server = initServer();
  112.84 -        ServerConfiguration conf = server.getServerConfiguration();
  112.85 +        server = initServer(".", true);
  112.86 +        final ServerConfiguration conf = server.getServerConfiguration();
  112.87 +        
  112.88 +        class DynamicResourceHandler extends HttpHandler {
  112.89 +            private final InvocationContext ic;
  112.90 +            public DynamicResourceHandler(InvocationContext ic) {
  112.91 +                if (ic == null || ic.httpPath == null) {
  112.92 +                    throw new NullPointerException();
  112.93 +                }
  112.94 +                this.ic = ic;
  112.95 +                conf.addHttpHandler(this, ic.httpPath);
  112.96 +            }
  112.97 +
  112.98 +            public void close() {
  112.99 +                conf.removeHttpHandler(this);
 112.100 +            }
 112.101 +            
 112.102 +            @Override
 112.103 +            public void service(Request request, Response response) throws Exception {
 112.104 +                if (ic.httpPath.equals(request.getRequestURI())) {
 112.105 +                    LOG.log(Level.INFO, "Serving HttpResource for {0}", request.getRequestURI());
 112.106 +                    response.setContentType(ic.httpType);
 112.107 +                    copyStream(ic.httpContent, response.getOutputStream(), null);
 112.108 +                }
 112.109 +            }
 112.110 +        }
 112.111 +        
 112.112          conf.addHttpHandler(new Page(resources, 
 112.113              "org/apidesign/bck2brwsr/launcher/harness.xhtml"
 112.114          ), "/execute");
 112.115 +        
 112.116          conf.addHttpHandler(new HttpHandler() {
 112.117              int cnt;
 112.118 -            List<MethodInvocation> cases = new ArrayList<>();
 112.119 +            List<InvocationContext> cases = new ArrayList<>();
 112.120 +            DynamicResourceHandler prev;
 112.121              @Override
 112.122              public void service(Request request, Response response) throws Exception {
 112.123                  String id = request.getParameter("request");
 112.124 @@ -152,7 +192,12 @@
 112.125                      cases.get(Integer.parseInt(id)).result(value, null);
 112.126                  }
 112.127                  
 112.128 -                MethodInvocation mi = methods.take();
 112.129 +                if (prev != null) {
 112.130 +                    prev.close();
 112.131 +                    prev = null;
 112.132 +                }
 112.133 +                
 112.134 +                InvocationContext mi = methods.take();
 112.135                  if (mi == END) {
 112.136                      response.getWriter().write("");
 112.137                      wait.countDown();
 112.138 @@ -161,8 +206,12 @@
 112.139                      return;
 112.140                  }
 112.141                  
 112.142 +                if (mi.httpPath != null) {
 112.143 +                    prev = new DynamicResourceHandler(mi);
 112.144 +                }
 112.145 +                
 112.146                  cases.add(mi);
 112.147 -                final String cn = mi.className;
 112.148 +                final String cn = mi.clazz.getName();
 112.149                  final String mn = mi.methodName;
 112.150                  LOG.log(Level.INFO, "Request for {0} case. Sending {1}.{2}", new Object[]{cnt, cn, mn});
 112.151                  response.getWriter().write("{"
   113.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Console.java	Tue Feb 05 16:40:01 2013 +0100
   113.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   113.3 @@ -1,253 +0,0 @@
   113.4 -/**
   113.5 - * Back 2 Browser Bytecode Translator
   113.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   113.7 - *
   113.8 - * This program is free software: you can redistribute it and/or modify
   113.9 - * it under the terms of the GNU General Public License as published by
  113.10 - * the Free Software Foundation, version 2 of the License.
  113.11 - *
  113.12 - * This program is distributed in the hope that it will be useful,
  113.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  113.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  113.15 - * GNU General Public License for more details.
  113.16 - *
  113.17 - * You should have received a copy of the GNU General Public License
  113.18 - * along with this program. Look for COPYING file in the top folder.
  113.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
  113.20 - */
  113.21 -package org.apidesign.bck2brwsr.launcher;
  113.22 -
  113.23 -import java.io.IOException;
  113.24 -import java.io.InputStream;
  113.25 -import java.lang.reflect.InvocationTargetException;
  113.26 -import java.lang.reflect.Method;
  113.27 -import java.lang.reflect.Modifier;
  113.28 -import java.net.URL;
  113.29 -import java.util.Enumeration;
  113.30 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
  113.31 -
  113.32 -/**
  113.33 - *
  113.34 - * @author Jaroslav Tulach <jtulach@netbeans.org>
  113.35 - */
  113.36 -public class Console {
  113.37 -    static {
  113.38 -        turnAssetionStatusOn();
  113.39 -    }
  113.40 -    
  113.41 -    @JavaScriptBody(args = {"id", "attr"}, body = 
  113.42 -        "return window.document.getElementById(id)[attr].toString();")
  113.43 -    private static native Object getAttr(String id, String attr);
  113.44 -
  113.45 -    @JavaScriptBody(args = {"id", "attr", "value"}, body = 
  113.46 -        "window.document.getElementById(id)[attr] = value;")
  113.47 -    private static native void setAttr(String id, String attr, Object value);
  113.48 -    
  113.49 -    @JavaScriptBody(args = {}, body = "return; window.close();")
  113.50 -    private static native void closeWindow();
  113.51 -
  113.52 -    private static void log(String newText) {
  113.53 -        String id = "bck2brwsr.result";
  113.54 -        String attr = "value";
  113.55 -        setAttr(id, attr, getAttr(id, attr) + "\n" + newText);
  113.56 -        setAttr(id, "scrollTop", getAttr(id, "scrollHeight"));
  113.57 -    }
  113.58 -    
  113.59 -    public static void execute() throws Exception {
  113.60 -        String clazz = (String) getAttr("clazz", "value");
  113.61 -        String method = (String) getAttr("method", "value");
  113.62 -        Object res = invokeMethod(clazz, method);
  113.63 -        setAttr("bck2brwsr.result", "value", res);
  113.64 -    }
  113.65 -
  113.66 -    @JavaScriptBody(args = { "url", "callback", "arr" }, body = ""
  113.67 -        + "var request = new XMLHttpRequest();\n"
  113.68 -        + "request.open('GET', url, true);\n"
  113.69 -        + "request.onreadystatechange = function() {\n"
  113.70 -        + "  if (this.readyState!==4) return;\n"
  113.71 -        + "  arr[0] = this.responseText;\n"
  113.72 -        + "  callback.run__V();\n"
  113.73 -        + "};"
  113.74 -        + "request.send();"
  113.75 -    )
  113.76 -    private static native void loadText(String url, Runnable callback, String[] arr) throws IOException;
  113.77 -    
  113.78 -    public static void harness(String url) throws IOException {
  113.79 -        log("Connecting to " + url);
  113.80 -        Request r = new Request(url);
  113.81 -    }
  113.82 -    
  113.83 -    private static class Request implements Runnable {
  113.84 -        private final String[] arr = { null };
  113.85 -        private final String url;
  113.86 -
  113.87 -        private Request(String url) throws IOException {
  113.88 -            this.url = url;
  113.89 -            loadText(url, this, arr);
  113.90 -        }
  113.91 -        
  113.92 -        @Override
  113.93 -        public void run() {
  113.94 -            try {
  113.95 -                String data = arr[0];
  113.96 -                log("\nGot \"" + data + "\"");
  113.97 -                
  113.98 -                if (data == null) {
  113.99 -                    log("Some error exiting");
 113.100 -                    closeWindow();
 113.101 -                    return;
 113.102 -                }
 113.103 -                
 113.104 -                if (data.isEmpty()) {
 113.105 -                    log("No data, exiting");
 113.106 -                    closeWindow();
 113.107 -                    return;
 113.108 -                }
 113.109 -                
 113.110 -                Case c = Case.parseData(data);
 113.111 -                if (c.getHtmlFragment() != null) {
 113.112 -                    setAttr("bck2brwsr.fragment", "innerHTML", c.getHtmlFragment());
 113.113 -                }
 113.114 -                log("Invoking " + c.getClassName() + '.' + c.getMethodName() + " as request: " + c.getRequestId());
 113.115 -
 113.116 -                Object result = invokeMethod(c.getClassName(), c.getMethodName());
 113.117 -                
 113.118 -                setAttr("bck2brwsr.fragment", "innerHTML", "");
 113.119 -                log("Result: " + result);
 113.120 -                
 113.121 -                result = encodeURL("" + result);
 113.122 -                
 113.123 -                log("Sending back: " + url + "?request=" + c.getRequestId() + "&result=" + result);
 113.124 -                String u = url + "?request=" + c.getRequestId() + "&result=" + result;
 113.125 -                
 113.126 -                loadText(u, this, arr);
 113.127 -                
 113.128 -            } catch (Exception ex) {
 113.129 -                log(ex.getMessage());
 113.130 -            }
 113.131 -        }
 113.132 -    }
 113.133 -    
 113.134 -    private static String encodeURL(String r) {
 113.135 -        StringBuilder sb = new StringBuilder();
 113.136 -        for (int i = 0; i < r.length(); i++) {
 113.137 -            int ch = r.charAt(i);
 113.138 -            if (ch < 32 || ch == '%' || ch == '+') {
 113.139 -                sb.append("%").append(("0" + Integer.toHexString(ch)).substring(0, 2));
 113.140 -            } else {
 113.141 -                if (ch == 32) {
 113.142 -                    sb.append("+");
 113.143 -                } else {
 113.144 -                    sb.append((char)ch);
 113.145 -                }
 113.146 -            }
 113.147 -        }
 113.148 -        return sb.toString();
 113.149 -    }
 113.150 -    
 113.151 -    static String invoke(String clazz, String method) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException {
 113.152 -        final Object r = invokeMethod(clazz, method);
 113.153 -        return r == null ? "null" : r.toString().toString();
 113.154 -    }
 113.155 -
 113.156 -    /** Helper method that inspects the classpath and loads given resource
 113.157 -     * (usually a class file). Used while running tests in Rhino.
 113.158 -     * 
 113.159 -     * @param name resource name to find
 113.160 -     * @return the array of bytes in the given resource
 113.161 -     * @throws IOException I/O in case something goes wrong
 113.162 -     */
 113.163 -    public static byte[] read(String name) throws IOException {
 113.164 -        URL u = null;
 113.165 -        Enumeration<URL> en = Console.class.getClassLoader().getResources(name);
 113.166 -        while (en.hasMoreElements()) {
 113.167 -            u = en.nextElement();
 113.168 -        }
 113.169 -        if (u == null) {
 113.170 -            throw new IOException("Can't find " + name);
 113.171 -        }
 113.172 -        try (InputStream is = u.openStream()) {
 113.173 -            byte[] arr;
 113.174 -            arr = new byte[is.available()];
 113.175 -            int offset = 0;
 113.176 -            while (offset < arr.length) {
 113.177 -                int len = is.read(arr, offset, arr.length - offset);
 113.178 -                if (len == -1) {
 113.179 -                    throw new IOException("Can't read " + name);
 113.180 -                }
 113.181 -                offset += len;
 113.182 -            }
 113.183 -            return arr;
 113.184 -        }
 113.185 -    }
 113.186 -   
 113.187 -    private static Object invokeMethod(String clazz, String method) 
 113.188 -    throws ClassNotFoundException, InvocationTargetException, 
 113.189 -    SecurityException, IllegalAccessException, IllegalArgumentException,
 113.190 -    InstantiationException {
 113.191 -        Method found = null;
 113.192 -        Class<?> c = Class.forName(clazz);
 113.193 -        for (Method m : c.getMethods()) {
 113.194 -            if (m.getName().equals(method)) {
 113.195 -                found = m;
 113.196 -            }
 113.197 -        }
 113.198 -        Object res;
 113.199 -        if (found != null) {
 113.200 -            try {
 113.201 -                if ((found.getModifiers() & Modifier.STATIC) != 0) {
 113.202 -                    res = found.invoke(null);
 113.203 -                } else {
 113.204 -                    res = found.invoke(c.newInstance());
 113.205 -                }
 113.206 -            } catch (Throwable ex) {
 113.207 -                res = ex.getClass().getName() + ":" + ex.getMessage();
 113.208 -            }
 113.209 -        } else {
 113.210 -            res = "Can't find method " + method + " in " + clazz;
 113.211 -        }
 113.212 -        return res;
 113.213 -    }
 113.214 -
 113.215 -    @JavaScriptBody(args = {}, body = "vm.desiredAssertionStatus = true;")
 113.216 -    private static void turnAssetionStatusOn() {
 113.217 -    }
 113.218 -    
 113.219 -    private static final class Case {
 113.220 -        private final Object data;
 113.221 -
 113.222 -        private Case(Object data) {
 113.223 -            this.data = data;
 113.224 -        }
 113.225 -        
 113.226 -        public static Case parseData(String s) {
 113.227 -            return new Case(toJSON(s));
 113.228 -        }
 113.229 -        
 113.230 -        public String getMethodName() {
 113.231 -            return value("methodName", data);
 113.232 -        }
 113.233 -
 113.234 -        public String getClassName() {
 113.235 -            return value("className", data);
 113.236 -        }
 113.237 -        
 113.238 -        public String getRequestId() {
 113.239 -            return value("request", data);
 113.240 -        }
 113.241 -
 113.242 -        public String getHtmlFragment() {
 113.243 -            return value("html", data);
 113.244 -        }
 113.245 -        
 113.246 -        @JavaScriptBody(args = "s", body = "return eval('(' + s + ')');")
 113.247 -        private static native Object toJSON(String s);
 113.248 -        
 113.249 -        @JavaScriptBody(args = {"p", "d"}, body = 
 113.250 -              "var v = d[p];\n"
 113.251 -            + "if (typeof v === 'undefined') return null;\n"
 113.252 -            + "return v.toString();"
 113.253 -        )
 113.254 -        private static native String value(String p, Object d);
 113.255 -    }
 113.256 -}
   114.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   114.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/InvocationContext.java	Tue Feb 05 17:04:22 2013 +0100
   114.3 @@ -0,0 +1,101 @@
   114.4 +/**
   114.5 + * Back 2 Browser Bytecode Translator
   114.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   114.7 + *
   114.8 + * This program is free software: you can redistribute it and/or modify
   114.9 + * it under the terms of the GNU General Public License as published by
  114.10 + * the Free Software Foundation, version 2 of the License.
  114.11 + *
  114.12 + * This program is distributed in the hope that it will be useful,
  114.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  114.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  114.15 + * GNU General Public License for more details.
  114.16 + *
  114.17 + * You should have received a copy of the GNU General Public License
  114.18 + * along with this program. Look for COPYING file in the top folder.
  114.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
  114.20 + */
  114.21 +package org.apidesign.bck2brwsr.launcher;
  114.22 +
  114.23 +import java.io.IOException;
  114.24 +import java.io.InputStream;
  114.25 +import java.util.concurrent.CountDownLatch;
  114.26 +import java.util.concurrent.TimeUnit;
  114.27 +
  114.28 +/** Represents individual method invocation, its context and its result.
  114.29 + *
  114.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
  114.31 + */
  114.32 +public final class InvocationContext {
  114.33 +    final CountDownLatch wait = new CountDownLatch(1);
  114.34 +    final Class<?> clazz;
  114.35 +    final String methodName;
  114.36 +    private final Launcher launcher;
  114.37 +    private String result;
  114.38 +    private Throwable exception;
  114.39 +    String html;
  114.40 +    InputStream httpContent;
  114.41 +    String httpType;
  114.42 +    String httpPath;
  114.43 +
  114.44 +    InvocationContext(Launcher launcher, Class<?> clazz, String methodName) {
  114.45 +        this.launcher = launcher;
  114.46 +        this.clazz = clazz;
  114.47 +        this.methodName = methodName;
  114.48 +    }
  114.49 +    
  114.50 +    /** An HTML fragment to be available for the execution. Useful primarily when
  114.51 +     * executing in a browser via {@link Launcher#createBrowser(java.lang.String)}.
  114.52 +     * @param html the html fragment
  114.53 +     */
  114.54 +    public void setHtmlFragment(String html) {
  114.55 +        this.html = html;
  114.56 +    }
  114.57 +    
  114.58 +    /** HTTP resource to be available during execution. An invocation may
  114.59 +     * perform an HTTP query and obtain a resource relative to the page.
  114.60 +     */
  114.61 +    public void setHttpResource(String relativePath, String mimeType, InputStream content) {
  114.62 +        if (relativePath == null || mimeType == null || content == null) {
  114.63 +            throw new NullPointerException();
  114.64 +        }
  114.65 +        this.httpPath = relativePath;
  114.66 +        this.httpType = mimeType;
  114.67 +        this.httpContent = content;
  114.68 +    }
  114.69 +    
  114.70 +    /** Invokes the associated method. 
  114.71 +     * @return the textual result of the invocation
  114.72 +     */
  114.73 +    public String invoke() throws IOException {
  114.74 +        launcher.runMethod(this);
  114.75 +        return toString();
  114.76 +    }
  114.77 +    
  114.78 +    /** Obtains textual result of the invocation.
  114.79 +     * @return text representing the exception or result value
  114.80 +     */
  114.81 +    @Override
  114.82 +    public String toString() {
  114.83 +        if (exception != null) {
  114.84 +            return exception.toString();
  114.85 +        }
  114.86 +        return result;
  114.87 +    }
  114.88 +    
  114.89 +    /**
  114.90 +     * @param timeOut
  114.91 +     * @throws InterruptedException 
  114.92 +     */
  114.93 +    void await(long timeOut) throws InterruptedException {
  114.94 +        wait.await(timeOut, TimeUnit.MILLISECONDS);
  114.95 +    }
  114.96 +    
  114.97 +    void result(String r, Throwable e) {
  114.98 +        this.result = r;
  114.99 +        this.exception = e;
 114.100 +        wait.countDown();
 114.101 +    }
 114.102 +
 114.103 +    
 114.104 +}
   115.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/JSLauncher.java	Tue Feb 05 16:40:01 2013 +0100
   115.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/JSLauncher.java	Tue Feb 05 17:04:22 2013 +0100
   115.3 @@ -17,12 +17,14 @@
   115.4   */
   115.5  package org.apidesign.bck2brwsr.launcher;
   115.6  
   115.7 +import org.apidesign.bck2brwsr.launcher.impl.Console;
   115.8  import java.io.IOException;
   115.9  import java.io.InputStream;
  115.10  import java.net.URL;
  115.11  import java.util.Enumeration;
  115.12  import java.util.LinkedHashSet;
  115.13  import java.util.Set;
  115.14 +import java.util.logging.Level;
  115.15  import java.util.logging.Logger;
  115.16  import javax.script.Invocable;
  115.17  import javax.script.ScriptEngine;
  115.18 @@ -42,14 +44,18 @@
  115.19      private Object console;
  115.20      
  115.21      
  115.22 -    @Override MethodInvocation addMethod(Class<?> clazz, String method, String html) {
  115.23 -        loaders.add(clazz.getClassLoader());
  115.24 -        MethodInvocation mi = new MethodInvocation(clazz.getName(), method, html);
  115.25 +    @Override InvocationContext runMethod(InvocationContext mi) {
  115.26 +        loaders.add(mi.clazz.getClassLoader());
  115.27          try {
  115.28 -            mi.result(code.invokeMethod(
  115.29 +            long time = System.currentTimeMillis();
  115.30 +            LOG.log(Level.FINE, "Invoking {0}.{1}", new Object[]{mi.clazz.getName(), mi.methodName});
  115.31 +            String res = code.invokeMethod(
  115.32                  console,
  115.33                  "invoke__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2",
  115.34 -                mi.className, mi.methodName).toString(), null);
  115.35 +                mi.clazz.getName(), mi.methodName).toString();
  115.36 +            time = System.currentTimeMillis() - time;
  115.37 +            LOG.log(Level.FINE, "Resut of {0}.{1} = {2} in {3} ms", new Object[]{mi.clazz.getName(), mi.methodName, res, time});
  115.38 +            mi.result(res, null);
  115.39          } catch (ScriptException | NoSuchMethodException ex) {
  115.40              mi.result(null, ex);
  115.41          }
  115.42 @@ -83,7 +89,7 @@
  115.43          ScriptEngine mach = sem.getEngineByExtension("js");
  115.44  
  115.45          sb.append(
  115.46 -              "\nvar vm = new bck2brwsr(org.apidesign.bck2brwsr.launcher.Console.read);"
  115.47 +              "\nvar vm = new bck2brwsr(org.apidesign.bck2brwsr.launcher.impl.Console.read);"
  115.48              + "\nfunction initVM() { return vm; };"
  115.49              + "\n");
  115.50  
   116.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java	Tue Feb 05 16:40:01 2013 +0100
   116.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java	Tue Feb 05 17:04:22 2013 +0100
   116.3 @@ -18,12 +18,14 @@
   116.4  package org.apidesign.bck2brwsr.launcher;
   116.5  
   116.6  import java.io.Closeable;
   116.7 +import java.io.File;
   116.8  import java.io.IOException;
   116.9  import java.net.URLClassLoader;
  116.10  import org.apidesign.vm4brwsr.Bck2Brwsr;
  116.11  
  116.12  /** An abstraction for executing tests in a Bck2Brwsr virtual machine.
  116.13 - * Either in JavaScript engine, or in external browser.
  116.14 + * Either in {@linkm Launcher#createJavaScript JavaScript engine}, 
  116.15 + * or in {@linkm Launcher#createBrowser external browser}.
  116.16   *
  116.17   * @author Jaroslav Tulach <jtulach@netbeans.org>
  116.18   */
  116.19 @@ -31,33 +33,83 @@
  116.20  
  116.21      Launcher() {
  116.22      }
  116.23 +
  116.24 +    /** Initializes the launcher. This may mean starting a web browser or
  116.25 +     * initializing execution engine.
  116.26 +     * @throws IOException if something goes wrong
  116.27 +     */
  116.28 +    public abstract void initialize() throws IOException;
  116.29      
  116.30 -    abstract MethodInvocation addMethod(Class<?> clazz, String method, String html) throws IOException; 
  116.31 -
  116.32 -    public abstract void initialize() throws IOException;
  116.33 +    /** Shuts down the launcher.
  116.34 +     * @throws IOException if something goes wrong
  116.35 +     */
  116.36      public abstract void shutdown() throws IOException;
  116.37 -    public MethodInvocation invokeMethod(Class<?> clazz, String method, String html) throws IOException {
  116.38 -        return addMethod(clazz, method, html);
  116.39 +    
  116.40 +    
  116.41 +    /** Builds an invocation context. The context can later be customized
  116.42 +     * and {@link InvocationContext#invoke() invoked}.
  116.43 +     * 
  116.44 +     * @param clazz the class to execute method from
  116.45 +     * @param method the method to execute
  116.46 +     * @return the context pointing to the selected method
  116.47 +     */
  116.48 +    public InvocationContext createInvocation(Class<?> clazz, String method) {
  116.49 +        return new InvocationContext(this, clazz, method);
  116.50      }
  116.51      
  116.52 -    
  116.53  
  116.54 +    /** Creates launcher that uses internal JavaScript engine (Rhino).
  116.55 +     * @return the launcher
  116.56 +     */
  116.57      public static Launcher createJavaScript() {
  116.58          final JSLauncher l = new JSLauncher();
  116.59          l.addClassLoader(Bck2Brwsr.class.getClassLoader());
  116.60          return l;
  116.61      }
  116.62      
  116.63 +    /** Creates launcher that is using external browser.
  116.64 +     * 
  116.65 +     * @param cmd <code>null</code> to use <code>java.awt.Desktop</code> to show the launcher
  116.66 +     *    or a string to execute in an external process (with a parameter to the URL)
  116.67 +     * @return launcher executing in external browser.
  116.68 +     */
  116.69      public static Launcher createBrowser(String cmd) {
  116.70          final Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(cmd);
  116.71          l.addClassLoader(Bck2Brwsr.class.getClassLoader());
  116.72          l.setTimeout(180000);
  116.73          return l;
  116.74      }
  116.75 +    
  116.76 +    /** Starts an HTTP server which provides access to classes and resources
  116.77 +     * available in the <code>classes</code> URL and shows a start page
  116.78 +     * available as {@link ClassLoader#getResource(java.lang.String)} from the
  116.79 +     * provide classloader. Opens a browser with URL showing the start page.
  116.80 +     * 
  116.81 +     * @param classes classloader offering access to classes and resources
  116.82 +     * @param startpage page to show in the browser
  116.83 +     * @return interface that allows one to stop the server
  116.84 +     * @throws IOException if something goes wrong
  116.85 +     */
  116.86      public static Closeable showURL(URLClassLoader classes, String startpage) throws IOException {
  116.87          Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(null);
  116.88          l.addClassLoader(classes);
  116.89          l.showURL(startpage);
  116.90          return l;
  116.91      }
  116.92 +    /** Starts an HTTP server which provides access to certain directory.
  116.93 +     * The <code>startpage</code> should be relative location inside the root 
  116.94 +     * driecotry
  116.95 +     * Opens a browser with URL showing the start page.
  116.96 +     * 
  116.97 +     * @param directory the root directory on disk
  116.98 +     * @praam startpage relative path from the root to the page
  116.99 +     * @exception IOException if something goes wrong.
 116.100 +     */
 116.101 +    public static Closeable showDir(File directory, String startpage) throws IOException {
 116.102 +        Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(null);
 116.103 +        l.showDirectory(directory, startpage);
 116.104 +        return l;
 116.105 +    }
 116.106 +
 116.107 +    abstract InvocationContext runMethod(InvocationContext c) throws IOException; 
 116.108  }
   117.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/MethodInvocation.java	Tue Feb 05 16:40:01 2013 +0100
   117.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   117.3 @@ -1,59 +0,0 @@
   117.4 -/**
   117.5 - * Back 2 Browser Bytecode Translator
   117.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   117.7 - *
   117.8 - * This program is free software: you can redistribute it and/or modify
   117.9 - * it under the terms of the GNU General Public License as published by
  117.10 - * the Free Software Foundation, version 2 of the License.
  117.11 - *
  117.12 - * This program is distributed in the hope that it will be useful,
  117.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  117.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  117.15 - * GNU General Public License for more details.
  117.16 - *
  117.17 - * You should have received a copy of the GNU General Public License
  117.18 - * along with this program. Look for COPYING file in the top folder.
  117.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
  117.20 - */
  117.21 -package org.apidesign.bck2brwsr.launcher;
  117.22 -
  117.23 -import java.util.concurrent.CountDownLatch;
  117.24 -import java.util.concurrent.TimeUnit;
  117.25 -
  117.26 -/**
  117.27 - *
  117.28 - * @author Jaroslav Tulach <jtulach@netbeans.org>
  117.29 - */
  117.30 -public final class MethodInvocation {
  117.31 -    final CountDownLatch wait = new CountDownLatch(1);
  117.32 -    final String className;
  117.33 -    final String methodName;
  117.34 -    final String html;
  117.35 -    private String result;
  117.36 -    private Throwable exception;
  117.37 -
  117.38 -    MethodInvocation(String className, String methodName, String html) {
  117.39 -        this.className = className;
  117.40 -        this.methodName = methodName;
  117.41 -        this.html = html;
  117.42 -    }
  117.43 -    
  117.44 -    void await(long timeOut) throws InterruptedException {
  117.45 -        wait.await(timeOut, TimeUnit.MILLISECONDS);
  117.46 -    }
  117.47 -    
  117.48 -    void result(String r, Throwable e) {
  117.49 -        this.result = r;
  117.50 -        this.exception = e;
  117.51 -        wait.countDown();
  117.52 -    }
  117.53 -
  117.54 -    @Override
  117.55 -    public String toString() {
  117.56 -        if (exception != null) {
  117.57 -            return exception.toString();
  117.58 -        }
  117.59 -        return result;
  117.60 -    }
  117.61 -    
  117.62 -}
   118.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   118.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/impl/Console.java	Tue Feb 05 17:04:22 2013 +0100
   118.3 @@ -0,0 +1,255 @@
   118.4 +/**
   118.5 + * Back 2 Browser Bytecode Translator
   118.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   118.7 + *
   118.8 + * This program is free software: you can redistribute it and/or modify
   118.9 + * it under the terms of the GNU General Public License as published by
  118.10 + * the Free Software Foundation, version 2 of the License.
  118.11 + *
  118.12 + * This program is distributed in the hope that it will be useful,
  118.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  118.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  118.15 + * GNU General Public License for more details.
  118.16 + *
  118.17 + * You should have received a copy of the GNU General Public License
  118.18 + * along with this program. Look for COPYING file in the top folder.
  118.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
  118.20 + */
  118.21 +package org.apidesign.bck2brwsr.launcher.impl;
  118.22 +
  118.23 +import java.io.IOException;
  118.24 +import java.io.InputStream;
  118.25 +import java.lang.reflect.InvocationTargetException;
  118.26 +import java.lang.reflect.Method;
  118.27 +import java.lang.reflect.Modifier;
  118.28 +import java.net.URL;
  118.29 +import java.util.Enumeration;
  118.30 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
  118.31 +
  118.32 +/**
  118.33 + *
  118.34 + * @author Jaroslav Tulach <jtulach@netbeans.org>
  118.35 + */
  118.36 +public class Console {
  118.37 +    private Console() {
  118.38 +    }
  118.39 +    static {
  118.40 +        turnAssetionStatusOn();
  118.41 +    }
  118.42 +    
  118.43 +    @JavaScriptBody(args = {"id", "attr"}, body = 
  118.44 +        "return window.document.getElementById(id)[attr].toString();")
  118.45 +    private static native Object getAttr(String id, String attr);
  118.46 +
  118.47 +    @JavaScriptBody(args = {"id", "attr", "value"}, body = 
  118.48 +        "window.document.getElementById(id)[attr] = value;")
  118.49 +    private static native void setAttr(String id, String attr, Object value);
  118.50 +    
  118.51 +    @JavaScriptBody(args = {}, body = "return; window.close();")
  118.52 +    private static native void closeWindow();
  118.53 +
  118.54 +    private static void log(String newText) {
  118.55 +        String id = "bck2brwsr.result";
  118.56 +        String attr = "value";
  118.57 +        setAttr(id, attr, getAttr(id, attr) + "\n" + newText);
  118.58 +        setAttr(id, "scrollTop", getAttr(id, "scrollHeight"));
  118.59 +    }
  118.60 +    
  118.61 +    public static void execute() throws Exception {
  118.62 +        String clazz = (String) getAttr("clazz", "value");
  118.63 +        String method = (String) getAttr("method", "value");
  118.64 +        Object res = invokeMethod(clazz, method);
  118.65 +        setAttr("bck2brwsr.result", "value", res);
  118.66 +    }
  118.67 +
  118.68 +    @JavaScriptBody(args = { "url", "callback", "arr" }, body = ""
  118.69 +        + "var request = new XMLHttpRequest();\n"
  118.70 +        + "request.open('GET', url, true);\n"
  118.71 +        + "request.onreadystatechange = function() {\n"
  118.72 +        + "  if (this.readyState!==4) return;\n"
  118.73 +        + "  arr[0] = this.responseText;\n"
  118.74 +        + "  callback.run__V();\n"
  118.75 +        + "};"
  118.76 +        + "request.send();"
  118.77 +    )
  118.78 +    private static native void loadText(String url, Runnable callback, String[] arr) throws IOException;
  118.79 +    
  118.80 +    public static void harness(String url) throws IOException {
  118.81 +        log("Connecting to " + url);
  118.82 +        Request r = new Request(url);
  118.83 +    }
  118.84 +    
  118.85 +    private static class Request implements Runnable {
  118.86 +        private final String[] arr = { null };
  118.87 +        private final String url;
  118.88 +
  118.89 +        private Request(String url) throws IOException {
  118.90 +            this.url = url;
  118.91 +            loadText(url, this, arr);
  118.92 +        }
  118.93 +        
  118.94 +        @Override
  118.95 +        public void run() {
  118.96 +            try {
  118.97 +                String data = arr[0];
  118.98 +                log("\nGot \"" + data + "\"");
  118.99 +                
 118.100 +                if (data == null) {
 118.101 +                    log("Some error exiting");
 118.102 +                    closeWindow();
 118.103 +                    return;
 118.104 +                }
 118.105 +                
 118.106 +                if (data.isEmpty()) {
 118.107 +                    log("No data, exiting");
 118.108 +                    closeWindow();
 118.109 +                    return;
 118.110 +                }
 118.111 +                
 118.112 +                Case c = Case.parseData(data);
 118.113 +                if (c.getHtmlFragment() != null) {
 118.114 +                    setAttr("bck2brwsr.fragment", "innerHTML", c.getHtmlFragment());
 118.115 +                }
 118.116 +                log("Invoking " + c.getClassName() + '.' + c.getMethodName() + " as request: " + c.getRequestId());
 118.117 +
 118.118 +                Object result = invokeMethod(c.getClassName(), c.getMethodName());
 118.119 +                
 118.120 +                setAttr("bck2brwsr.fragment", "innerHTML", "");
 118.121 +                log("Result: " + result);
 118.122 +                
 118.123 +                result = encodeURL("" + result);
 118.124 +                
 118.125 +                log("Sending back: " + url + "?request=" + c.getRequestId() + "&result=" + result);
 118.126 +                String u = url + "?request=" + c.getRequestId() + "&result=" + result;
 118.127 +                
 118.128 +                loadText(u, this, arr);
 118.129 +                
 118.130 +            } catch (Exception ex) {
 118.131 +                log(ex.getMessage());
 118.132 +            }
 118.133 +        }
 118.134 +    }
 118.135 +    
 118.136 +    private static String encodeURL(String r) {
 118.137 +        StringBuilder sb = new StringBuilder();
 118.138 +        for (int i = 0; i < r.length(); i++) {
 118.139 +            int ch = r.charAt(i);
 118.140 +            if (ch < 32 || ch == '%' || ch == '+') {
 118.141 +                sb.append("%").append(("0" + Integer.toHexString(ch)).substring(0, 2));
 118.142 +            } else {
 118.143 +                if (ch == 32) {
 118.144 +                    sb.append("+");
 118.145 +                } else {
 118.146 +                    sb.append((char)ch);
 118.147 +                }
 118.148 +            }
 118.149 +        }
 118.150 +        return sb.toString();
 118.151 +    }
 118.152 +    
 118.153 +    static String invoke(String clazz, String method) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException {
 118.154 +        final Object r = invokeMethod(clazz, method);
 118.155 +        return r == null ? "null" : r.toString().toString();
 118.156 +    }
 118.157 +
 118.158 +    /** Helper method that inspects the classpath and loads given resource
 118.159 +     * (usually a class file). Used while running tests in Rhino.
 118.160 +     * 
 118.161 +     * @param name resource name to find
 118.162 +     * @return the array of bytes in the given resource
 118.163 +     * @throws IOException I/O in case something goes wrong
 118.164 +     */
 118.165 +    public static byte[] read(String name) throws IOException {
 118.166 +        URL u = null;
 118.167 +        Enumeration<URL> en = Console.class.getClassLoader().getResources(name);
 118.168 +        while (en.hasMoreElements()) {
 118.169 +            u = en.nextElement();
 118.170 +        }
 118.171 +        if (u == null) {
 118.172 +            throw new IOException("Can't find " + name);
 118.173 +        }
 118.174 +        try (InputStream is = u.openStream()) {
 118.175 +            byte[] arr;
 118.176 +            arr = new byte[is.available()];
 118.177 +            int offset = 0;
 118.178 +            while (offset < arr.length) {
 118.179 +                int len = is.read(arr, offset, arr.length - offset);
 118.180 +                if (len == -1) {
 118.181 +                    throw new IOException("Can't read " + name);
 118.182 +                }
 118.183 +                offset += len;
 118.184 +            }
 118.185 +            return arr;
 118.186 +        }
 118.187 +    }
 118.188 +   
 118.189 +    private static Object invokeMethod(String clazz, String method) 
 118.190 +    throws ClassNotFoundException, InvocationTargetException, 
 118.191 +    SecurityException, IllegalAccessException, IllegalArgumentException,
 118.192 +    InstantiationException {
 118.193 +        Method found = null;
 118.194 +        Class<?> c = Class.forName(clazz);
 118.195 +        for (Method m : c.getMethods()) {
 118.196 +            if (m.getName().equals(method)) {
 118.197 +                found = m;
 118.198 +            }
 118.199 +        }
 118.200 +        Object res;
 118.201 +        if (found != null) {
 118.202 +            try {
 118.203 +                if ((found.getModifiers() & Modifier.STATIC) != 0) {
 118.204 +                    res = found.invoke(null);
 118.205 +                } else {
 118.206 +                    res = found.invoke(c.newInstance());
 118.207 +                }
 118.208 +            } catch (Throwable ex) {
 118.209 +                res = ex.getClass().getName() + ":" + ex.getMessage();
 118.210 +            }
 118.211 +        } else {
 118.212 +            res = "Can't find method " + method + " in " + clazz;
 118.213 +        }
 118.214 +        return res;
 118.215 +    }
 118.216 +
 118.217 +    @JavaScriptBody(args = {}, body = "vm.desiredAssertionStatus = true;")
 118.218 +    private static void turnAssetionStatusOn() {
 118.219 +    }
 118.220 +    
 118.221 +    private static final class Case {
 118.222 +        private final Object data;
 118.223 +
 118.224 +        private Case(Object data) {
 118.225 +            this.data = data;
 118.226 +        }
 118.227 +        
 118.228 +        public static Case parseData(String s) {
 118.229 +            return new Case(toJSON(s));
 118.230 +        }
 118.231 +        
 118.232 +        public String getMethodName() {
 118.233 +            return value("methodName", data);
 118.234 +        }
 118.235 +
 118.236 +        public String getClassName() {
 118.237 +            return value("className", data);
 118.238 +        }
 118.239 +        
 118.240 +        public String getRequestId() {
 118.241 +            return value("request", data);
 118.242 +        }
 118.243 +
 118.244 +        public String getHtmlFragment() {
 118.245 +            return value("html", data);
 118.246 +        }
 118.247 +        
 118.248 +        @JavaScriptBody(args = "s", body = "return eval('(' + s + ')');")
 118.249 +        private static native Object toJSON(String s);
 118.250 +        
 118.251 +        @JavaScriptBody(args = {"p", "d"}, body = 
 118.252 +              "var v = d[p];\n"
 118.253 +            + "if (typeof v === 'undefined') return null;\n"
 118.254 +            + "return v.toString();"
 118.255 +        )
 118.256 +        private static native String value(String p, Object d);
 118.257 +    }
 118.258 +}
   119.1 --- a/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml	Tue Feb 05 16:40:01 2013 +0100
   119.2 +++ b/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml	Tue Feb 05 17:04:22 2013 +0100
   119.3 @@ -34,7 +34,7 @@
   119.4          <div id="bck2brwsr.fragment"/>
   119.5          
   119.6          <script type="text/javascript">
   119.7 -            vm.loadClass('org.apidesign.bck2brwsr.launcher.Console').harness__VLjava_lang_String_2('$U/../data');
   119.8 +            vm.loadClass('org.apidesign.bck2brwsr.launcher.impl.Console').harness__VLjava_lang_String_2('$U/../data');
   119.9          </script>
  119.10      </body>
  119.11  </html>
   120.1 --- a/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java	Tue Feb 05 16:40:01 2013 +0100
   120.2 +++ b/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java	Tue Feb 05 17:04:22 2013 +0100
   120.3 @@ -51,21 +51,28 @@
   120.4      /** Root of the class files */
   120.5      @Parameter(defaultValue="${project.build.directory}/classes")
   120.6      private File classes;
   120.7 +    
   120.8 +    /** Root of all pages, and files, etc. */
   120.9 +    @Parameter
  120.10 +    private File directory;
  120.11  
  120.12      @Override
  120.13      public void execute() throws MojoExecutionException {
  120.14          if (startpage == null) {
  120.15              throw new MojoExecutionException("You have to provide a start page");
  120.16          }
  120.17 -
  120.18 +        
  120.19          try {
  120.20 -            URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
  120.21 -            
  120.22              Closeable httpServer;
  120.23 -            try {
  120.24 -                httpServer = Launcher.showURL(url, startpage());
  120.25 -            } catch (Exception ex) {
  120.26 -                throw new MojoExecutionException("Can't open " + startpage(), ex);
  120.27 +            if (directory != null) {
  120.28 +                httpServer = Launcher.showDir(directory, startpage);
  120.29 +            } else {
  120.30 +                URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
  120.31 +                try {
  120.32 +                    httpServer = Launcher.showURL(url, startpage());
  120.33 +                } catch (Exception ex) {
  120.34 +                    throw new MojoExecutionException("Can't open " + startpage(), ex);
  120.35 +                }
  120.36              }
  120.37              System.in.read();
  120.38              httpServer.close();
   121.1 --- a/mojo/src/main/resources/archetype-resources/pom.xml	Tue Feb 05 16:40:01 2013 +0100
   121.2 +++ b/mojo/src/main/resources/archetype-resources/pom.xml	Tue Feb 05 17:04:22 2013 +0100
   121.3 @@ -60,7 +60,7 @@
   121.4        <scope>test</scope>
   121.5      </dependency>
   121.6      <dependency>
   121.7 -      <groupId>${project.groupId}</groupId>
   121.8 +      <groupId>org.apidesign.bck2brwsr</groupId>
   121.9        <artifactId>vmtest</artifactId>
  121.10        <version>0.3-SNAPSHOT</version>
  121.11        <scope>test</scope>
   122.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Tue Feb 05 16:40:01 2013 +0100
   122.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Tue Feb 05 17:04:22 2013 +0100
   122.3 @@ -1278,7 +1278,7 @@
   122.4                      int indx = readIntArg(byteCodes, i);
   122.5                      final String type = jc.getClassName(indx);
   122.6                      if (!type.startsWith("[")) {
   122.7 -                        emit(out, "var @2 = @1.$instOf_@3 ? 1 : 0;",
   122.8 +                        emit(out, "var @2 = @1 != null && @1.$instOf_@3 ? 1 : 0;",
   122.9                               smapper.popA(), smapper.pushI(),
  122.10                               type.replace('/', '_'));
  122.11                      } else {
   123.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Tue Feb 05 16:40:01 2013 +0100
   123.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Tue Feb 05 17:04:22 2013 +0100
   123.3 @@ -32,6 +32,7 @@
   123.4      static {
   123.5          // uses VMLazy to load dynamic classes
   123.6          VMLazy.init();
   123.7 +        Zips.init();
   123.8      }
   123.9  
  123.10      @Override
  123.11 @@ -116,6 +117,12 @@
  123.12              + "    var args = arguments;\n"
  123.13              + "    var loader = {};\n"
  123.14              + "    loader.vm = vm;\n"
  123.15 +            + "    if (args.length == 1 && typeof args[0] !== 'function') {;\n"
  123.16 +            + "      var classpath = args[0];\n"
  123.17 +            + "      args[0] = function(name) {\n"
  123.18 +            + "        return vm.org_apidesign_vm4brwsr_Zips(false).loadFromCp___3B_3Ljava_lang_Object_2Ljava_lang_String_2(classpath, name);\n"
  123.19 +            + "      };\n"
  123.20 +            + "    };\n"
  123.21              + "    loader.loadClass = function(name) {\n"
  123.22              + "      var attr = name.replace__Ljava_lang_String_2CC('.','_');\n"
  123.23              + "      var fn = vm[attr];\n"
   124.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   124.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/Zips.java	Tue Feb 05 17:04:22 2013 +0100
   124.3 @@ -0,0 +1,97 @@
   124.4 +/**
   124.5 + * Back 2 Browser Bytecode Translator
   124.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   124.7 + *
   124.8 + * This program is free software: you can redistribute it and/or modify
   124.9 + * it under the terms of the GNU General Public License as published by
  124.10 + * the Free Software Foundation, version 2 of the License.
  124.11 + *
  124.12 + * This program is distributed in the hope that it will be useful,
  124.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  124.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  124.15 + * GNU General Public License for more details.
  124.16 + *
  124.17 + * You should have received a copy of the GNU General Public License
  124.18 + * along with this program. Look for COPYING file in the top folder.
  124.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
  124.20 + */
  124.21 +package org.apidesign.vm4brwsr;
  124.22 +
  124.23 +import java.io.IOException;
  124.24 +import java.net.URL;
  124.25 +import java.util.zip.ZipEntry;
  124.26 +import java.util.zip.ZipInputStream;
  124.27 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
  124.28 +
  124.29 +/** Conversion from classpath to load function.
  124.30 + *
  124.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
  124.32 + */
  124.33 +final class Zips {
  124.34 +    private Zips() {
  124.35 +    }
  124.36 +    
  124.37 +    public static void init() {
  124.38 +    }
  124.39 +    
  124.40 +    public static byte[] loadFromCp(Object[] classpath, String res) {
  124.41 +        for (int i = 0; i < classpath.length; i++) {
  124.42 +            Object c = classpath[i];
  124.43 +            if (c instanceof String) {
  124.44 +                try {
  124.45 +                    c = classpath[i] = toZip((String)c);
  124.46 +                } catch (IOException ex) {
  124.47 +                    classpath[i] = ex;
  124.48 +                }
  124.49 +            }
  124.50 +            if (c instanceof Zips) {
  124.51 +                Object checkRes = ((Zips)c).findRes(res);
  124.52 +                if (checkRes instanceof byte[]) {
  124.53 +                    return (byte[])checkRes;
  124.54 +                }
  124.55 +            }
  124.56 +        }
  124.57 +        return null;
  124.58 +    }
  124.59 +
  124.60 +    @JavaScriptBody(args = { "res" }, body = "var r = this[res]; return r ? r : null;")
  124.61 +    private native byte[] findRes(String res);
  124.62 +
  124.63 +    @JavaScriptBody(args = { "res", "arr" }, body = "this[res] = arr;")
  124.64 +    private native void putRes(String res, byte[] arr);
  124.65 +    
  124.66 +    private static Zips toZip(String path) throws IOException {
  124.67 +        URL u = new URL(path);
  124.68 +        ZipInputStream zip = new ZipInputStream(u.openStream());
  124.69 +        Zips z = new Zips();
  124.70 +        for (;;) {
  124.71 +            ZipEntry entry = zip.getNextEntry();
  124.72 +            if (entry == null) {
  124.73 +                break;
  124.74 +            }
  124.75 +            byte[] arr = new byte[4096];
  124.76 +            int offset = 0;
  124.77 +            for (;;) {
  124.78 +                int len = zip.read(arr, offset, arr.length - offset);
  124.79 +                if (len == -1) {
  124.80 +                    break;
  124.81 +                }
  124.82 +                offset += len;
  124.83 +                if (offset == arr.length) {
  124.84 +                    enlargeArray(arr, arr.length + 4096);
  124.85 +                }
  124.86 +            }
  124.87 +            sliceArray(arr, offset);
  124.88 +            z.putRes(entry.getName(), arr);
  124.89 +        }
  124.90 +        return z;
  124.91 +    }
  124.92 +
  124.93 +    @JavaScriptBody(args = { "arr", "len" }, body = "while (arr.length < len) arr.push(0);")
  124.94 +    private static native void enlargeArray(byte[] arr, int len);
  124.95 +
  124.96 +    @JavaScriptBody(args = { "arr", "len" }, body = "arr.splice(len, arr.length - len);")
  124.97 +    private static native void sliceArray(byte[] arr, int len);
  124.98 +    
  124.99 +    
 124.100 +}
   125.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java	Tue Feb 05 16:40:01 2013 +0100
   125.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java	Tue Feb 05 17:04:22 2013 +0100
   125.3 @@ -68,12 +68,12 @@
   125.4          GetByte i = new InstanceSub(7, 2.2d);
   125.5          return i.getByte();
   125.6      }
   125.7 -    public static boolean instanceOf(boolean sub) {
   125.8 +    public static boolean instanceOf(int sub) {
   125.9          Instance i = createInstance(sub);
  125.10          return isInstanceSubOf(i);
  125.11      }
  125.12      public static int castsWork(boolean interfc) {
  125.13 -        Instance i = createInstance(true);
  125.14 +        Instance i = createInstance(2);
  125.15          if (interfc) {
  125.16              GetByte b = (GetByte)i;
  125.17          } else {
  125.18 @@ -85,11 +85,16 @@
  125.19      private static boolean isInstanceSubOf(Instance instance) {
  125.20          return instance instanceof InstanceSub;
  125.21      }
  125.22 -    private static Instance createInstance(boolean sub) {
  125.23 -        return sub ? new InstanceSub(3, 0) : new Instance();
  125.24 +    private static Instance createInstance(int type) {
  125.25 +        switch (type) {
  125.26 +            case 0: return null;
  125.27 +            case 1: return new Instance();
  125.28 +            case 2: return new InstanceSub(3, 0);
  125.29 +        }
  125.30 +        throw new IllegalArgumentException();
  125.31      }
  125.32      private static boolean isNull() {
  125.33 -        return createInstance(true) == null;
  125.34 +        return createInstance(2) == null;
  125.35      }
  125.36      
  125.37      @JavaScriptBody(args = "obj", body = "return obj.constructor;")
   126.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java	Tue Feb 05 16:40:01 2013 +0100
   126.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java	Tue Feb 05 17:04:22 2013 +0100
   126.3 @@ -80,16 +80,23 @@
   126.4      @Test public void isInstanceOf() throws Exception {
   126.5          assertExec(
   126.6              "Yes, we are instance",
   126.7 -            Instance.class, "instanceOf__ZZ",
   126.8 -            Double.valueOf(1.0), true
   126.9 +            Instance.class, "instanceOf__ZI",
  126.10 +            Double.valueOf(1.0), 2
  126.11          );
  126.12      }
  126.13  
  126.14      @Test public void notInstanceOf() throws Exception {
  126.15          assertExec(
  126.16              "No, we are not an instance",
  126.17 -            Instance.class, "instanceOf__ZZ",
  126.18 -            Double.valueOf(0.0), false
  126.19 +            Instance.class, "instanceOf__ZI",
  126.20 +            Double.valueOf(0.0), 1
  126.21 +        );
  126.22 +    }
  126.23 +    @Test public void nullInstanceOf() throws Exception {
  126.24 +        assertExec(
  126.25 +            "No, null is not an instance",
  126.26 +            Instance.class, "instanceOf__ZI",
  126.27 +            Double.valueOf(0.0), 0
  126.28          );
  126.29      }
  126.30      
   127.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java	Tue Feb 05 16:40:01 2013 +0100
   127.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java	Tue Feb 05 17:04:22 2013 +0100
   127.3 @@ -78,6 +78,89 @@
   127.4              3.0d, 1l
   127.5          );
   127.6      }
   127.7 +    
   127.8 +    @Test public void rintNegativeUp() throws Exception {
   127.9 +        final double cnts = -453904.634;
  127.10 +        assertExec(
  127.11 +            "Should round up to end with 5",
  127.12 +            Math.class, "rint__DD", 
  127.13 +            -453905.0, cnts
  127.14 +        );
  127.15 +    }
  127.16 +
  127.17 +    @Test public void rintNegativeDown() throws Exception {
  127.18 +        final double cnts = -453904.434;
  127.19 +        assertExec(
  127.20 +            "Should round up to end with 4",
  127.21 +            Math.class, "rint__DD", 
  127.22 +            -453904.0, cnts
  127.23 +        );
  127.24 +    }
  127.25 +
  127.26 +    @Test public void rintPositiveUp() throws Exception {
  127.27 +        final double cnts = 453904.634;
  127.28 +        assertExec(
  127.29 +            "Should round up to end with 5",
  127.30 +            Math.class, "rint__DD", 
  127.31 +            453905.0, cnts
  127.32 +        );
  127.33 +    }
  127.34 +    @Test public void rintPositiveDown() throws Exception {
  127.35 +        final double cnts = 453904.434;
  127.36 +        assertExec(
  127.37 +            "Should round up to end with 4",
  127.38 +            Math.class, "rint__DD", 
  127.39 +            453904.0, cnts
  127.40 +        );
  127.41 +    }
  127.42 +    @Test public void rintOneHalf() throws Exception {
  127.43 +        final double cnts = 1.5;
  127.44 +        assertExec(
  127.45 +            "Should round up to end with 2",
  127.46 +            Math.class, "rint__DD", 
  127.47 +            2.0, cnts
  127.48 +        );
  127.49 +    }
  127.50 +    @Test public void rintNegativeOneHalf() throws Exception {
  127.51 +        final double cnts = -1.5;
  127.52 +        assertExec(
  127.53 +            "Should round up to end with 2",
  127.54 +            Math.class, "rint__DD", 
  127.55 +            -2.0, cnts
  127.56 +        );
  127.57 +    }
  127.58 +    @Test public void rintTwoAndHalf() throws Exception {
  127.59 +        final double cnts = 2.5;
  127.60 +        assertExec(
  127.61 +            "Should round up to end with 2",
  127.62 +            Math.class, "rint__DD", 
  127.63 +            2.0, cnts
  127.64 +        );
  127.65 +    }
  127.66 +    @Test public void rintNegativeTwoOneHalf() throws Exception {
  127.67 +        final double cnts = -2.5;
  127.68 +        assertExec(
  127.69 +            "Should round up to end with 2",
  127.70 +            Math.class, "rint__DD", 
  127.71 +            -2.0, cnts
  127.72 +        );
  127.73 +    }
  127.74 +
  127.75 +    @Test public void ieeeReminder1() throws Exception {
  127.76 +        assertExec(
  127.77 +            "Same result 1",
  127.78 +            Math.class, "IEEEremainder__DDD", 
  127.79 +            Math.IEEEremainder(10.0, 4.5), 10.0, 4.5
  127.80 +        );
  127.81 +    }
  127.82 +
  127.83 +    @Test public void ieeeReminder2() throws Exception {
  127.84 +        assertExec(
  127.85 +            "Same result 1",
  127.86 +            Math.class, "IEEEremainder__DDD", 
  127.87 +            Math.IEEEremainder(Integer.MAX_VALUE, -4.5), Integer.MAX_VALUE, -4.5
  127.88 +        );
  127.89 +    }
  127.90  
  127.91      @Test public void divAndRound() throws Exception {
  127.92          assertExec(
   128.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/StringSample.java	Tue Feb 05 16:40:01 2013 +0100
   128.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StringSample.java	Tue Feb 05 17:04:22 2013 +0100
   128.3 @@ -68,6 +68,15 @@
   128.4          return chars('a', (char)30, 'b') instanceof String;
   128.5      }
   128.6      
   128.7 +    public static String getBytes(String s) {
   128.8 +        byte[] arr = s.getBytes();
   128.9 +        StringBuilder sb = new StringBuilder();
  128.10 +        for (int i = 0; i < arr.length; i++) {
  128.11 +            sb.append(arr[i]).append(" ");
  128.12 +        }
  128.13 +        return sb.toString().toString();
  128.14 +    }
  128.15 +    
  128.16      public static String insertBuffer() {
  128.17          StringBuilder sb = new StringBuilder();
  128.18          sb.append("Jardo!");
   129.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/StringTest.java	Tue Feb 05 16:40:01 2013 +0100
   129.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StringTest.java	Tue Feb 05 17:04:22 2013 +0100
   129.3 @@ -75,6 +75,16 @@
   129.4          );
   129.5      }
   129.6  
   129.7 +    @Test public void getBytes() throws Exception {
   129.8 +        final String horse = "Žluťoučký kůň";
   129.9 +        final String expected = StringSample.getBytes(horse);
  129.10 +        assertExec(
  129.11 +            "Bytes look simplar",
  129.12 +            StringSample.class, "getBytes__Ljava_lang_String_2Ljava_lang_String_2",
  129.13 +            expected, horse
  129.14 +        );
  129.15 +    }
  129.16 +
  129.17      @Test(timeOut=10000) public void toStringConcatenation() throws Exception {
  129.18          assertExec(
  129.19              "Five executions should generate 5Hello World!",
   130.1 --- a/vmtest/pom.xml	Tue Feb 05 16:40:01 2013 +0100
   130.2 +++ b/vmtest/pom.xml	Tue Feb 05 17:04:22 2013 +0100
   130.3 @@ -58,5 +58,10 @@
   130.4        <artifactId>launcher</artifactId>
   130.5        <version>${project.version}</version>
   130.6      </dependency>
   130.7 +    <dependency>
   130.8 +      <groupId>org.netbeans.api</groupId>
   130.9 +      <artifactId>org-openide-util-lookup</artifactId>
  130.10 +      <scope>provided</scope>
  130.11 +    </dependency>
  130.12    </dependencies>
  130.13  </project>
   131.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   131.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/HttpResource.java	Tue Feb 05 17:04:22 2013 +0100
   131.3 @@ -0,0 +1,43 @@
   131.4 +/**
   131.5 + * Back 2 Browser Bytecode Translator
   131.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   131.7 + *
   131.8 + * This program is free software: you can redistribute it and/or modify
   131.9 + * it under the terms of the GNU General Public License as published by
  131.10 + * the Free Software Foundation, version 2 of the License.
  131.11 + *
  131.12 + * This program is distributed in the hope that it will be useful,
  131.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  131.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  131.15 + * GNU General Public License for more details.
  131.16 + *
  131.17 + * You should have received a copy of the GNU General Public License
  131.18 + * along with this program. Look for COPYING file in the top folder.
  131.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
  131.20 + */
  131.21 +package org.apidesign.bck2brwsr.vmtest;
  131.22 +
  131.23 +import java.lang.annotation.ElementType;
  131.24 +import java.lang.annotation.Retention;
  131.25 +import java.lang.annotation.RetentionPolicy;
  131.26 +import java.lang.annotation.Target;
  131.27 +
  131.28 +/** Exposes an HTTP page to the running {@link BrwsrTest}, so it can access
  131.29 + * under the relative path.
  131.30 + *
  131.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
  131.32 + */
  131.33 +@Retention(RetentionPolicy.RUNTIME)
  131.34 +@Target({ ElementType.METHOD, ElementType.TYPE})
  131.35 +public @interface HttpResource {
  131.36 +    /** path on the server that the test can use to access the exposed resource */
  131.37 +    String path();
  131.38 +    /** the content of the HttpResource */
  131.39 +    String content();
  131.40 +    /** resource relative to the class that should be used instead of <code>content</code>.
  131.41 +     * Leave content equal to empty string.
  131.42 +     */
  131.43 +    String resource() default "";
  131.44 +    /** mime type of the resource */
  131.45 +    String mimeType();
  131.46 +}
   132.1 --- a/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Bck2BrwsrCase.java	Tue Feb 05 16:40:01 2013 +0100
   132.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Bck2BrwsrCase.java	Tue Feb 05 17:04:22 2013 +0100
   132.3 @@ -17,16 +17,18 @@
   132.4   */
   132.5  package org.apidesign.bck2brwsr.vmtest.impl;
   132.6  
   132.7 +import java.io.ByteArrayInputStream;
   132.8  import java.io.File;
   132.9  import java.io.FileWriter;
  132.10  import java.io.IOException;
  132.11 +import java.io.InputStream;
  132.12  import java.lang.reflect.Constructor;
  132.13  import java.lang.reflect.InvocationTargetException;
  132.14  import java.lang.reflect.Method;
  132.15 -import java.util.Map;
  132.16 -import java.util.WeakHashMap;
  132.17  import org.apidesign.bck2brwsr.launcher.Launcher;
  132.18 -import org.apidesign.bck2brwsr.launcher.MethodInvocation;
  132.19 +import org.apidesign.bck2brwsr.launcher.InvocationContext;
  132.20 +import org.apidesign.bck2brwsr.vmtest.HtmlFragment;
  132.21 +import org.apidesign.bck2brwsr.vmtest.HttpResource;
  132.22  import org.testng.ITest;
  132.23  import org.testng.annotations.Test;
  132.24  
  132.25 @@ -39,22 +41,36 @@
  132.26      private final Launcher l;
  132.27      private final String type;
  132.28      private final boolean fail;
  132.29 +    private final HtmlFragment html;
  132.30 +    private final HttpResource http;
  132.31      Object value;
  132.32 -    private final String html;
  132.33  
  132.34 -    Bck2BrwsrCase(Method m, String type, Launcher l, boolean fail, String html) {
  132.35 +    Bck2BrwsrCase(Method m, String type, Launcher l, boolean fail, HtmlFragment html, HttpResource http) {
  132.36          this.l = l;
  132.37          this.m = m;
  132.38          this.type = type;
  132.39          this.fail = fail;
  132.40          this.html = html;
  132.41 +        this.http = http;
  132.42      }
  132.43  
  132.44      @Test(groups = "run")
  132.45      public void executeCode() throws Throwable {
  132.46          if (l != null) {
  132.47 -            MethodInvocation c = l.invokeMethod(m.getDeclaringClass(), m.getName(), html);
  132.48 -            String res = c.toString();
  132.49 +            InvocationContext c = l.createInvocation(m.getDeclaringClass(), m.getName());
  132.50 +            if (html != null) {
  132.51 +                c.setHtmlFragment(html.value());
  132.52 +            }
  132.53 +            if (http != null) {
  132.54 +                if (!http.content().isEmpty()) {
  132.55 +                    InputStream is = new ByteArrayInputStream(http.content().getBytes("UTF-8"));
  132.56 +                    c.setHttpResource(http.path(), http.mimeType(), is);
  132.57 +                } else {
  132.58 +                    InputStream is = m.getDeclaringClass().getResourceAsStream(http.resource());
  132.59 +                    c.setHttpResource(http.path(), http.mimeType(), is);
  132.60 +                }
  132.61 +            }
  132.62 +            String res = c.invoke();
  132.63              value = res;
  132.64              if (fail) {
  132.65                  int idx = res.indexOf(':');
  132.66 @@ -94,6 +110,9 @@
  132.67              } catch (InvocationTargetException ex) {
  132.68                  Throwable t = ex.getTargetException();
  132.69                  value = t.getClass().getName() + ":" + t.getMessage();
  132.70 +                if (t instanceof AssertionError) {
  132.71 +                    throw t;
  132.72 +                }
  132.73              }
  132.74          }
  132.75      }
   133.1 --- a/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/CompareCase.java	Tue Feb 05 16:40:01 2013 +0100
   133.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/CompareCase.java	Tue Feb 05 17:04:22 2013 +0100
   133.3 @@ -111,17 +111,17 @@
   133.4          if (c == null) {
   133.5              return;
   133.6          }
   133.7 -        final Bck2BrwsrCase real = new Bck2BrwsrCase(m, "Java", null, false, null);
   133.8 +        final Bck2BrwsrCase real = new Bck2BrwsrCase(m, "Java", null, false, null, null);
   133.9          ret.add(real);
  133.10          if (c.scripting()) {
  133.11 -            final Bck2BrwsrCase js = new Bck2BrwsrCase(m, "JavaScript", l.javaScript(), false, null);
  133.12 +            final Bck2BrwsrCase js = new Bck2BrwsrCase(m, "JavaScript", l.javaScript(), false, null, null);
  133.13              ret.add(js);
  133.14              ret.add(new CompareCase(m, real, js));
  133.15          }
  133.16          for (String b : brwsr) {
  133.17              final Launcher s = l.brwsr(b);
  133.18              ret.add(s);
  133.19 -            final Bck2BrwsrCase cse = new Bck2BrwsrCase(m, b, s, false, null);
  133.20 +            final Bck2BrwsrCase cse = new Bck2BrwsrCase(m, b, s, false, null, null);
  133.21              ret.add(cse);
  133.22              ret.add(new CompareCase(m, real, cse));
  133.23          }
  133.24 @@ -135,16 +135,19 @@
  133.25          if (f == null) {
  133.26              f = m.getDeclaringClass().getAnnotation(HtmlFragment.class);
  133.27          }
  133.28 -        String html = f == null ? null : f.value();
  133.29 +        HttpResource r = m.getAnnotation(HttpResource.class);
  133.30 +        if (r == null) {
  133.31 +            r = m.getDeclaringClass().getAnnotation(HttpResource.class);
  133.32 +        }
  133.33          if (brwsr.length == 0) {
  133.34              final Launcher s = l.brwsr(null);
  133.35              ret.add(s);
  133.36 -            ret.add(new Bck2BrwsrCase(m, "Brwsr", s, true, html));
  133.37 +            ret.add(new Bck2BrwsrCase(m, "Brwsr", s, true, f, r));
  133.38          } else {
  133.39              for (String b : brwsr) {
  133.40                  final Launcher s = l.brwsr(b);
  133.41                  ret.add(s);
  133.42 -                ret.add(new Bck2BrwsrCase(m, b, s, true, html));
  133.43 +                ret.add(new Bck2BrwsrCase(m, b, s, true, f, r));
  133.44              }
  133.45          }
  133.46      }
   134.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   134.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/GenerateZip.java	Tue Feb 05 17:04:22 2013 +0100
   134.3 @@ -0,0 +1,36 @@
   134.4 +/**
   134.5 + * Back 2 Browser Bytecode Translator
   134.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   134.7 + *
   134.8 + * This program is free software: you can redistribute it and/or modify
   134.9 + * it under the terms of the GNU General Public License as published by
  134.10 + * the Free Software Foundation, version 2 of the License.
  134.11 + *
  134.12 + * This program is distributed in the hope that it will be useful,
  134.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  134.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  134.15 + * GNU General Public License for more details.
  134.16 + *
  134.17 + * You should have received a copy of the GNU General Public License
  134.18 + * along with this program. Look for COPYING file in the top folder.
  134.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
  134.20 + */
  134.21 +package org.apidesign.bck2brwsr.vmtest.impl;
  134.22 +
  134.23 +import java.lang.annotation.Retention;
  134.24 +import java.lang.annotation.RetentionPolicy;
  134.25 +
  134.26 +/** Annotation to generate a ZIP or JAR file during build.
  134.27 + *
  134.28 + * @author Jaroslav Tulach <jtulach@netbeans.org>
  134.29 + */
  134.30 +@Retention(RetentionPolicy.SOURCE)
  134.31 +@interface GenerateZip {
  134.32 +    String name();
  134.33 +    
  134.34 +    /** manifest for the file */
  134.35 +    String manifest() default "";
  134.36 +
  134.37 +    /** Array of names (at odd positions) and their content (on even) */
  134.38 +    String[] contents();
  134.39 +}
   135.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   135.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/GenerateZipProcessor.java	Tue Feb 05 17:04:22 2013 +0100
   135.3 @@ -0,0 +1,98 @@
   135.4 +/**
   135.5 + * Back 2 Browser Bytecode Translator
   135.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   135.7 + *
   135.8 + * This program is free software: you can redistribute it and/or modify
   135.9 + * it under the terms of the GNU General Public License as published by
  135.10 + * the Free Software Foundation, version 2 of the License.
  135.11 + *
  135.12 + * This program is distributed in the hope that it will be useful,
  135.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  135.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  135.15 + * GNU General Public License for more details.
  135.16 + *
  135.17 + * You should have received a copy of the GNU General Public License
  135.18 + * along with this program. Look for COPYING file in the top folder.
  135.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
  135.20 + */
  135.21 +package org.apidesign.bck2brwsr.vmtest.impl;
  135.22 +
  135.23 +import java.io.ByteArrayInputStream;
  135.24 +import java.io.IOException;
  135.25 +import java.io.OutputStream;
  135.26 +import java.util.Set;
  135.27 +import java.util.jar.JarEntry;
  135.28 +import java.util.jar.JarOutputStream;
  135.29 +import java.util.jar.Manifest;
  135.30 +import javax.annotation.processing.AbstractProcessor;
  135.31 +import javax.annotation.processing.Processor;
  135.32 +import javax.annotation.processing.RoundEnvironment;
  135.33 +import javax.annotation.processing.SupportedAnnotationTypes;
  135.34 +import javax.lang.model.element.Element;
  135.35 +import javax.lang.model.element.ElementKind;
  135.36 +import javax.lang.model.element.PackageElement;
  135.37 +import javax.lang.model.element.TypeElement;
  135.38 +import javax.tools.Diagnostic;
  135.39 +import javax.tools.FileObject;
  135.40 +import javax.tools.StandardLocation;
  135.41 +import org.openide.util.lookup.ServiceProvider;
  135.42 +
  135.43 +/**
  135.44 + *
  135.45 + * @author Jaroslav Tulach <jtulach@netbeans.org>
  135.46 + */
  135.47 +@ServiceProvider(service = Processor.class)
  135.48 +@SupportedAnnotationTypes("org.apidesign.bck2brwsr.vmtest.impl.GenerateZip")
  135.49 +public class GenerateZipProcessor extends AbstractProcessor {
  135.50 +
  135.51 +    @Override
  135.52 +    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
  135.53 +        for (Element e : roundEnv.getElementsAnnotatedWith(GenerateZip.class)) {
  135.54 +            GenerateZip gz = e.getAnnotation(GenerateZip.class);
  135.55 +            if (gz == null) {
  135.56 +                continue;
  135.57 +            }
  135.58 +            PackageElement pe = findPackage(e);
  135.59 +            try {
  135.60 +                generateJar(pe, gz, e);
  135.61 +            } catch (IOException ex) {
  135.62 +                processingEnv.getMessager().printMessage(
  135.63 +                    Diagnostic.Kind.ERROR, 
  135.64 +                    "Can't generate JAR " + gz.name() + ": " + ex.getMessage()
  135.65 +                );
  135.66 +            }
  135.67 +        }
  135.68 +        return true;
  135.69 +    }
  135.70 +
  135.71 +    private static PackageElement findPackage(Element e) {
  135.72 +        while (e.getKind() != ElementKind.PACKAGE) {
  135.73 +            e = e.getEnclosingElement();
  135.74 +        }
  135.75 +        return (PackageElement)e;
  135.76 +    }
  135.77 +
  135.78 +    private void generateJar(PackageElement pe, GenerateZip gz, Element e) throws IOException {
  135.79 +        FileObject res = processingEnv.getFiler().createResource(
  135.80 +            StandardLocation.CLASS_OUTPUT, 
  135.81 +            pe.getQualifiedName().toString(), 
  135.82 +            gz.name(), e
  135.83 +        );
  135.84 +        OutputStream os = res.openOutputStream();
  135.85 +        JarOutputStream jar;
  135.86 +        if (gz.manifest().isEmpty()) {
  135.87 +            jar = new JarOutputStream(os);
  135.88 +        } else {
  135.89 +            Manifest mf = new Manifest(new ByteArrayInputStream(gz.manifest().getBytes("UTF-8")));
  135.90 +            jar = new JarOutputStream(os, mf);
  135.91 +        }
  135.92 +        String[] arr = gz.contents();
  135.93 +        for (int i = 0; i < arr.length; i += 2) {
  135.94 +            JarEntry je = new JarEntry(arr[i]);
  135.95 +            jar.putNextEntry(je);
  135.96 +            jar.write(arr[i + 1].getBytes("UTF-8"));
  135.97 +            jar.closeEntry();
  135.98 +        }
  135.99 +    }
 135.100 +    
 135.101 +}
   136.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/AssertionTest.java	Tue Feb 05 16:40:01 2013 +0100
   136.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/AssertionTest.java	Tue Feb 05 17:04:22 2013 +0100
   136.3 @@ -28,8 +28,12 @@
   136.4  public class AssertionTest {
   136.5  
   136.6      @Compare public Object checkAssert() throws ClassNotFoundException {
   136.7 -        assert false : "Is assertion status on?";
   136.8 -        return null;
   136.9 +        try {
  136.10 +            assert false : "Is assertion status on?";
  136.11 +            return null;
  136.12 +        } catch (AssertionError ex) {
  136.13 +            return ex.getClass().getName();
  136.14 +        }
  136.15      }
  136.16      
  136.17      @Factory
   137.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java	Tue Feb 05 16:40:01 2013 +0100
   137.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java	Tue Feb 05 17:04:22 2013 +0100
   137.3 @@ -17,6 +17,7 @@
   137.4   */
   137.5  package org.apidesign.bck2brwsr.tck;
   137.6  
   137.7 +import java.io.UnsupportedEncodingException;
   137.8  import java.net.MalformedURLException;
   137.9  import java.net.URL;
  137.10  import org.apidesign.bck2brwsr.vmtest.Compare;
  137.11 @@ -120,6 +121,21 @@
  137.12          NullField nf = new NullField();
  137.13          return ("" + nf.name).toString();
  137.14      }
  137.15 +    @Compare
  137.16 +    public String toUTFString() throws UnsupportedEncodingException {
  137.17 +        byte[] arr = {
  137.18 +            (byte) -59, (byte) -67, (byte) 108, (byte) 117, (byte) -59, (byte) -91,
  137.19 +            (byte) 111, (byte) 117, (byte) -60, (byte) -115, (byte) 107, (byte) -61,
  137.20 +            (byte) -67, (byte) 32, (byte) 107, (byte) -59, (byte) -81, (byte) -59,
  137.21 +            (byte) -120
  137.22 +        };
  137.23 +        return new String(arr, "utf-8");
  137.24 +    }
  137.25 +
  137.26 +    @Compare
  137.27 +    public int stringToBytesLenght() throws UnsupportedEncodingException {
  137.28 +        return "Žluťoučký kůň".getBytes("utf8").length;
  137.29 +    }
  137.30  
  137.31      @Factory
  137.32      public static Object[] create() {
   138.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   138.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/HttpResourceTest.java	Tue Feb 05 17:04:22 2013 +0100
   138.3 @@ -0,0 +1,94 @@
   138.4 +/**
   138.5 + * Back 2 Browser Bytecode Translator
   138.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   138.7 + *
   138.8 + * This program is free software: you can redistribute it and/or modify
   138.9 + * it under the terms of the GNU General Public License as published by
  138.10 + * the Free Software Foundation, version 2 of the License.
  138.11 + *
  138.12 + * This program is distributed in the hope that it will be useful,
  138.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  138.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  138.15 + * GNU General Public License for more details.
  138.16 + *
  138.17 + * You should have received a copy of the GNU General Public License
  138.18 + * along with this program. Look for COPYING file in the top folder.
  138.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
  138.20 + */
  138.21 +package org.apidesign.bck2brwsr.tck;
  138.22 +
  138.23 +import java.io.InputStream;
  138.24 +import java.net.URL;
  138.25 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
  138.26 +import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
  138.27 +import org.apidesign.bck2brwsr.vmtest.HttpResource;
  138.28 +import org.apidesign.bck2brwsr.vmtest.VMTest;
  138.29 +import org.testng.annotations.Factory;
  138.30 +
  138.31 +/**
  138.32 + *
  138.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
  138.34 + */
  138.35 +public class HttpResourceTest {
  138.36 +    
  138.37 +    @HttpResource(path = "/xhr", content = "Hello Brwsr!", mimeType = "text/plain")
  138.38 +    @BrwsrTest
  138.39 +    public String testReadContentViaXHR() throws Exception {
  138.40 +        String msg = read("/xhr");
  138.41 +        assert "Hello Brwsr!".equals(msg) : "The message was " + msg;
  138.42 +        return msg;
  138.43 +    }
  138.44 +
  138.45 +    @HttpResource(path = "/url", content = "Hello via URL!", mimeType = "text/plain")
  138.46 +    @BrwsrTest
  138.47 +    public String testReadContentViaURL() throws Exception {
  138.48 +        URL url = new URL("http:/url");
  138.49 +        String msg = (String) url.getContent();
  138.50 +        assert "Hello via URL!".equals(msg) : "The message was " + msg;
  138.51 +        return msg;
  138.52 +    }
  138.53 +    @HttpResource(path = "/url", content = "Hello via URL!", mimeType = "text/plain")
  138.54 +    @BrwsrTest
  138.55 +    public String testReadContentViaURLWithStringParam() throws Exception {
  138.56 +        URL url = new URL("http:/url");
  138.57 +        String msg = (String) url.getContent(new Class[] { String.class });
  138.58 +        assert "Hello via URL!".equals(msg) : "The message was " + msg;
  138.59 +        return msg;
  138.60 +    }
  138.61 +
  138.62 +    @HttpResource(path = "/bytes", content = "", resource = "0xfe", mimeType = "x-application/binary")
  138.63 +    @BrwsrTest
  138.64 +    public void testReadByte() throws Exception {
  138.65 +        URL url = new URL("http:/bytes");
  138.66 +        final Object res = url.getContent(new Class[] { byte[].class });
  138.67 +        assert res instanceof byte[] : "Expecting byte[]: " + res;
  138.68 +        byte[] arr = (byte[]) res;
  138.69 +        assert arr.length == 1 : "One byte " + arr.length;
  138.70 +        assert arr[0] == 0xfe : "It is 0xfe: " + Integer.toHexString(arr[0]);
  138.71 +    }
  138.72 +
  138.73 +    @HttpResource(path = "/bytes", content = "", resource = "0xfe", mimeType = "x-application/binary")
  138.74 +    @BrwsrTest
  138.75 +    public void testReadByteViaInputStream() throws Exception {
  138.76 +        URL url = new URL("http:/bytes");
  138.77 +        InputStream is = url.openStream();
  138.78 +        byte[] arr = new byte[10];
  138.79 +        int len = is.read(arr);
  138.80 +        assert len == 1 : "One byte " + len;
  138.81 +        assert arr[0] == 0xfe : "It is 0xfe: " + Integer.toHexString(arr[0]);
  138.82 +    }
  138.83 +    
  138.84 +    @JavaScriptBody(args = { "url" }, body = 
  138.85 +          "var req = new XMLHttpRequest();\n"
  138.86 +        + "req.open('GET', url, false);\n"
  138.87 +        + "req.send();\n"
  138.88 +        + "return req.responseText;"
  138.89 +    )
  138.90 +    private static native String read(String url);
  138.91 +    
  138.92 +    
  138.93 +    @Factory
  138.94 +    public static Object[] create() {
  138.95 +        return VMTest.create(HttpResourceTest.class);
  138.96 +    }
  138.97 +}
   139.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   139.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/CRC32Test.java	Tue Feb 05 17:04:22 2013 +0100
   139.3 @@ -0,0 +1,41 @@
   139.4 +/**
   139.5 + * Back 2 Browser Bytecode Translator
   139.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   139.7 + *
   139.8 + * This program is free software: you can redistribute it and/or modify
   139.9 + * it under the terms of the GNU General Public License as published by
  139.10 + * the Free Software Foundation, version 2 of the License.
  139.11 + *
  139.12 + * This program is distributed in the hope that it will be useful,
  139.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  139.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  139.15 + * GNU General Public License for more details.
  139.16 + *
  139.17 + * You should have received a copy of the GNU General Public License
  139.18 + * along with this program. Look for COPYING file in the top folder.
  139.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
  139.20 + */
  139.21 +package org.apidesign.bck2brwsr.vmtest.impl;
  139.22 +
  139.23 +import java.io.UnsupportedEncodingException;
  139.24 +import java.util.zip.CRC32;
  139.25 +import org.apidesign.bck2brwsr.vmtest.Compare;
  139.26 +import org.apidesign.bck2brwsr.vmtest.VMTest;
  139.27 +import org.testng.annotations.Factory;
  139.28 +
  139.29 +/**
  139.30 + *
  139.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
  139.32 + */
  139.33 +public class CRC32Test {
  139.34 +
  139.35 +    @Compare public long crc1() throws UnsupportedEncodingException {
  139.36 +        CRC32 crc = new CRC32();
  139.37 +        crc.update("Hello World!".getBytes("UTF-8"));
  139.38 +        return crc.getValue();
  139.39 +    }
  139.40 +    
  139.41 +    @Factory public static Object[] create() {
  139.42 +        return VMTest.create(CRC32Test.class);
  139.43 +    }
  139.44 +}
   140.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   140.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipFileTest.java	Tue Feb 05 17:04:22 2013 +0100
   140.3 @@ -0,0 +1,84 @@
   140.4 +/**
   140.5 + * Back 2 Browser Bytecode Translator
   140.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   140.7 + *
   140.8 + * This program is free software: you can redistribute it and/or modify
   140.9 + * it under the terms of the GNU General Public License as published by
  140.10 + * the Free Software Foundation, version 2 of the License.
  140.11 + *
  140.12 + * This program is distributed in the hope that it will be useful,
  140.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  140.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  140.15 + * GNU General Public License for more details.
  140.16 + *
  140.17 + * You should have received a copy of the GNU General Public License
  140.18 + * along with this program. Look for COPYING file in the top folder.
  140.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
  140.20 + */
  140.21 +package org.apidesign.bck2brwsr.vmtest.impl;
  140.22 +
  140.23 +import java.io.IOException;
  140.24 +import java.io.InputStream;
  140.25 +import java.util.Objects;
  140.26 +import java.util.zip.ZipEntry;
  140.27 +import java.util.zip.ZipInputStream;
  140.28 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
  140.29 +import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
  140.30 +import org.apidesign.bck2brwsr.vmtest.Compare;
  140.31 +import org.apidesign.bck2brwsr.vmtest.HttpResource;
  140.32 +import org.apidesign.bck2brwsr.vmtest.VMTest;
  140.33 +import org.testng.annotations.Factory;
  140.34 +
  140.35 +/**
  140.36 + *
  140.37 + * @author Jaroslav Tulach <jtulach@netbeans.org>
  140.38 + */
  140.39 +@GenerateZip(name = "readAnEntry.zip", contents = { 
  140.40 +    "my/main/file.txt", "Hello World!"
  140.41 +})
  140.42 +public class ZipFileTest {
  140.43 +    
  140.44 +    @Compare public String readAnEntry() throws IOException {
  140.45 +        InputStream is = ZipFileTest.class.getResourceAsStream("readAnEntry.zip");
  140.46 +        ZipInputStream zip = new ZipInputStream(is);
  140.47 +        ZipEntry entry = zip.getNextEntry();
  140.48 +        assertEquals(entry.getName(), "my/main/file.txt", "Correct entry");
  140.49 +
  140.50 +        byte[] arr = new byte[4096];
  140.51 +        int len = zip.read(arr);
  140.52 +        
  140.53 +        assertEquals(zip.getNextEntry(), null, "No next entry");
  140.54 +        
  140.55 +        final String ret = new String(arr, 0, len, "UTF-8");
  140.56 +        return ret;
  140.57 +    }
  140.58 +    
  140.59 +    @JavaScriptBody(args = { "res", "path" }, body = 
  140.60 +          "var myvm = new bck2brwsr(path);\n"
  140.61 +        + "var cls = myvm.loadClass('java.lang.String');\n"
  140.62 +        + "return cls.getClass__Ljava_lang_Class_2().getResourceAsStream__Ljava_io_InputStream_2Ljava_lang_String_2(res);\n"
  140.63 +    )
  140.64 +    private static native Object loadVMResource(String res, String...path);
  140.65 +
  140.66 +    @HttpResource(path = "/readAnEntry.jar", mimeType = "x-application/zip", content = "", resource="readAnEntry.zip")
  140.67 +    @BrwsrTest  public void canVmLoadResourceFromZip() throws IOException {
  140.68 +        Object res = loadVMResource("/my/main/file.txt", "/readAnEntry.jar");
  140.69 +        assert res instanceof InputStream : "Got array of bytes: " + res;
  140.70 +        InputStream is = (InputStream)res;
  140.71 +        
  140.72 +        byte[] arr = new byte[4096];
  140.73 +        int len = is.read(arr);
  140.74 +        
  140.75 +        final String ret = new String(arr, 0, len, "UTF-8");
  140.76 +
  140.77 +        assertEquals(ret, "Hello World!", "Can read the bytes");
  140.78 +    }
  140.79 +    
  140.80 +    private static void assertEquals(Object real, Object exp, String msg) {
  140.81 +        assert Objects.equals(exp, real) : msg + " exp: " + exp + " real: " + real;
  140.82 +    }
  140.83 +    
  140.84 +    @Factory public static Object[] create() {
  140.85 +        return VMTest.create(ZipFileTest.class);
  140.86 +    }
  140.87 +}
   141.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   141.2 +++ b/vmtest/src/test/resources/org/apidesign/bck2brwsr/tck/0xfe	Tue Feb 05 17:04:22 2013 +0100
   141.3 @@ -0,0 +1,1 @@
   141.4 +
   141.5 \ No newline at end of file